diff options
author | Jelle Raaijmakers <jelle@gmta.nl> | 2021-12-12 21:43:21 +0100 |
---|---|---|
committer | Brian Gianforcaro <b.gianfo@gmail.com> | 2021-12-20 10:36:53 -0800 |
commit | 4e3ed165279ee103c87093e85cef7930c6174cdd (patch) | |
tree | 408571c23c59caf1f0b59dcebf8f191f2df249bf /Userland | |
parent | f201567153bb143c972545e611bdb6c0ef80d3d2 (diff) | |
download | serenity-4e3ed165279ee103c87093e85cef7930c6174cdd.zip |
LibGL: Only pass bound texture units to rasterizer
Before, `SoftwareRasterizer` was iterating over all 32 possible texture
units for each fragment and checking each if they're bound to a texture.
After this change, an intrusive list containing only texture units with
bound textures is passed to the rasterizer. In GLQuake, this results in
a performance improvement of ~30% (from 12 to 16 FPS in the first demo)
on my machine.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareGLContext.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareRasterizer.cpp | 11 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/SoftwareRasterizer.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGL/Tex/TextureUnit.h | 4 |
5 files changed, 16 insertions, 10 deletions
diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index b452319d34..82d5259a7a 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -328,6 +328,12 @@ void SoftwareGLContext::gl_end() } } + m_bound_texture_units.clear(); + for (auto& texture_unit : m_texture_units) { + if (texture_unit.is_bound()) + m_bound_texture_units.append(texture_unit); + } + for (size_t i = 0; i < processed_triangles.size(); i++) { GLTriangle& triangle = processed_triangles.at(i); @@ -356,7 +362,7 @@ void SoftwareGLContext::gl_end() swap(triangle.vertices[0], triangle.vertices[1]); } - m_rasterizer.submit_triangle(triangle, m_texture_units); + m_rasterizer.submit_triangle(triangle, m_bound_texture_units); } } diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.h b/Userland/Libraries/LibGL/SoftwareGLContext.h index 64a4b995ab..d6b744cefc 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.h +++ b/Userland/Libraries/LibGL/SoftwareGLContext.h @@ -234,6 +234,7 @@ private: HashMap<GLuint, RefPtr<Texture>> m_allocated_textures; Array<TextureUnit, 32> m_texture_units; TextureUnit* m_active_texture_unit { &m_texture_units[0] }; + TextureUnit::BoundList m_bound_texture_units; SoftwareRasterizer m_rasterizer; diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp index f59b8a4318..5e82478ad9 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.cpp +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.cpp @@ -494,17 +494,12 @@ SoftwareRasterizer::SoftwareRasterizer(const Gfx::IntSize& min_size) m_options.scissor_box = m_render_target->rect(); } -void SoftwareRasterizer::submit_triangle(const GLTriangle& triangle, const Array<TextureUnit, 32>& texture_units) +void SoftwareRasterizer::submit_triangle(GLTriangle const& triangle, TextureUnit::BoundList const& bound_texture_units) { - rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [this, &texture_units](const FloatVector2& uv, const FloatVector4& color, float z) -> FloatVector4 { + rasterize_triangle(m_options, *m_render_target, *m_depth_buffer, triangle, [this, &bound_texture_units](const FloatVector2& uv, const FloatVector4& color, float z) -> FloatVector4 { FloatVector4 fragment = color; - for (const auto& texture_unit : texture_units) { - - // No texture is bound to this texture unit - if (!texture_unit.is_bound()) - continue; - + for (auto const& texture_unit : bound_texture_units) { // FIXME: implement GL_TEXTURE_1D, GL_TEXTURE_3D and GL_TEXTURE_CUBE_MAP FloatVector4 texel; switch (texture_unit.currently_bound_target()) { diff --git a/Userland/Libraries/LibGL/SoftwareRasterizer.h b/Userland/Libraries/LibGL/SoftwareRasterizer.h index f8d5b03a60..320e168c0b 100644 --- a/Userland/Libraries/LibGL/SoftwareRasterizer.h +++ b/Userland/Libraries/LibGL/SoftwareRasterizer.h @@ -56,7 +56,7 @@ class SoftwareRasterizer final { public: SoftwareRasterizer(const Gfx::IntSize& min_size); - void submit_triangle(const GLTriangle& triangle, const Array<TextureUnit, 32>& texture_units); + void submit_triangle(GLTriangle const& triangle, TextureUnit::BoundList const& bound_texture_units); void resize(const Gfx::IntSize& min_size); void clear_color(const FloatVector4&); void clear_depth(float); diff --git a/Userland/Libraries/LibGL/Tex/TextureUnit.h b/Userland/Libraries/LibGL/Tex/TextureUnit.h index 06b51e3a68..8d52e86d4b 100644 --- a/Userland/Libraries/LibGL/Tex/TextureUnit.h +++ b/Userland/Libraries/LibGL/Tex/TextureUnit.h @@ -6,6 +6,7 @@ #pragma once +#include <AK/IntrusiveList.h> #include <AK/OwnPtr.h> #include <LibGL/Tex/Texture2D.h> @@ -35,6 +36,9 @@ public: bool texture_cube_map_enabled() const { return m_texture_cube_map_enabled; }; void set_texture_cube_map_enabled(bool texture_cube_map_enabled) { m_texture_cube_map_enabled = texture_cube_map_enabled; } + IntrusiveListNode<TextureUnit> m_bound_node; + using BoundList = IntrusiveList<&TextureUnit::m_bound_node>; + private: mutable RefPtr<Texture2D> m_texture_target_2d { nullptr }; mutable RefPtr<Texture> m_currently_bound_texture { nullptr }; |