mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-10 13:00:29 +03:00
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.
This commit is contained in:
parent
1f3642ed48
commit
4a99875582
Notes:
sideshowbarker
2024-07-17 14:22:48 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/4a99875582 Pull-request: https://github.com/SerenityOS/serenity/pull/13294 Reviewed-by: https://github.com/Quaker762 ✅ Reviewed-by: https://github.com/creator1creeper1 Reviewed-by: https://github.com/gmta
@ -8,7 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <LibSoftGPU/Image.h>
|
#include <LibGPU/Image.h>
|
||||||
|
|
||||||
namespace GL {
|
namespace GL {
|
||||||
|
|
||||||
@ -21,11 +21,11 @@ public:
|
|||||||
virtual bool is_texture_3d() const { return false; }
|
virtual bool is_texture_3d() const { return false; }
|
||||||
virtual bool is_cube_map() const { return false; }
|
virtual bool is_cube_map() const { return false; }
|
||||||
|
|
||||||
RefPtr<SoftGPU::Image> device_image() { return m_device_image; }
|
RefPtr<GPU::Image> device_image() { return m_device_image; }
|
||||||
void set_device_image(RefPtr<SoftGPU::Image> image) { m_device_image = image; }
|
void set_device_image(RefPtr<GPU::Image> image) { m_device_image = image; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<SoftGPU::Image> m_device_image;
|
RefPtr<GPU::Image> m_device_image;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
35
Userland/Libraries/LibGPU/Image.h
Normal file
35
Userland/Libraries/LibGPU/Image.h
Normal file
@ -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 };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibGPU/Image.h>
|
||||||
#include <LibGfx/Vector4.h>
|
#include <LibGfx/Vector4.h>
|
||||||
#include <LibSoftGPU/Image.h>
|
|
||||||
|
|
||||||
namespace GPU {
|
namespace GPU {
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ enum class TextureEnvMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SamplerConfig final {
|
struct SamplerConfig final {
|
||||||
RefPtr<SoftGPU::Image> bound_image;
|
RefPtr<Image> bound_image;
|
||||||
MipMapFilter mipmap_filter { MipMapFilter::Nearest };
|
MipMapFilter mipmap_filter { MipMapFilter::Nearest };
|
||||||
TextureFilter texture_mag_filter { TextureFilter::Linear };
|
TextureFilter texture_mag_filter { TextureFilter::Linear };
|
||||||
TextureFilter texture_min_filter { TextureFilter::Linear };
|
TextureFilter texture_min_filter { TextureFilter::Linear };
|
||||||
|
@ -1219,7 +1219,7 @@ GPU::DepthType Device::get_depthbuffer_value(int x, int y)
|
|||||||
return m_frame_buffer->depth_buffer()->scanline(y)[x];
|
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(format == GPU::ImageFormat::BGRA8888);
|
||||||
VERIFY(width > 0);
|
VERIFY(width > 0);
|
||||||
@ -1228,11 +1228,13 @@ NonnullRefPtr<Image> Device::create_image(GPU::ImageFormat format, unsigned widt
|
|||||||
VERIFY(levels > 0);
|
VERIFY(levels > 0);
|
||||||
VERIFY(layers > 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)
|
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);
|
m_samplers[sampler].set_config(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibGPU/DeviceInfo.h>
|
#include <LibGPU/DeviceInfo.h>
|
||||||
#include <LibGPU/Enums.h>
|
#include <LibGPU/Enums.h>
|
||||||
|
#include <LibGPU/Image.h>
|
||||||
#include <LibGPU/ImageFormat.h>
|
#include <LibGPU/ImageFormat.h>
|
||||||
#include <LibGPU/Light.h>
|
#include <LibGPU/Light.h>
|
||||||
#include <LibGPU/LightModelParameters.h>
|
#include <LibGPU/LightModelParameters.h>
|
||||||
@ -33,7 +34,6 @@
|
|||||||
#include <LibSoftGPU/Buffer/Typed2DBuffer.h>
|
#include <LibSoftGPU/Buffer/Typed2DBuffer.h>
|
||||||
#include <LibSoftGPU/Clipper.h>
|
#include <LibSoftGPU/Clipper.h>
|
||||||
#include <LibSoftGPU/Config.h>
|
#include <LibSoftGPU/Config.h>
|
||||||
#include <LibSoftGPU/Image.h>
|
|
||||||
#include <LibSoftGPU/Sampler.h>
|
#include <LibSoftGPU/Sampler.h>
|
||||||
#include <LibSoftGPU/Triangle.h>
|
#include <LibSoftGPU/Triangle.h>
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public:
|
|||||||
GPU::ColorType get_color_buffer_pixel(int x, int y);
|
GPU::ColorType get_color_buffer_pixel(int x, int y);
|
||||||
GPU::DepthType get_depthbuffer_value(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_sampler_config(unsigned, GPU::SamplerConfig const&);
|
||||||
void set_light_state(unsigned, GPU::Light const&);
|
void set_light_state(unsigned, GPU::Light const&);
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
namespace SoftGPU {
|
namespace SoftGPU {
|
||||||
|
|
||||||
Image::Image(unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers)
|
Image::Image(void* const ownership_token, unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers)
|
||||||
: m_num_layers(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))
|
, m_mipmap_buffers(FixedArray<RefPtr<Typed3DBuffer<GPU::ColorType>>>::must_create_but_fixme_should_propagate_errors(layers * max_levels))
|
||||||
{
|
{
|
||||||
VERIFY(width > 0);
|
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.has_same_ownership_token(*this));
|
||||||
VERIFY(source_level < source.num_levels());
|
|
||||||
VERIFY(source_offset.x() + size.x() <= source.level_width(source_level));
|
auto const& src_image = static_cast<Image const&>(source);
|
||||||
VERIFY(source_offset.y() + size.y() <= source.level_height(source_level));
|
|
||||||
VERIFY(source_offset.z() + size.z() <= source.level_depth(source_level));
|
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_layer < num_layers());
|
||||||
VERIFY(destination_level < num_levels());
|
VERIFY(destination_level < num_levels());
|
||||||
VERIFY(destination_offset.x() + size.x() <= level_width(destination_level));
|
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 z = 0; z < size.z(); ++z) {
|
||||||
for (unsigned y = 0; y < size.y(); ++y) {
|
for (unsigned y = 0; y < size.y(); ++y) {
|
||||||
for (unsigned x = 0; x < size.x(); ++x) {
|
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);
|
set_texel(destination_layer, destination_level, destination_offset.x() + x, destination_offset.y() + y, destination_offset.z() + z, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
#include <AK/RefPtr.h>
|
#include <AK/RefPtr.h>
|
||||||
#include <LibGPU/Enums.h>
|
#include <LibGPU/Enums.h>
|
||||||
|
#include <LibGPU/Image.h>
|
||||||
#include <LibGPU/ImageDataLayout.h>
|
#include <LibGPU/ImageDataLayout.h>
|
||||||
#include <LibGPU/ImageFormat.h>
|
#include <LibGPU/ImageFormat.h>
|
||||||
#include <LibGfx/Vector3.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:
|
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_width(unsigned level) const { return m_mipmap_buffers[level]->width(); }
|
||||||
unsigned level_height(unsigned level) const { return m_mipmap_buffers[level]->height(); }
|
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);
|
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);
|
virtual void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, GPU::ImageDataLayout const& layout) override;
|
||||||
void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, GPU::ImageDataLayout const& layout) const;
|
virtual void read_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void* data, GPU::ImageDataLayout const& layout) const override;
|
||||||
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 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:
|
private:
|
||||||
void const* texel_pointer(unsigned layer, unsigned level, int x, int y, int z) const
|
void const* texel_pointer(unsigned layer, unsigned level, int x, int y, int z) const
|
||||||
|
@ -109,7 +109,7 @@ Vector4<AK::SIMD::f32x4> Sampler::sample_2d(Vector2<AK::SIMD::f32x4> const& uv)
|
|||||||
if (m_config.bound_image.is_null())
|
if (m_config.bound_image.is_null())
|
||||||
return expand4(FloatVector4 { 1, 0, 0, 1 });
|
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)
|
// FIXME: Make base level configurable with glTexParameteri(GL_TEXTURE_BASE_LEVEL, base_level)
|
||||||
constexpr unsigned base_level = 0;
|
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
|
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 layer = expand4(0u);
|
||||||
|
|
||||||
u32x4 const width = {
|
u32x4 const width = {
|
||||||
|
Loading…
Reference in New Issue
Block a user