diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2022-03-27 16:26:50 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-06 11:32:24 +0200 |
commit | 4a9987558281c4ac4b235f7965ff323e5dba5673 (patch) | |
tree | 4204c0964347e1340234ca0906a7b9e36b3c3df3 | |
parent | 1f3642ed48b6be1e1e913e5a550f2e38f299f07f (diff) | |
download | serenity-4a9987558281c4ac4b235f7965ff323e5dba5673.zip |
LibGL+LibGPU+LibSoftGPU: Add virtual base class for Images
This introduces a new device independent base class for Images in LibGPU
that also keeps track of the device from which it was created in order
to prevent assigning images across devices.
-rw-r--r-- | Userland/Libraries/LibGL/Tex/Texture.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/Image.h | 35 | ||||
-rw-r--r-- | Userland/Libraries/LibGPU/SamplerConfig.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Device.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Device.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Image.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Image.h | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibSoftGPU/Sampler.cpp | 4 |
8 files changed, 69 insertions, 26 deletions
diff --git a/Userland/Libraries/LibGL/Tex/Texture.h b/Userland/Libraries/LibGL/Tex/Texture.h index 1009d15028..452201f7d9 100644 --- a/Userland/Libraries/LibGL/Tex/Texture.h +++ b/Userland/Libraries/LibGL/Tex/Texture.h @@ -8,7 +8,7 @@ #pragma once #include <AK/RefCounted.h> -#include <LibSoftGPU/Image.h> +#include <LibGPU/Image.h> namespace GL { @@ -21,11 +21,11 @@ public: virtual bool is_texture_3d() const { return false; } virtual bool is_cube_map() const { return false; } - RefPtr<SoftGPU::Image> device_image() { return m_device_image; } - void set_device_image(RefPtr<SoftGPU::Image> image) { m_device_image = image; } + RefPtr<GPU::Image> device_image() { return m_device_image; } + void set_device_image(RefPtr<GPU::Image> image) { m_device_image = image; } private: - RefPtr<SoftGPU::Image> m_device_image; + RefPtr<GPU::Image> m_device_image; }; } diff --git a/Userland/Libraries/LibGPU/Image.h b/Userland/Libraries/LibGPU/Image.h new file mode 100644 index 0000000000..4803d4ec17 --- /dev/null +++ b/Userland/Libraries/LibGPU/Image.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022, Stephan Unverwerth <s.unverwerth@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/RefCounted.h> +#include <LibGPU/ImageDataLayout.h> +#include <LibGfx/Vector3.h> + +namespace GPU { + +class Image : public RefCounted<Image> { +public: + Image(void const* ownership_token) + : m_ownership_token { ownership_token } + { + } + + virtual ~Image() { } + + virtual void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, ImageDataLayout const& layout) = 0; + virtual void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, ImageDataLayout const& layout) const = 0; + virtual void copy_texels(Image const& source, unsigned source_layer, unsigned source_level, Vector3<unsigned> const& source_offset, Vector3<unsigned> const& size, unsigned destination_layer, unsigned destination_level, Vector3<unsigned> const& destination_offset) = 0; + + void const* ownership_token() const { return m_ownership_token; } + bool has_same_ownership_token(Image const& other) const { return other.ownership_token() == ownership_token(); } + +private: + void const* const m_ownership_token { nullptr }; +}; + +} diff --git a/Userland/Libraries/LibGPU/SamplerConfig.h b/Userland/Libraries/LibGPU/SamplerConfig.h index fe121913ab..42ccdd2c76 100644 --- a/Userland/Libraries/LibGPU/SamplerConfig.h +++ b/Userland/Libraries/LibGPU/SamplerConfig.h @@ -6,8 +6,8 @@ #pragma once +#include <LibGPU/Image.h> #include <LibGfx/Vector4.h> -#include <LibSoftGPU/Image.h> namespace GPU { @@ -37,7 +37,7 @@ enum class TextureEnvMode { }; struct SamplerConfig final { - RefPtr<SoftGPU::Image> bound_image; + RefPtr<Image> bound_image; MipMapFilter mipmap_filter { MipMapFilter::Nearest }; TextureFilter texture_mag_filter { TextureFilter::Linear }; TextureFilter texture_min_filter { TextureFilter::Linear }; diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index 62f615206d..ad721f2ee4 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -1219,7 +1219,7 @@ GPU::DepthType Device::get_depthbuffer_value(int x, int y) return m_frame_buffer->depth_buffer()->scanline(y)[x]; } -NonnullRefPtr<Image> Device::create_image(GPU::ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers) +NonnullRefPtr<GPU::Image> Device::create_image(GPU::ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers) { VERIFY(format == GPU::ImageFormat::BGRA8888); VERIFY(width > 0); @@ -1228,11 +1228,13 @@ NonnullRefPtr<Image> Device::create_image(GPU::ImageFormat format, unsigned widt VERIFY(levels > 0); VERIFY(layers > 0); - return adopt_ref(*new Image(width, height, depth, levels, layers)); + return adopt_ref(*new Image(this, width, height, depth, levels, layers)); } void Device::set_sampler_config(unsigned sampler, GPU::SamplerConfig const& config) { + VERIFY(config.bound_image.is_null() || config.bound_image->ownership_token() == this); + m_samplers[sampler].set_config(config); } diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index 14955542d7..2816e947da 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -13,6 +13,7 @@ #include <AK/Vector.h> #include <LibGPU/DeviceInfo.h> #include <LibGPU/Enums.h> +#include <LibGPU/Image.h> #include <LibGPU/ImageFormat.h> #include <LibGPU/Light.h> #include <LibGPU/LightModelParameters.h> @@ -33,7 +34,6 @@ #include <LibSoftGPU/Buffer/Typed2DBuffer.h> #include <LibSoftGPU/Clipper.h> #include <LibSoftGPU/Config.h> -#include <LibSoftGPU/Image.h> #include <LibSoftGPU/Sampler.h> #include <LibSoftGPU/Triangle.h> @@ -62,7 +62,7 @@ public: GPU::ColorType get_color_buffer_pixel(int x, int y); GPU::DepthType get_depthbuffer_value(int x, int y); - NonnullRefPtr<Image> create_image(GPU::ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers); + NonnullRefPtr<GPU::Image> create_image(GPU::ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers); void set_sampler_config(unsigned, GPU::SamplerConfig const&); void set_light_state(unsigned, GPU::Light const&); diff --git a/Userland/Libraries/LibSoftGPU/Image.cpp b/Userland/Libraries/LibSoftGPU/Image.cpp index bd7f6217e5..ee986c4cfd 100644 --- a/Userland/Libraries/LibSoftGPU/Image.cpp +++ b/Userland/Libraries/LibSoftGPU/Image.cpp @@ -9,8 +9,9 @@ namespace SoftGPU { -Image::Image(unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers) - : m_num_layers(layers) +Image::Image(void* const ownership_token, unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers) + : GPU::Image(ownership_token) + , m_num_layers(layers) , m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<GPU::ColorType>>>::must_create_but_fixme_should_propagate_errors(layers * max_levels)) { VERIFY(width > 0); @@ -77,13 +78,17 @@ void Image::read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& } } -void Image::copy_texels(Image const& source, unsigned source_layer, unsigned source_level, Vector3<unsigned> const& source_offset, Vector3<unsigned> const& size, unsigned destination_layer, unsigned destination_level, Vector3<unsigned> const& destination_offset) +void Image::copy_texels(GPU::Image const& source, unsigned source_layer, unsigned source_level, Vector3<unsigned> const& source_offset, Vector3<unsigned> const& size, unsigned destination_layer, unsigned destination_level, Vector3<unsigned> const& destination_offset) { - VERIFY(source_layer < source.num_layers()); - VERIFY(source_level < source.num_levels()); - VERIFY(source_offset.x() + size.x() <= source.level_width(source_level)); - VERIFY(source_offset.y() + size.y() <= source.level_height(source_level)); - VERIFY(source_offset.z() + size.z() <= source.level_depth(source_level)); + VERIFY(source.has_same_ownership_token(*this)); + + auto const& src_image = static_cast<Image const&>(source); + + VERIFY(source_layer < src_image.num_layers()); + VERIFY(source_level < src_image.num_levels()); + VERIFY(source_offset.x() + size.x() <= src_image.level_width(source_level)); + VERIFY(source_offset.y() + size.y() <= src_image.level_height(source_level)); + VERIFY(source_offset.z() + size.z() <= src_image.level_depth(source_level)); VERIFY(destination_layer < num_layers()); VERIFY(destination_level < num_levels()); VERIFY(destination_offset.x() + size.x() <= level_width(destination_level)); @@ -93,7 +98,7 @@ void Image::copy_texels(Image const& source, unsigned source_layer, unsigned sou for (unsigned z = 0; z < size.z(); ++z) { for (unsigned y = 0; y < size.y(); ++y) { for (unsigned x = 0; x < size.x(); ++x) { - auto color = source.texel(source_layer, source_level, source_offset.x() + x, source_offset.y() + y, source_offset.z() + z); + auto color = src_image.texel(source_layer, source_level, source_offset.x() + x, source_offset.y() + y, source_offset.z() + z); set_texel(destination_layer, destination_level, destination_offset.x() + x, destination_offset.y() + y, destination_offset.z() + z, color); } } diff --git a/Userland/Libraries/LibSoftGPU/Image.h b/Userland/Libraries/LibSoftGPU/Image.h index bbfe154138..99c2348bfc 100644 --- a/Userland/Libraries/LibSoftGPU/Image.h +++ b/Userland/Libraries/LibSoftGPU/Image.h @@ -11,6 +11,7 @@ #include <AK/RefCounted.h> #include <AK/RefPtr.h> #include <LibGPU/Enums.h> +#include <LibGPU/Image.h> #include <LibGPU/ImageDataLayout.h> #include <LibGPU/ImageFormat.h> #include <LibGfx/Vector3.h> @@ -133,9 +134,9 @@ inline static void pack_color(FloatVector4 const& color, void* ptr, GPU::ImageFo } } -class Image final : public RefCounted<Image> { +class Image final : public GPU::Image { public: - Image(unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers); + Image(void* const ownership_token, unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers); unsigned level_width(unsigned level) const { return m_mipmap_buffers[level]->width(); } unsigned level_height(unsigned level) const { return m_mipmap_buffers[level]->height(); } @@ -156,9 +157,9 @@ public: pack_color(color, texel_pointer(layer, level, x, y, z), GPU::ImageFormat::BGRA8888); } - void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, GPU::ImageDataLayout const& layout); - void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, GPU::ImageDataLayout const& layout) const; - void copy_texels(Image const& source, unsigned source_layer, unsigned source_level, Vector3<unsigned> const& source_offset, Vector3<unsigned> const& size, unsigned destination_layer, unsigned destination_level, Vector3<unsigned> const& destination_offset); + virtual void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, GPU::ImageDataLayout const& layout) override; + virtual void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, GPU::ImageDataLayout const& layout) const override; + virtual void copy_texels(GPU::Image const& source, unsigned source_layer, unsigned source_level, Vector3<unsigned> const& source_offset, Vector3<unsigned> const& size, unsigned destination_layer, unsigned destination_level, Vector3<unsigned> const& destination_offset) override; private: void const* texel_pointer(unsigned layer, unsigned level, int x, int y, int z) const diff --git a/Userland/Libraries/LibSoftGPU/Sampler.cpp b/Userland/Libraries/LibSoftGPU/Sampler.cpp index fa37aa6836..082760a4b9 100644 --- a/Userland/Libraries/LibSoftGPU/Sampler.cpp +++ b/Userland/Libraries/LibSoftGPU/Sampler.cpp @@ -109,7 +109,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv) if (m_config.bound_image.is_null()) return expand4(FloatVector4 { 1, 0, 0, 1 }); - auto const& image = *m_config.bound_image; + auto const& image = *static_ptr_cast<Image>(m_config.bound_image); // FIXME: Make base level configurable with glTexParameteri(GL_TEXTURE_BASE_LEVEL, base_level) constexpr unsigned base_level = 0; @@ -152,7 +152,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv) Vector4<AK::SIMD::f32x4> Sampler::sample_2d_lod(Vector2<AK::SIMD::f32x4> const& uv, AK::SIMD::u32x4 level, GPU::TextureFilter filter) const { - auto const& image = *m_config.bound_image; + auto const& image = *static_ptr_cast<Image>(m_config.bound_image); u32x4 const layer = expand4(0u); u32x4 const width = { |