From 00d46e5d77d7188d835627cd4c3d76152e4f7b3e Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Mon, 5 Sep 2022 00:40:27 +0200 Subject: [PATCH] LibGL+LibGPU+LibSoftGPU: Implement matrix stack per texture unit Each texture unit now has its own texture transformation matrix stack. Introduce a new texture unit configuration that is synced when changed. Because we're no longer passing a silly `Vector` when drawing each primitive, this results in a slightly improved frames per second :^) --- Tests/LibGL/TestRender.cpp | 24 ++++++ .../0008_test_pop_matrix_regression.qoi | Bin 0 -> 184 bytes Userland/Libraries/LibGL/ClipPlane.cpp | 2 +- Userland/Libraries/LibGL/ContextParameter.cpp | 16 +++- Userland/Libraries/LibGL/GLContext.cpp | 28 +++--- Userland/Libraries/LibGL/GLContext.h | 27 +++--- Userland/Libraries/LibGL/Lighting.cpp | 8 +- Userland/Libraries/LibGL/Matrix.cpp | 32 +++---- Userland/Libraries/LibGL/Tex/TextureUnit.h | 8 ++ Userland/Libraries/LibGL/Texture.cpp | 57 ++++++------ Userland/Libraries/LibGPU/Config.h | 2 +- Userland/Libraries/LibGPU/Device.h | 5 +- Userland/Libraries/LibGPU/Enums.h | 2 +- Userland/Libraries/LibGPU/RasterizerOptions.h | 3 - .../Libraries/LibGPU/StencilConfiguration.h | 1 - .../LibGPU/TexCoordGenerationConfig.h | 19 ---- .../LibGPU/TextureUnitConfiguration.h | 30 +++++++ Userland/Libraries/LibGPU/Vertex.h | 2 +- Userland/Libraries/LibSoftGPU/Clipper.cpp | 2 +- Userland/Libraries/LibSoftGPU/Device.cpp | 81 +++++++++--------- Userland/Libraries/LibSoftGPU/Device.h | 9 +- Userland/Libraries/LibSoftGPU/PixelQuad.h | 2 +- 22 files changed, 208 insertions(+), 152 deletions(-) create mode 100644 Tests/LibGL/reference-images/0008_test_pop_matrix_regression.qoi delete mode 100644 Userland/Libraries/LibGPU/TexCoordGenerationConfig.h create mode 100644 Userland/Libraries/LibGPU/TextureUnitConfiguration.h diff --git a/Tests/LibGL/TestRender.cpp b/Tests/LibGL/TestRender.cpp index e772db8f4f..f55bbf5371 100644 --- a/Tests/LibGL/TestRender.cpp +++ b/Tests/LibGL/TestRender.cpp @@ -228,3 +228,27 @@ TEST_CASE(0007_test_rgba_to_rgb_texture) context->present(); expect_bitmap_equals_reference(context->frontbuffer(), "0007_test_rgba_to_rgb_texture"sv); } + +TEST_CASE(0008_test_pop_matrix_regression) +{ + auto context = create_testing_context(64, 64); + + // Load identity matrix after popping + glMatrixMode(GL_MODELVIEW); + glTranslatef(10.f, 10.f, 10.f); + glPushMatrix(); + glPopMatrix(); + glLoadIdentity(); + + glBegin(GL_TRIANGLES); + glColor3f(0.f, 1.f, 0.f); + glVertex2f(.5f, -.5f); + glVertex2f(.0f, .5f); + glVertex2f(-.5f, -.5f); + glEnd(); + + EXPECT_EQ(glGetError(), 0u); + + context->present(); + expect_bitmap_equals_reference(context->frontbuffer(), "0008_test_pop_matrix_regression"sv); +} diff --git a/Tests/LibGL/reference-images/0008_test_pop_matrix_regression.qoi b/Tests/LibGL/reference-images/0008_test_pop_matrix_regression.qoi new file mode 100644 index 0000000000000000000000000000000000000000..091d4b11920f26e8c06c55f0545b49e341915589 GIT binary patch literal 184 zcmXTS&rD-rU~m9o7KXnV;LtyY{|pCA{}>!F{cUi_^q0XQ)1L-MOn(?0G5v0E%=DYV zG1IRGCrrN>oG|@taLV+P!70;^24_q^7@RSEZ*b1^oxwTNw+0tX-xypleQj{b^p(LS z)0YNUOkWsWF@0`u&GebUHPfdCH%y-x+%SD?aLe?O!7bB=26s#!7~C(plane) - GL_CLIP_PLANE0; auto eqn = FloatVector4(equation[0], equation[1], equation[2], equation[3]); - m_clip_plane_attributes.eye_clip_plane[plane_idx] = m_model_view_matrix * eqn; + m_clip_plane_attributes.eye_clip_plane[plane_idx] = model_view_matrix() * eqn; m_clip_planes_dirty = true; } diff --git a/Userland/Libraries/LibGL/ContextParameter.cpp b/Userland/Libraries/LibGL/ContextParameter.cpp index 965b3207fc..739b27e3e6 100644 --- a/Userland/Libraries/LibGL/ContextParameter.cpp +++ b/Userland/Libraries/LibGL/ContextParameter.cpp @@ -276,25 +276,29 @@ void GLContext::gl_disable(GLenum capability) case GL_TEXTURE_1D: m_active_texture_unit->set_texture_1d_enabled(false); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_2D: m_active_texture_unit->set_texture_2d_enabled(false); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_3D: m_active_texture_unit->set_texture_3d_enabled(false); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_CUBE_MAP: m_active_texture_unit->set_texture_cube_map_enabled(false); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_GEN_Q: case GL_TEXTURE_GEN_R: case GL_TEXTURE_GEN_S: case GL_TEXTURE_GEN_T: texture_coordinate_generation(m_active_texture_unit_index, capability).enabled = false; - m_texcoord_generation_dirty = true; + m_texture_units_dirty = true; break; default: dbgln_if(GL_DEBUG, "gl_disable({:#x}): unknown parameter", capability); @@ -426,25 +430,29 @@ void GLContext::gl_enable(GLenum capability) case GL_TEXTURE_1D: m_active_texture_unit->set_texture_1d_enabled(true); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_2D: m_active_texture_unit->set_texture_2d_enabled(true); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_3D: m_active_texture_unit->set_texture_3d_enabled(true); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_CUBE_MAP: m_active_texture_unit->set_texture_cube_map_enabled(true); m_sampler_config_is_dirty = true; + m_texture_units_dirty = true; break; case GL_TEXTURE_GEN_Q: case GL_TEXTURE_GEN_R: case GL_TEXTURE_GEN_S: case GL_TEXTURE_GEN_T: texture_coordinate_generation(m_active_texture_unit_index, capability).enabled = true; - m_texcoord_generation_dirty = true; + m_texture_units_dirty = true; break; default: dbgln_if(GL_DEBUG, "gl_enable({:#x}): unknown parameter", capability); @@ -522,10 +530,10 @@ void GLContext::get_floating_point(GLenum pname, T* params) }; switch (pname) { case GL_MODELVIEW_MATRIX: - flatten_and_assign_matrix(m_model_view_matrix); + flatten_and_assign_matrix(model_view_matrix()); return; case GL_PROJECTION_MATRIX: - flatten_and_assign_matrix(m_projection_matrix); + flatten_and_assign_matrix(projection_matrix()); return; } diff --git a/Userland/Libraries/LibGL/GLContext.cpp b/Userland/Libraries/LibGL/GLContext.cpp index da01df474c..161a0e79b8 100644 --- a/Userland/Libraries/LibGL/GLContext.cpp +++ b/Userland/Libraries/LibGL/GLContext.cpp @@ -59,14 +59,14 @@ GLContext::GLContext(RefPtr driver, NonnullOwnPtr devi // coordinate generation config. m_texture_coordinate_generation.resize(m_device_info.num_texture_units); for (auto& texture_coordinate_generation : m_texture_coordinate_generation) { - texture_coordinate_generation[0].object_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f }; - texture_coordinate_generation[0].eye_plane_coefficients = { 1.0f, 0.0f, 0.0f, 0.0f }; - texture_coordinate_generation[1].object_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f }; - texture_coordinate_generation[1].eye_plane_coefficients = { 0.0f, 1.0f, 0.0f, 0.0f }; - texture_coordinate_generation[2].object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f }; - texture_coordinate_generation[2].eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f }; - texture_coordinate_generation[3].object_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f }; - texture_coordinate_generation[3].eye_plane_coefficients = { 0.0f, 0.0f, 0.0f, 0.0f }; + texture_coordinate_generation[0].object_plane_coefficients = { 1.f, 0.f, 0.f, 0.f }; + texture_coordinate_generation[0].eye_plane_coefficients = { 1.f, 0.f, 0.f, 0.f }; + texture_coordinate_generation[1].object_plane_coefficients = { 0.f, 1.f, 0.f, 0.f }; + texture_coordinate_generation[1].eye_plane_coefficients = { 0.f, 1.f, 0.f, 0.f }; + texture_coordinate_generation[2].object_plane_coefficients = { 0.f, 0.f, 0.f, 0.f }; + texture_coordinate_generation[2].eye_plane_coefficients = { 0.f, 0.f, 0.f, 0.f }; + texture_coordinate_generation[3].object_plane_coefficients = { 0.f, 0.f, 0.f, 0.f }; + texture_coordinate_generation[3].eye_plane_coefficients = { 0.f, 0.f, 0.f, 0.f }; } build_extension_string(); @@ -134,12 +134,6 @@ void GLContext::gl_end() RETURN_WITH_ERROR_IF(!m_in_draw_state, GL_INVALID_OPERATION); m_in_draw_state = false; - Vector enabled_texture_units; - for (size_t i = 0; i < m_texture_units.size(); ++i) { - if (m_texture_units[i].texture_2d_enabled()) - enabled_texture_units.append(i); - } - sync_device_config(); GPU::PrimitiveType primitive_type; @@ -174,7 +168,7 @@ void GLContext::gl_end() VERIFY_NOT_REACHED(); } - m_rasterizer->draw_primitives(primitive_type, m_model_view_matrix, m_projection_matrix, m_texture_matrix, m_vertex_list, enabled_texture_units); + m_rasterizer->draw_primitives(primitive_type, model_view_matrix(), projection_matrix(), m_vertex_list); m_vertex_list.clear_with_capacity(); } @@ -832,7 +826,7 @@ void GLContext::gl_raster_pos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_raster_pos, x, y, z, w); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - m_rasterizer->set_raster_position({ x, y, z, w }, m_model_view_matrix, m_projection_matrix); + m_rasterizer->set_raster_position({ x, y, z, w }, model_view_matrix(), projection_matrix()); } void GLContext::gl_line_width(GLfloat width) @@ -913,7 +907,7 @@ void GLContext::present() void GLContext::sync_device_config() { sync_device_sampler_config(); - sync_device_texcoord_config(); + sync_device_texture_units(); sync_light_state(); sync_stencil_configuration(); sync_clip_planes(); diff --git a/Userland/Libraries/LibGL/GLContext.h b/Userland/Libraries/LibGL/GLContext.h index 13f523475a..c14e23a651 100644 --- a/Userland/Libraries/LibGL/GLContext.h +++ b/Userland/Libraries/LibGL/GLContext.h @@ -217,7 +217,7 @@ public: private: void sync_device_config(); void sync_device_sampler_config(); - void sync_device_texcoord_config(); + void sync_device_texture_units(); void sync_light_state(); void sync_stencil_configuration(); void sync_clip_planes(); @@ -256,16 +256,22 @@ private: GLenum m_current_draw_mode; GLenum m_current_matrix_mode { GL_MODELVIEW }; - FloatMatrix4x4 m_projection_matrix { FloatMatrix4x4::identity() }; - FloatMatrix4x4 m_model_view_matrix { FloatMatrix4x4::identity() }; - FloatMatrix4x4 m_texture_matrix { FloatMatrix4x4::identity() }; - FloatMatrix4x4* m_current_matrix { &m_model_view_matrix }; - Vector m_projection_matrix_stack; - Vector m_model_view_matrix_stack; - // FIXME: implement multi-texturing: the texture matrix stack should live inside a texture unit - Vector m_texture_matrix_stack; + FloatMatrix4x4& projection_matrix() { return m_projection_matrix_stack.last(); } + FloatMatrix4x4& model_view_matrix() { return m_model_view_matrix_stack.last(); } + + Vector m_projection_matrix_stack { FloatMatrix4x4::identity() }; + Vector m_model_view_matrix_stack { FloatMatrix4x4::identity() }; Vector* m_current_matrix_stack { &m_model_view_matrix_stack }; + FloatMatrix4x4* m_current_matrix { &m_current_matrix_stack->last() }; + + ALWAYS_INLINE void update_current_matrix(FloatMatrix4x4 const& new_matrix) + { + *m_current_matrix = new_matrix; + + if (m_current_matrix_mode == GL_TEXTURE) + m_texture_units_dirty = true; + } Gfx::IntRect m_viewport; @@ -353,6 +359,7 @@ private: Vector m_texture_units; TextureUnit* m_active_texture_unit; size_t m_active_texture_unit_index { 0 }; + bool m_texture_units_dirty { true }; // Texture coordinate generation state struct TextureCoordinateGeneration { @@ -362,8 +369,6 @@ private: FloatVector4 eye_plane_coefficients { 0.0f, 0.0f, 0.0f, 0.0f }; }; Vector> m_texture_coordinate_generation; - bool m_texcoord_generation_dirty { true }; - ALWAYS_INLINE TextureCoordinateGeneration& texture_coordinate_generation(size_t texture_unit, GLenum capability) { return m_texture_coordinate_generation[texture_unit][capability - GL_TEXTURE_GEN_S]; diff --git a/Userland/Libraries/LibGL/Lighting.cpp b/Userland/Libraries/LibGL/Lighting.cpp index 13dd3f7401..9c24b7834f 100644 --- a/Userland/Libraries/LibGL/Lighting.cpp +++ b/Userland/Libraries/LibGL/Lighting.cpp @@ -249,7 +249,7 @@ void GLContext::gl_lightfv(GLenum light, GLenum pname, GLfloat const* params) break; case GL_POSITION: light_state.position = { params[0], params[1], params[2], params[3] }; - light_state.position = m_model_view_matrix * light_state.position; + light_state.position = model_view_matrix() * light_state.position; break; case GL_CONSTANT_ATTENUATION: RETURN_WITH_ERROR_IF(params[0] < 0.f, GL_INVALID_VALUE); @@ -277,7 +277,7 @@ void GLContext::gl_lightfv(GLenum light, GLenum pname, GLfloat const* params) } case GL_SPOT_DIRECTION: { FloatVector4 direction_vector = { params[0], params[1], params[2], 0.f }; - direction_vector = m_model_view_matrix * direction_vector; + direction_vector = model_view_matrix() * direction_vector; light_state.spotlight_direction = direction_vector.xyz(); break; } @@ -313,7 +313,7 @@ void GLContext::gl_lightiv(GLenum light, GLenum pname, GLint const* params) break; case GL_POSITION: light_state.position = to_float_vector(params[0], params[1], params[2], params[3]); - light_state.position = m_model_view_matrix * light_state.position; + light_state.position = model_view_matrix() * light_state.position; break; case GL_CONSTANT_ATTENUATION: RETURN_WITH_ERROR_IF(params[0] < 0, GL_INVALID_VALUE); @@ -341,7 +341,7 @@ void GLContext::gl_lightiv(GLenum light, GLenum pname, GLint const* params) } case GL_SPOT_DIRECTION: { auto direction_vector = to_float_vector(params[0], params[1], params[2], 0.0f); - direction_vector = m_model_view_matrix * direction_vector; + direction_vector = model_view_matrix() * direction_vector; light_state.spotlight_direction = direction_vector.xyz(); break; } diff --git a/Userland/Libraries/LibGL/Matrix.cpp b/Userland/Libraries/LibGL/Matrix.cpp index 186661c777..dd34d4e097 100644 --- a/Userland/Libraries/LibGL/Matrix.cpp +++ b/Userland/Libraries/LibGL/Matrix.cpp @@ -45,7 +45,7 @@ void GLContext::gl_frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdou 0, 0, c, d, 0, 0, -1, 0 }; - *m_current_matrix = *m_current_matrix * frustum; + update_current_matrix(*m_current_matrix * frustum); } void GLContext::gl_load_identity() @@ -53,7 +53,7 @@ void GLContext::gl_load_identity() APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_load_identity); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - *m_current_matrix = FloatMatrix4x4::identity(); + update_current_matrix(FloatMatrix4x4::identity()); } void GLContext::gl_load_matrix(FloatMatrix4x4 const& matrix) @@ -61,7 +61,7 @@ void GLContext::gl_load_matrix(FloatMatrix4x4 const& matrix) APPEND_TO_CALL_LIST_WITH_ARG_AND_RETURN_IF_NEEDED(gl_load_matrix, matrix); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - *m_current_matrix = matrix; + update_current_matrix(matrix); } void GLContext::gl_matrix_mode(GLenum mode) @@ -73,20 +73,18 @@ void GLContext::gl_matrix_mode(GLenum mode) m_current_matrix_mode = mode; switch (mode) { case GL_MODELVIEW: - m_current_matrix = &m_model_view_matrix; m_current_matrix_stack = &m_model_view_matrix_stack; break; case GL_PROJECTION: - m_current_matrix = &m_projection_matrix; m_current_matrix_stack = &m_projection_matrix_stack; break; case GL_TEXTURE: - m_current_matrix = &m_texture_matrix; - m_current_matrix_stack = &m_texture_matrix_stack; + m_current_matrix_stack = &m_active_texture_unit->texture_matrix_stack(); break; default: VERIFY_NOT_REACHED(); } + m_current_matrix = &m_current_matrix_stack->last(); } void GLContext::gl_mult_matrix(FloatMatrix4x4 const& matrix) @@ -94,7 +92,7 @@ void GLContext::gl_mult_matrix(FloatMatrix4x4 const& matrix) APPEND_TO_CALL_LIST_WITH_ARG_AND_RETURN_IF_NEEDED(gl_mult_matrix, matrix); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - *m_current_matrix = *m_current_matrix * matrix; + update_current_matrix(*m_current_matrix * matrix); } void GLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) @@ -117,25 +115,27 @@ void GLContext::gl_ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdoubl 0, 0, static_cast(-2 / fn), static_cast(tz), 0, 0, 0, 1 }; - *m_current_matrix = *m_current_matrix * projection; + update_current_matrix(*m_current_matrix * projection); } void GLContext::gl_pop_matrix() { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_pop_matrix); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF((*m_current_matrix_stack).is_empty(), GL_STACK_UNDERFLOW); + RETURN_WITH_ERROR_IF(m_current_matrix_stack->size() <= 1, GL_STACK_UNDERFLOW); - *m_current_matrix = (*m_current_matrix_stack).take_last(); + m_current_matrix_stack->take_last(); + m_current_matrix = &m_current_matrix_stack->last(); } void GLContext::gl_push_matrix() { APPEND_TO_CALL_LIST_AND_RETURN_IF_NEEDED(gl_push_matrix); RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); - RETURN_WITH_ERROR_IF((*m_current_matrix_stack).size() >= matrix_stack_limit(m_current_matrix_mode), GL_STACK_OVERFLOW); + RETURN_WITH_ERROR_IF(m_current_matrix_stack->size() >= matrix_stack_limit(m_current_matrix_mode), GL_STACK_OVERFLOW); - (*m_current_matrix_stack).append(*m_current_matrix); + m_current_matrix_stack->append(*m_current_matrix); + m_current_matrix = &m_current_matrix_stack->last(); } void GLContext::gl_rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) @@ -147,7 +147,7 @@ void GLContext::gl_rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) if (axis.length() > 0.f) axis.normalize(); auto rotation_mat = Gfx::rotation_matrix(axis, angle * static_cast(M_PI * 2 / 360)); - *m_current_matrix = *m_current_matrix * rotation_mat; + update_current_matrix(*m_current_matrix * rotation_mat); } void GLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z) @@ -156,7 +156,7 @@ void GLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z) RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); auto scale_matrix = Gfx::scale_matrix(FloatVector3 { static_cast(x), static_cast(y), static_cast(z) }); - *m_current_matrix = *m_current_matrix * scale_matrix; + update_current_matrix(*m_current_matrix * scale_matrix); } void GLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) @@ -165,7 +165,7 @@ void GLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) RETURN_WITH_ERROR_IF(m_in_draw_state, GL_INVALID_OPERATION); auto translation_matrix = Gfx::translation_matrix(FloatVector3 { static_cast(x), static_cast(y), static_cast(z) }); - *m_current_matrix = *m_current_matrix * translation_matrix; + update_current_matrix(*m_current_matrix * translation_matrix); } } diff --git a/Userland/Libraries/LibGL/Tex/TextureUnit.h b/Userland/Libraries/LibGL/Tex/TextureUnit.h index 0dc2ac8a18..e1782e4447 100644 --- a/Userland/Libraries/LibGL/Tex/TextureUnit.h +++ b/Userland/Libraries/LibGL/Tex/TextureUnit.h @@ -8,7 +8,9 @@ #pragma once #include +#include #include +#include namespace GL { @@ -49,6 +51,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; } + FloatMatrix4x4& texture_matrix() { return m_texture_matrix_stack.last(); } + Vector& texture_matrix_stack() { return m_texture_matrix_stack; } + private: GLenum m_alpha_combinator { GL_MODULATE }; Array m_alpha_operand { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }; @@ -69,6 +74,9 @@ private: bool m_texture_2d_enabled { false }; bool m_texture_3d_enabled { false }; bool m_texture_cube_map_enabled { false }; + + // Matrix stack for this unit + Vector m_texture_matrix_stack { FloatMatrix4x4::identity() }; }; } diff --git a/Userland/Libraries/LibGL/Texture.cpp b/Userland/Libraries/LibGL/Texture.cpp index 6ef6819a9f..9a8c5158b2 100644 --- a/Userland/Libraries/LibGL/Texture.cpp +++ b/Userland/Libraries/LibGL/Texture.cpp @@ -19,6 +19,11 @@ void GLContext::gl_active_texture(GLenum texture) m_active_texture_unit_index = texture - GL_TEXTURE0; m_active_texture_unit = &m_texture_units.at(m_active_texture_unit_index); + + if (m_current_matrix_mode == GL_TEXTURE) { + m_current_matrix_stack = &m_active_texture_unit->texture_matrix_stack(); + m_current_matrix = &m_current_matrix_stack->last(); + } } void GLContext::gl_bind_texture(GLenum target, GLuint texture) @@ -471,7 +476,7 @@ void GLContext::gl_tex_gen(GLenum coord, GLenum pname, GLint param) GLenum const capability = GL_TEXTURE_GEN_S + (coord - GL_S); texture_coordinate_generation(m_active_texture_unit_index, capability).generation_mode = param; - m_texcoord_generation_dirty = true; + m_texture_units_dirty = true; } void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* params) @@ -506,7 +511,7 @@ void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* par texture_coordinate_generation(m_active_texture_unit_index, capability).object_plane_coefficients = { params[0], params[1], params[2], params[3] }; break; case GL_EYE_PLANE: { - auto const& inverse_model_view = m_model_view_matrix.inverse(); + auto const& inverse_model_view = model_view_matrix().inverse(); auto input_coefficients = FloatVector4 { params[0], params[1], params[2], params[3] }; // Note: we are allowed to store transformed coefficients here, according to the documentation on @@ -522,7 +527,7 @@ void GLContext::gl_tex_gen_floatv(GLenum coord, GLenum pname, GLfloat const* par VERIFY_NOT_REACHED(); } - m_texcoord_generation_dirty = true; + m_texture_units_dirty = true; } void GLContext::gl_tex_image_2d(GLenum target, GLint level, GLint internal_format, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid const* data) @@ -909,39 +914,41 @@ void GLContext::sync_device_sampler_config() } } -void GLContext::sync_device_texcoord_config() +void GLContext::sync_device_texture_units() { - if (!m_texcoord_generation_dirty) + if (!m_texture_units_dirty) return; - m_texcoord_generation_dirty = false; + m_texture_units_dirty = false; - auto options = m_rasterizer->options(); - - for (size_t i = 0; i < m_device_info.num_texture_units; ++i) { + for (GPU::TextureUnitIndex i = 0; i < m_device_info.num_texture_units; ++i) { + GPU::TextureUnitConfiguration texture_unit_configuration; + texture_unit_configuration.enabled = m_texture_units[i].texture_2d_enabled(); + texture_unit_configuration.transformation_matrix = m_texture_units[i].texture_matrix(); + // Tex coord generation u8 enabled_coordinates = GPU::TexCoordGenerationCoordinate::None; for (GLenum capability = GL_TEXTURE_GEN_S; capability <= GL_TEXTURE_GEN_Q; ++capability) { auto const context_coordinate_config = texture_coordinate_generation(i, capability); if (!context_coordinate_config.enabled) continue; - GPU::TexCoordGenerationConfig* texcoord_generation_config; + GPU::TexCoordGeneration* texcoord_generation; switch (capability) { case GL_TEXTURE_GEN_S: enabled_coordinates |= GPU::TexCoordGenerationCoordinate::S; - texcoord_generation_config = &options.texcoord_generation_config[i][0]; + texcoord_generation = &texture_unit_configuration.tex_coord_generation[0]; break; case GL_TEXTURE_GEN_T: enabled_coordinates |= GPU::TexCoordGenerationCoordinate::T; - texcoord_generation_config = &options.texcoord_generation_config[i][1]; + texcoord_generation = &texture_unit_configuration.tex_coord_generation[1]; break; case GL_TEXTURE_GEN_R: enabled_coordinates |= GPU::TexCoordGenerationCoordinate::R; - texcoord_generation_config = &options.texcoord_generation_config[i][2]; + texcoord_generation = &texture_unit_configuration.tex_coord_generation[2]; break; case GL_TEXTURE_GEN_Q: enabled_coordinates |= GPU::TexCoordGenerationCoordinate::Q; - texcoord_generation_config = &options.texcoord_generation_config[i][3]; + texcoord_generation = &texture_unit_configuration.tex_coord_generation[3]; break; default: VERIFY_NOT_REACHED(); @@ -949,28 +956,30 @@ void GLContext::sync_device_texcoord_config() switch (context_coordinate_config.generation_mode) { case GL_OBJECT_LINEAR: - texcoord_generation_config->mode = GPU::TexCoordGenerationMode::ObjectLinear; - texcoord_generation_config->coefficients = context_coordinate_config.object_plane_coefficients; + texcoord_generation->mode = GPU::TexCoordGenerationMode::ObjectLinear; + texcoord_generation->coefficients = context_coordinate_config.object_plane_coefficients; break; case GL_EYE_LINEAR: - texcoord_generation_config->mode = GPU::TexCoordGenerationMode::EyeLinear; - texcoord_generation_config->coefficients = context_coordinate_config.eye_plane_coefficients; + texcoord_generation->mode = GPU::TexCoordGenerationMode::EyeLinear; + texcoord_generation->coefficients = context_coordinate_config.eye_plane_coefficients; break; case GL_SPHERE_MAP: - texcoord_generation_config->mode = GPU::TexCoordGenerationMode::SphereMap; + texcoord_generation->mode = GPU::TexCoordGenerationMode::SphereMap; break; case GL_REFLECTION_MAP: - texcoord_generation_config->mode = GPU::TexCoordGenerationMode::ReflectionMap; + texcoord_generation->mode = GPU::TexCoordGenerationMode::ReflectionMap; break; case GL_NORMAL_MAP: - texcoord_generation_config->mode = GPU::TexCoordGenerationMode::NormalMap; + texcoord_generation->mode = GPU::TexCoordGenerationMode::NormalMap; break; + default: + VERIFY_NOT_REACHED(); } } - options.texcoord_generation_enabled_coordinates[i] = enabled_coordinates; + texture_unit_configuration.tex_coord_generation_enabled = enabled_coordinates; + + m_rasterizer->set_texture_unit_configuration(i, texture_unit_configuration); } - - m_rasterizer->set_options(options); } } diff --git a/Userland/Libraries/LibGPU/Config.h b/Userland/Libraries/LibGPU/Config.h index 4a61826025..f3ab5e5c3f 100644 --- a/Userland/Libraries/LibGPU/Config.h +++ b/Userland/Libraries/LibGPU/Config.h @@ -18,6 +18,6 @@ using StencilType = u8; // FIXME: This constant was originally introduced in LibSoftGPU and is currently used in the Vertex struct. // Once we refactor the interface this should move back into LibSoftGPU. -static constexpr int NUM_SAMPLERS = 2; +static constexpr int NUM_TEXTURE_UNITS = 2; } diff --git a/Userland/Libraries/LibGPU/Device.h b/Userland/Libraries/LibGPU/Device.h index 279a1355ce..270d44dfc0 100644 --- a/Userland/Libraries/LibGPU/Device.h +++ b/Userland/Libraries/LibGPU/Device.h @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -38,7 +38,7 @@ public: virtual DeviceInfo info() const = 0; - virtual void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector& vertices, Vector const& enabled_texture_units) = 0; + virtual void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector& vertices) = 0; virtual void resize(Gfx::IntSize const& min_size) = 0; virtual void clear_color(FloatVector4 const&) = 0; virtual void clear_depth(DepthType) = 0; @@ -61,6 +61,7 @@ public: virtual void set_light_state(unsigned, Light const&) = 0; virtual void set_material_state(Face, Material const&) = 0; virtual void set_stencil_configuration(Face, StencilConfiguration const&) = 0; + virtual void set_texture_unit_configuration(TextureUnitIndex, TextureUnitConfiguration const&) = 0; virtual void set_clip_planes(Vector const&) = 0; virtual RasterPosition raster_position() const = 0; diff --git a/Userland/Libraries/LibGPU/Enums.h b/Userland/Libraries/LibGPU/Enums.h index 3486fd03d4..5cf8922761 100644 --- a/Userland/Libraries/LibGPU/Enums.h +++ b/Userland/Libraries/LibGPU/Enums.h @@ -120,7 +120,7 @@ enum StencilTestFunction { NotEqual, }; -enum TexCoordGenerationCoordinate { +enum TexCoordGenerationCoordinate : u8 { None = 0x0, S = 0x1, T = 0x2, diff --git a/Userland/Libraries/LibGPU/RasterizerOptions.h b/Userland/Libraries/LibGPU/RasterizerOptions.h index a5ae66c6c1..82130292c4 100644 --- a/Userland/Libraries/LibGPU/RasterizerOptions.h +++ b/Userland/Libraries/LibGPU/RasterizerOptions.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -53,8 +52,6 @@ struct RasterizerOptions { WindingOrder front_face { WindingOrder::CounterClockwise }; bool cull_back { true }; bool cull_front { false }; - Array texcoord_generation_enabled_coordinates {}; - Array, NUM_SAMPLERS> texcoord_generation_config {}; Gfx::IntRect viewport; bool lighting_enabled { false }; bool color_material_enabled { false }; diff --git a/Userland/Libraries/LibGPU/StencilConfiguration.h b/Userland/Libraries/LibGPU/StencilConfiguration.h index b68b2d6ba1..1c0d9503f0 100644 --- a/Userland/Libraries/LibGPU/StencilConfiguration.h +++ b/Userland/Libraries/LibGPU/StencilConfiguration.h @@ -6,7 +6,6 @@ #pragma once -#include #include namespace GPU { diff --git a/Userland/Libraries/LibGPU/TexCoordGenerationConfig.h b/Userland/Libraries/LibGPU/TexCoordGenerationConfig.h deleted file mode 100644 index dbd8db63e6..0000000000 --- a/Userland/Libraries/LibGPU/TexCoordGenerationConfig.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2022, Jelle Raaijmakers - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace GPU { - -struct TexCoordGenerationConfig { - GPU::TexCoordGenerationMode mode { GPU::TexCoordGenerationMode::EyeLinear }; - FloatVector4 coefficients {}; -}; - -} diff --git a/Userland/Libraries/LibGPU/TextureUnitConfiguration.h b/Userland/Libraries/LibGPU/TextureUnitConfiguration.h new file mode 100644 index 0000000000..686dba5e5d --- /dev/null +++ b/Userland/Libraries/LibGPU/TextureUnitConfiguration.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Jelle Raaijmakers + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace GPU { + +typedef u8 TextureUnitIndex; + +struct TexCoordGeneration { + bool enabled; + TexCoordGenerationMode mode; + FloatVector4 coefficients; +}; + +struct TextureUnitConfiguration { + bool enabled { false }; + FloatMatrix4x4 transformation_matrix { FloatMatrix4x4::identity() }; + u8 tex_coord_generation_enabled; + TexCoordGeneration tex_coord_generation[4]; +}; + +} diff --git a/Userland/Libraries/LibGPU/Vertex.h b/Userland/Libraries/LibGPU/Vertex.h index 5307dd083c..e11e1eebc6 100644 --- a/Userland/Libraries/LibGPU/Vertex.h +++ b/Userland/Libraries/LibGPU/Vertex.h @@ -20,7 +20,7 @@ struct Vertex { FloatVector4 clip_coordinates; FloatVector4 window_coordinates; FloatVector4 color; - Array tex_coords; + Array tex_coords; FloatVector3 normal; }; diff --git a/Userland/Libraries/LibSoftGPU/Clipper.cpp b/Userland/Libraries/LibSoftGPU/Clipper.cpp index b9a6351058..b8c79209e9 100644 --- a/Userland/Libraries/LibSoftGPU/Clipper.cpp +++ b/Userland/Libraries/LibSoftGPU/Clipper.cpp @@ -61,7 +61,7 @@ static GPU::Vertex clip_intersection_point(GPU::Vertex const& p1, GPU::Vertex co out.eye_coordinates = mix(p1.eye_coordinates, p2.eye_coordinates, a); out.clip_coordinates = mix(p1.clip_coordinates, p2.clip_coordinates, a); out.color = mix(p1.color, p2.color, a); - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) + for (size_t i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) out.tex_coords[i] = mix(p1.tex_coords[i], p2.tex_coords[i], a); out.normal = mix(p1.normal, p2.normal, a); return out; diff --git a/Userland/Libraries/LibSoftGPU/Device.cpp b/Userland/Libraries/LibSoftGPU/Device.cpp index d0a44f9bad..8ef5618c4e 100644 --- a/Userland/Libraries/LibSoftGPU/Device.cpp +++ b/Userland/Libraries/LibSoftGPU/Device.cpp @@ -543,7 +543,7 @@ void Device::rasterize_line_antialiased(GPU::Vertex& from, GPU::Vertex& to) // FIXME: interpolate color, tex coords and fog depth along the distance of the line // in clip space (i.e. NOT distance_from_line) quad.vertex_color = from_color4; - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) + for (size_t i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) quad.texture_coordinates[i] = expand4(from.tex_coords[i]); quad.fog_depth = from_fog_depth4; }); @@ -590,7 +590,7 @@ void Device::rasterize_point_aliased(GPU::Vertex& point) }, [&point](auto& quad) { quad.vertex_color = expand4(point.color); - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) + for (size_t i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) quad.texture_coordinates[i] = expand4(point.tex_coords[i]); quad.fog_depth = expand4(abs(point.eye_coordinates.z())); }); @@ -625,7 +625,7 @@ void Device::rasterize_point_antialiased(GPU::Vertex& point) }, [&point](auto& quad) { quad.vertex_color = expand4(point.color); - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) + for (size_t i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) quad.texture_coordinates[i] = expand4(point.tex_coords[i]); quad.fog_depth = expand4(abs(point.eye_coordinates.z())); }); @@ -634,7 +634,7 @@ void Device::rasterize_point_antialiased(GPU::Vertex& point) void Device::rasterize_point(GPU::Vertex& point) { // Divide texture coordinates R, S and T by Q - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) { + for (size_t i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) { auto& tex_coord = point.tex_coords[i]; auto one_over_w = 1 / tex_coord.w(); tex_coord = { @@ -790,7 +790,7 @@ void Device::rasterize_triangle(Triangle& triangle) else quad.vertex_color = expand4(vertex0.color); - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) + for (GPU::TextureUnitIndex i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) quad.texture_coordinates[i] = interpolate(expand4(vertex0.tex_coords[i]), expand4(vertex1.tex_coords[i]), expand4(vertex2.tex_coords[i]), quad.barycentrics); if (m_options.fog_enabled) @@ -810,7 +810,7 @@ GPU::DeviceInfo Device::info() const return { .vendor_name = "SerenityOS", .device_name = "SoftGPU", - .num_texture_units = GPU::NUM_SAMPLERS, + .num_texture_units = GPU::NUM_TEXTURE_UNITS, .num_lights = NUM_LIGHTS, .max_clip_planes = MAX_CLIP_PLANES, .max_texture_lod_bias = MAX_TEXTURE_LOD_BIAS, @@ -820,18 +820,17 @@ GPU::DeviceInfo Device::info() const }; } -static void generate_texture_coordinates(GPU::Vertex& vertex, GPU::RasterizerOptions const& options) +static void generate_texture_coordinates(GPU::Vertex const& vertex, FloatVector4& tex_coord, GPU::TextureUnitConfiguration const& texture_unit_configuration) { - auto generate_coordinate = [&](size_t texcoord_index, size_t config_index) -> float { - auto mode = options.texcoord_generation_config[texcoord_index][config_index].mode; - - switch (mode) { + auto generate_coordinate = [&](size_t config_index) -> float { + auto const& tex_coord_generation = texture_unit_configuration.tex_coord_generation[config_index]; + switch (tex_coord_generation.mode) { case GPU::TexCoordGenerationMode::ObjectLinear: { - auto coefficients = options.texcoord_generation_config[texcoord_index][config_index].coefficients; + auto coefficients = tex_coord_generation.coefficients; return coefficients.dot(vertex.position); } case GPU::TexCoordGenerationMode::EyeLinear: { - auto coefficients = options.texcoord_generation_config[texcoord_index][config_index].coefficients; + auto coefficients = tex_coord_generation.coefficients; return coefficients.dot(vertex.eye_coordinates); } case GPU::TexCoordGenerationMode::SphereMap: { @@ -853,21 +852,20 @@ static void generate_texture_coordinates(GPU::Vertex& vertex, GPU::RasterizerOpt case GPU::TexCoordGenerationMode::NormalMap: { return vertex.normal[config_index]; } - default: - VERIFY_NOT_REACHED(); } + VERIFY_NOT_REACHED(); }; - for (size_t i = 0; i < vertex.tex_coords.size(); ++i) { - auto& tex_coord = vertex.tex_coords[i]; - auto const enabled_coords = options.texcoord_generation_enabled_coordinates[i]; - tex_coord = { - ((enabled_coords & GPU::TexCoordGenerationCoordinate::S) > 0) ? generate_coordinate(i, 0) : tex_coord.x(), - ((enabled_coords & GPU::TexCoordGenerationCoordinate::T) > 0) ? generate_coordinate(i, 1) : tex_coord.y(), - ((enabled_coords & GPU::TexCoordGenerationCoordinate::R) > 0) ? generate_coordinate(i, 2) : tex_coord.z(), - ((enabled_coords & GPU::TexCoordGenerationCoordinate::Q) > 0) ? generate_coordinate(i, 3) : tex_coord.w(), - }; - } + auto const enabled_coords = texture_unit_configuration.tex_coord_generation_enabled; + if (enabled_coords == GPU::TexCoordGenerationCoordinate::None) + return; + + tex_coord = { + ((enabled_coords & GPU::TexCoordGenerationCoordinate::S) > 0) ? generate_coordinate(0) : tex_coord.x(), + ((enabled_coords & GPU::TexCoordGenerationCoordinate::T) > 0) ? generate_coordinate(1) : tex_coord.y(), + ((enabled_coords & GPU::TexCoordGenerationCoordinate::R) > 0) ? generate_coordinate(2) : tex_coord.z(), + ((enabled_coords & GPU::TexCoordGenerationCoordinate::Q) > 0) ? generate_coordinate(3) : tex_coord.w(), + }; } void Device::calculate_vertex_lighting(GPU::Vertex& vertex) const @@ -989,8 +987,7 @@ void Device::calculate_vertex_lighting(GPU::Vertex& vertex) const vertex.color.clamp(0.0f, 1.0f); } -void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, - FloatMatrix4x4 const& texture_transform, Vector& vertices, Vector const& enabled_texture_units) +void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector& vertices) { // At this point, the user has effectively specified that they are done with defining the geometry // of what they want to draw. We now need to do a few things (https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview): @@ -1005,17 +1002,10 @@ void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 c if (vertices.is_empty()) return; - m_enabled_texture_units = enabled_texture_units; - // Set up normals transform by taking the upper left 3x3 elements from the model view matrix // See section 2.11.3 of the OpenGL 1.5 spec auto const normal_transform = model_view_transform.submatrix_from_topleft<3>().transpose().inverse(); - // Generate texture coordinates if at least one coordinate is enabled - bool texture_coordinate_generation_enabled = any_of( - m_options.texcoord_generation_enabled_coordinates, - [](auto coordinates_enabled) { return coordinates_enabled != GPU::TexCoordGenerationCoordinate::None; }); - // First, transform all vertices for (auto& vertex : vertices) { vertex.eye_coordinates = model_view_transform * vertex.position; @@ -1028,11 +1018,13 @@ void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 c vertex.clip_coordinates = projection_transform * vertex.eye_coordinates; - if (texture_coordinate_generation_enabled) - generate_texture_coordinates(vertex, m_options); - - for (size_t i = 0; i < GPU::NUM_SAMPLERS; ++i) - vertex.tex_coords[i] = texture_transform * vertex.tex_coords[i]; + for (GPU::TextureUnitIndex i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) { + auto const& texture_unit_configuration = m_texture_unit_configuration[i]; + if (!texture_unit_configuration.enabled) + continue; + generate_texture_coordinates(vertex, vertex.tex_coords[i], texture_unit_configuration); + vertex.tex_coords[i] = texture_unit_configuration.transformation_matrix * vertex.tex_coords[i]; + } } // Window coordinate calculation @@ -1188,10 +1180,12 @@ void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 c ALWAYS_INLINE void Device::shade_fragments(PixelQuad& quad) { - Array, GPU::NUM_SAMPLERS> texture_stage_texel; + Array, GPU::NUM_TEXTURE_UNITS> texture_stage_texel; auto current_color = quad.vertex_color; - for (size_t i : m_enabled_texture_units) { + for (GPU::TextureUnitIndex i = 0; i < GPU::NUM_TEXTURE_UNITS; ++i) { + if (!m_texture_unit_configuration[i].enabled) + continue; auto const& sampler = m_samplers[i]; auto texel = sampler.sample_2d(quad.texture_coordinates[i].xy()); @@ -1661,6 +1655,11 @@ void Device::set_stencil_configuration(GPU::Face face, GPU::StencilConfiguration m_stencil_configuration[face] = stencil_configuration; } +void Device::set_texture_unit_configuration(GPU::TextureUnitIndex index, GPU::TextureUnitConfiguration const& configuration) +{ + m_texture_unit_configuration[index] = configuration; +} + void Device::set_raster_position(GPU::RasterPosition const& raster_position) { m_raster_position = raster_position; diff --git a/Userland/Libraries/LibSoftGPU/Device.h b/Userland/Libraries/LibSoftGPU/Device.h index 4fd6fcafac..5641d9b9c0 100644 --- a/Userland/Libraries/LibSoftGPU/Device.h +++ b/Userland/Libraries/LibSoftGPU/Device.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,7 +47,7 @@ public: virtual GPU::DeviceInfo info() const override; - virtual void draw_primitives(GPU::PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, FloatMatrix4x4 const& texture_transform, Vector& vertices, Vector const& enabled_texture_units) override; + virtual void draw_primitives(GPU::PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector& vertices) override; virtual void resize(Gfx::IntSize const& min_size) override; virtual void clear_color(FloatVector4 const&) override; virtual void clear_depth(GPU::DepthType) override; @@ -70,6 +70,7 @@ public: virtual void set_light_state(unsigned, GPU::Light const&) override; virtual void set_material_state(GPU::Face, GPU::Material const&) override; virtual void set_stencil_configuration(GPU::Face, GPU::StencilConfiguration const&) override; + virtual void set_texture_unit_configuration(GPU::TextureUnitIndex, GPU::TextureUnitConfiguration const&) override; virtual void set_clip_planes(Vector const&) override; virtual GPU::RasterPosition raster_position() const override { return m_raster_position; } @@ -107,14 +108,14 @@ private: Vector m_triangle_list; Vector m_processed_triangles; Vector m_clipped_vertices; - Array m_samplers; - Vector m_enabled_texture_units; + Array m_samplers; AlphaBlendFactors m_alpha_blend_factors; Array m_lights; Array m_materials; GPU::RasterPosition m_raster_position; Vector m_clip_planes; Array m_stencil_configuration; + Array m_texture_unit_configuration; }; } diff --git a/Userland/Libraries/LibSoftGPU/PixelQuad.h b/Userland/Libraries/LibSoftGPU/PixelQuad.h index af3ace084f..009ff33c03 100644 --- a/Userland/Libraries/LibSoftGPU/PixelQuad.h +++ b/Userland/Libraries/LibSoftGPU/PixelQuad.h @@ -25,7 +25,7 @@ struct PixelQuad final { Vector3 barycentrics; f32x4 depth; Vector4 vertex_color; - Array, GPU::NUM_SAMPLERS> texture_coordinates; + Array, GPU::NUM_TEXTURE_UNITS> texture_coordinates; Vector4 out_color; f32x4 fog_depth; i32x4 mask;