summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibGL/Tex/Texture.h8
-rw-r--r--Userland/Libraries/LibGPU/Image.h35
-rw-r--r--Userland/Libraries/LibGPU/SamplerConfig.h4
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.cpp6
-rw-r--r--Userland/Libraries/LibSoftGPU/Device.h4
-rw-r--r--Userland/Libraries/LibSoftGPU/Image.cpp23
-rw-r--r--Userland/Libraries/LibSoftGPU/Image.h11
-rw-r--r--Userland/Libraries/LibSoftGPU/Sampler.cpp4
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 = {