mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 21:17:44 +00:00
LibSoftGPU: Generalize pixel buffers and standardize on BGRA8888
Between the OpenGL client and server, a lot of data type and color conversion needs to happen. We are performing these conversions both in `LibSoftGPU` and `LibGL`, which is not ideal. Additionally, some concepts like the color, depth and stencil buffers should share their logic but have separate implementations. This is the first step towards generalizing our `LibSoftGPU` frame buffer: a generalized `Typed3DBuffer` is introduced for arbitrary 3D value storage and retrieval, and `Typed2DBuffer` wraps around it to provide in an easy-to-use 2D pixel buffer. The color, depth and stencil buffers are replaced by `Typed2DBuffer` and are now managed by the new `FrameBuffer` class. The `Image` class now uses multiple `Typed3DBuffer`s for layers and mipmap levels. Additionally, the textures are now always stored as BGRA8888, only converting between formats when reading or writing pixels. Ideally this refactor should have no functional changes, but some graphical glitches in Grim Fandango seem to be fixed and most OpenGL ports get an FPS boost on my machine. :^)
This commit is contained in:
parent
72ec2c21f4
commit
db0616c67a
14 changed files with 339 additions and 316 deletions
|
@ -1,15 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Stephan Unverwerth <s.unverwerth@serenityos.org>
|
||||
* Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FixedArray.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <LibGfx/Vector3.h>
|
||||
#include <LibGfx/Vector4.h>
|
||||
#include <LibSoftGPU/Buffer/Typed3DBuffer.h>
|
||||
#include <LibSoftGPU/Enums.h>
|
||||
#include <LibSoftGPU/ImageDataLayout.h>
|
||||
#include <LibSoftGPU/ImageFormat.h>
|
||||
|
||||
|
@ -17,29 +21,25 @@ namespace SoftGPU {
|
|||
|
||||
class Image final : public RefCounted<Image> {
|
||||
public:
|
||||
Image(ImageFormat format, unsigned width, unsigned height, unsigned depth, unsigned levels, unsigned layers);
|
||||
Image(unsigned width, unsigned height, unsigned depth, unsigned max_levels, unsigned layers);
|
||||
|
||||
ImageFormat format() const { return m_format; }
|
||||
unsigned width() const { return m_width; }
|
||||
unsigned height() const { return m_height; }
|
||||
unsigned depth() const { return m_depth; }
|
||||
unsigned level_width(unsigned level) const { return m_mipmap_sizes[level].x(); }
|
||||
unsigned level_height(unsigned level) const { return m_mipmap_sizes[level].y(); }
|
||||
unsigned level_depth(unsigned level) const { return m_mipmap_sizes[level].z(); }
|
||||
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_depth(unsigned level) const { return m_mipmap_buffers[level]->depth(); }
|
||||
unsigned num_levels() const { return m_num_levels; }
|
||||
unsigned num_layers() const { return m_num_layers; }
|
||||
bool width_is_power_of_two() const { return m_width_is_power_of_two; }
|
||||
bool height_is_power_of_two() const { return m_height_is_power_of_two; }
|
||||
bool depth_is_power_of_two() const { return m_depth_is_power_of_two; }
|
||||
|
||||
FloatVector4 texel(unsigned layer, unsigned level, unsigned x, unsigned y, unsigned z) const
|
||||
FloatVector4 texel(unsigned layer, unsigned level, int x, int y, int z) const
|
||||
{
|
||||
return unpack_color(texel_pointer(layer, level, x, y, z), m_format);
|
||||
return unpack_color(texel_pointer(layer, level, x, y, z), ImageFormat::BGRA8888);
|
||||
}
|
||||
|
||||
void set_texel(unsigned layer, unsigned level, unsigned x, unsigned y, unsigned z, FloatVector4 const& color)
|
||||
void set_texel(unsigned layer, unsigned level, int x, int y, int z, FloatVector4 const& color)
|
||||
{
|
||||
pack_color(color, texel_pointer(layer, level, x, y, z), m_format);
|
||||
pack_color(color, texel_pointer(layer, level, x, y, z), ImageFormat::BGRA8888);
|
||||
}
|
||||
|
||||
void write_texels(unsigned layer, unsigned level, Vector3<unsigned> const& offset, Vector3<unsigned> const& size, void const* data, ImageDataLayout const& layout);
|
||||
|
@ -47,30 +47,22 @@ public:
|
|||
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);
|
||||
|
||||
private:
|
||||
void const* texel_pointer(unsigned layer, unsigned level, unsigned x, unsigned y, unsigned z) const
|
||||
void const* texel_pointer(unsigned layer, unsigned level, int x, int y, int z) const
|
||||
{
|
||||
auto size = m_mipmap_sizes[level];
|
||||
return &m_data[m_mipchain_size * layer + m_mipmap_offsets[level] + (z * size.x() * size.y() + y * size.x() + x) * element_size(m_format)];
|
||||
return m_mipmap_buffers[layer * m_num_layers + level]->buffer_pointer(x, y, z);
|
||||
}
|
||||
|
||||
void* texel_pointer(unsigned layer, unsigned level, unsigned x, unsigned y, unsigned z)
|
||||
void* texel_pointer(unsigned layer, unsigned level, int x, int y, int z)
|
||||
{
|
||||
auto size = m_mipmap_sizes[level];
|
||||
return &m_data[m_mipchain_size * layer + m_mipmap_offsets[level] + (z * size.x() * size.y() + y * size.x() + x) * element_size(m_format)];
|
||||
return m_mipmap_buffers[layer * m_num_layers + level]->buffer_pointer(x, y, z);
|
||||
}
|
||||
|
||||
private:
|
||||
ImageFormat m_format { ImageFormat::RGBA8888 };
|
||||
unsigned m_width { 0 };
|
||||
unsigned m_height { 0 };
|
||||
unsigned m_depth { 0 };
|
||||
unsigned m_num_levels { 0 };
|
||||
unsigned m_num_layers { 0 };
|
||||
|
||||
size_t m_mipchain_size { 0 };
|
||||
Vector<size_t, 16> m_mipmap_offsets;
|
||||
Vector<Vector3<unsigned>, 16> m_mipmap_sizes;
|
||||
Vector<u8> m_data;
|
||||
FixedArray<RefPtr<Typed3DBuffer<ColorType>>> m_mipmap_buffers;
|
||||
|
||||
bool m_width_is_power_of_two { false };
|
||||
bool m_height_is_power_of_two { false };
|
||||
bool m_depth_is_power_of_two { false };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue