diff options
author | Stephan Unverwerth <s.unverwerth@serenityos.org> | 2021-12-23 13:52:19 +0100 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2021-12-24 05:10:28 -0800 |
commit | 5e9d99474dc4e8cfa9a18755ff0b580d3bbbb279 (patch) | |
tree | 583fe031e57852bf65fb6ae214111f1074539a64 | |
parent | 4c944eaa41c1ad3f0d85af1cbe05ba87b4fe8554 (diff) | |
download | serenity-5e9d99474dc4e8cfa9a18755ff0b580d3bbbb279.zip |
LibGL: Remove image storage from MipMap
Images are stored on the device side. Texture2D and MipMap are now only
used to store imformation about the texture and reference to the device
image.
-rw-r--r-- | Userland/Libraries/LibGL/Tex/MipMap.h | 24 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/Texture2D.cpp | 118 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/Texture2D.h | 12 |
3 files changed, 37 insertions, 117 deletions
diff --git a/Userland/Libraries/LibGL/Tex/MipMap.h b/Userland/Libraries/LibGL/Tex/MipMap.h index 01bfd02397..fc2d697d75 100644 --- a/Userland/Libraries/LibGL/Tex/MipMap.h +++ b/Userland/Libraries/LibGL/Tex/MipMap.h @@ -7,43 +7,19 @@ #pragma once -#include <AK/Vector.h> #include <LibGL/GL/gl.h> -#include <LibGfx/Vector4.h> namespace GL { class MipMap { public: - MipMap() = default; - ~MipMap() = default; - void set_width(GLsizei width) { m_width = width; } void set_height(GLsizei height) { m_height = height; } GLsizei width() const { return m_width; } GLsizei height() const { return m_height; } - Vector<u32>& pixel_data() { return m_pixel_data; } - const Vector<u32>& pixel_data() const { return m_pixel_data; } - - FloatVector4 texel(unsigned x, unsigned y) const - { - if (x >= (unsigned)m_width || y >= (unsigned)m_height) - return { 0, 0, 0, 0 }; - - u32 texel = m_pixel_data.at(y * m_width + x); - - return { - ((texel >> 16) & 0xff) / 255.f, - ((texel >> 8) & 0xff) / 255.f, - (texel & 0xff) / 255.f, - ((texel >> 24) & 0xff) / 255.f - }; - } - private: GLsizei m_width { 0 }; GLsizei m_height { 0 }; - Vector<u32> m_pixel_data; }; } diff --git a/Userland/Libraries/LibGL/Tex/Texture2D.cpp b/Userland/Libraries/LibGL/Tex/Texture2D.cpp index d6a04f4d42..19162eb2b9 100644 --- a/Userland/Libraries/LibGL/Tex/Texture2D.cpp +++ b/Userland/Libraries/LibGL/Tex/Texture2D.cpp @@ -19,7 +19,6 @@ void Texture2D::upload_texture_data(GLuint lod, GLint internal_format, GLsizei w auto& mip = m_mipmaps[lod]; mip.set_width(width); mip.set_height(height); - mip.pixel_data().resize(width * height); // No pixel data was supplied leave the texture memory uninitialized. if (pixels == nullptr) @@ -39,6 +38,12 @@ void Texture2D::replace_sub_texture_data(GLuint lod, GLint xoffset, GLint yoffse VERIFY(xoffset >= 0 && yoffset >= 0 && xoffset + width <= mip.width() && yoffset + height <= mip.height()); VERIFY(pixels_per_row == 0 || pixels_per_row >= xoffset + width); + // FIXME: We currently depend on the first glTexImage2D call to attach an image to mipmap level 0, which initializes the GPU image + // Ideally we would create separate GPU images for each level and merge them into a final image + // once used for rendering for the first time. + if (device_image().is_null()) + return; + u8 pixel_size_bytes; switch (type) { case GL_UNSIGNED_BYTE: @@ -54,91 +59,38 @@ void Texture2D::replace_sub_texture_data(GLuint lod, GLint xoffset, GLint yoffse // Calculate row offset at end to fit alignment int const physical_width = pixels_per_row > 0 ? pixels_per_row : width; size_t const physical_width_bytes = physical_width * pixel_size_bytes; - size_t const row_remainder_bytes = (physical_width - width) * pixel_size_bytes - + (byte_alignment - physical_width_bytes % byte_alignment) % byte_alignment; - - u8 const* pixel_byte_array = reinterpret_cast<u8 const*>(pixels); - - auto get_next_pixel = [type, format](u8 const** pixels) -> u32 { - // Split bytes up into RGBA components - u8 c1, c2, c3, c4; - switch (type) { - case GL_UNSIGNED_BYTE: - c1 = *((*pixels)++); - c2 = *((*pixels)++); - c3 = *((*pixels)++); - if (format == GL_RGBA || format == GL_BGRA) { - c4 = *((*pixels)++); - } else { - c4 = 255; - } - break; - case GL_UNSIGNED_SHORT_5_6_5: { - u16 const s = *reinterpret_cast<u16 const*>((*pixels) += 2); - c1 = (s & 0xf800) >> 8; - c2 = (s & 0x7e0) >> 3; - c3 = (s & 0x1f) << 3; - c4 = 255; - break; - } - default: - VERIFY_NOT_REACHED(); - } - - // Reorder components into BGRA pixel - switch (format) { - case GL_BGR: - case GL_BGRA: - return ((c4 << 24) | (c3 << 16) | (c2 << 8) | c1); - case GL_RGB: - case GL_RGBA: - return ((c4 << 24) | (c1 << 16) | (c2 << 8) | c3); - default: - VERIFY_NOT_REACHED(); - } - }; - for (auto y = yoffset; y < yoffset + height; y++) { - for (auto x = xoffset; x < xoffset + width; x++) { - u32 pixel = get_next_pixel(&pixel_byte_array); - mip.pixel_data()[y * mip.width() + x] = pixel; - } - - pixel_byte_array += row_remainder_bytes; + SoftGPU::ImageDataLayout layout; + layout.column_stride = pixel_size_bytes; + layout.row_stride = physical_width_bytes + (byte_alignment - physical_width_bytes % byte_alignment) % byte_alignment; + layout.depth_stride = 0; + + if (type == GL_UNSIGNED_SHORT_5_6_5) { + layout.format = SoftGPU::ImageFormat::RGB565; + } else if (type == GL_UNSIGNED_BYTE) { + if (format == GL_RGB) + layout.format = SoftGPU::ImageFormat::RGB888; + else if (format == GL_BGR) + layout.format = SoftGPU::ImageFormat::BGR888; + else if (format == GL_RGBA) + layout.format = SoftGPU::ImageFormat::RGBA8888; + else if (format == GL_BGRA) + layout.format = SoftGPU::ImageFormat::BGRA8888; } - if (!device_image().is_null()) { - SoftGPU::ImageDataLayout layout; - layout.column_stride = pixel_size_bytes; - layout.row_stride = physical_width_bytes + (byte_alignment - physical_width_bytes % byte_alignment) % byte_alignment; - layout.depth_stride = 0; - if (type == GL_UNSIGNED_SHORT_5_6_5) { - layout.format = SoftGPU::ImageFormat::RGB565; - } else if (type == GL_UNSIGNED_BYTE) { - if (format == GL_RGB) - layout.format = SoftGPU::ImageFormat::RGB888; - else if (format == GL_BGR) - layout.format = SoftGPU::ImageFormat::BGR888; - else if (format == GL_RGBA) - layout.format = SoftGPU::ImageFormat::RGBA8888; - else if (format == GL_BGRA) - layout.format = SoftGPU::ImageFormat::BGRA8888; - } - - Vector3<unsigned> offset { - static_cast<unsigned>(xoffset), - static_cast<unsigned>(yoffset), - 0 - }; - - Vector3<unsigned> size { - static_cast<unsigned>(width), - static_cast<unsigned>(height), - 1 - }; - - device_image()->write_texels(0, lod, offset, size, pixels, layout); - } + Vector3<unsigned> offset { + static_cast<unsigned>(xoffset), + static_cast<unsigned>(yoffset), + 0 + }; + + Vector3<unsigned> size { + static_cast<unsigned>(width), + static_cast<unsigned>(height), + 1 + }; + + device_image()->write_texels(0, lod, offset, size, pixels, layout); } } diff --git a/Userland/Libraries/LibGL/Tex/Texture2D.h b/Userland/Libraries/LibGL/Tex/Texture2D.h index e071a182a4..626c8d124f 100644 --- a/Userland/Libraries/LibGL/Tex/Texture2D.h +++ b/Userland/Libraries/LibGL/Tex/Texture2D.h @@ -44,16 +44,8 @@ public: Sampler2D const& sampler() const { return m_sampler; } Sampler2D& sampler() { return m_sampler; } - int width_at_lod(unsigned level) const { return (level >= m_mipmaps.size()) ? 0 : max(1, m_mipmaps.at(level).width() >> level); } - int height_at_lod(unsigned level) const { return (level >= m_mipmaps.size()) ? 0 : max(1, m_mipmaps.at(level).height() >> level); } - -private: - template<typename TCallback> - void swizzle(Vector<u32>& pixels, TCallback&& callback) - { - for (auto& pixel : pixels) - pixel = callback(pixel); - } + int width_at_lod(unsigned level) const { return (level >= m_mipmaps.size()) ? 0 : m_mipmaps.at(level).width(); } + int height_at_lod(unsigned level) const { return (level >= m_mipmaps.size()) ? 0 : m_mipmaps.at(level).height(); } private: // FIXME: Mipmaps are currently unused, but we have the plumbing for it at least |