diff options
author | Jelle Raaijmakers <jelle@gmta.nl> | 2022-09-05 00:40:27 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-09-11 22:37:07 +0100 |
commit | 00d46e5d77d7188d835627cd4c3d76152e4f7b3e (patch) | |
tree | 8402803e233cf896a714aa8fd1045d6256ba2cec | |
parent | 1540c56e6c82bfbdb1fd9b29c34c7ac1a399a1d3 (diff) | |
download | serenity-00d46e5d77d7188d835627cd4c3d76152e4f7b3e.zip |
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 :^)
22 files changed, 209 insertions, 153 deletions
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 Binary files differnew file mode 100644 index 0000000000..091d4b1192 --- /dev/null +++ b/Tests/LibGL/reference-images/0008_test_pop_matrix_regression.qoi diff --git a/Userland/Libraries/LibGL/ClipPlane.cpp b/Userland/Libraries/LibGL/ClipPlane.cpp index 52863abb53..2684d78575 100644 --- a/Userland/Libraries/LibGL/ClipPlane.cpp +++ b/Userland/Libraries/LibGL/ClipPlane.cpp @@ -22,7 +22,7 @@ void GLContext::gl_clip_plane(GLenum plane, GLdouble const* equation) auto plane_idx = static_cast<size_t>(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<GPU::Driver> driver, NonnullOwnPtr<GPU::Device> 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<size_t, 32> 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<FloatMatrix4x4> m_projection_matrix_stack; - Vector<FloatMatrix4x4> m_model_view_matrix_stack; - // FIXME: implement multi-texturing: the texture matrix stack should live inside a texture unit - Vector<FloatMatrix4x4> 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<FloatMatrix4x4> m_projection_matrix_stack { FloatMatrix4x4::identity() }; + Vector<FloatMatrix4x4> m_model_view_matrix_stack { FloatMatrix4x4::identity() }; Vector<FloatMatrix4x4>* 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<TextureUnit> 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<Array<TextureCoordinateGeneration, 4>> 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<float>(-2 / fn), static_cast<float>(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<float>(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<float>(x), static_cast<float>(y), static_cast<float>(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<float>(x), static_cast<float>(y), static_cast<float>(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 <AK/RefPtr.h> +#include <AK/Vector.h> #include <LibGL/Tex/Texture2D.h> +#include <LibGfx/Matrix4x4.h> 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<FloatMatrix4x4>& texture_matrix_stack() { return m_texture_matrix_stack; } + private: GLenum m_alpha_combinator { GL_MODULATE }; Array<GLenum, 3> 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<FloatMatrix4x4> 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_options(options); + m_rasterizer->set_texture_unit_configuration(i, texture_unit_configuration); + } } } 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 <LibGPU/RasterizerOptions.h> #include <LibGPU/SamplerConfig.h> #include <LibGPU/StencilConfiguration.h> -#include <LibGPU/TexCoordGenerationConfig.h> +#include <LibGPU/TextureUnitConfiguration.h> #include <LibGPU/Vertex.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Matrix3x3.h> @@ -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<Vertex>& vertices, Vector<size_t> const& enabled_texture_units) = 0; + virtual void draw_primitives(PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector<Vertex>& 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<FloatVector4> 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 <AK/Array.h> #include <LibGPU/Config.h> #include <LibGPU/Enums.h> -#include <LibGPU/TexCoordGenerationConfig.h> #include <LibGfx/Rect.h> #include <LibGfx/Vector4.h> @@ -53,8 +52,6 @@ struct RasterizerOptions { WindingOrder front_face { WindingOrder::CounterClockwise }; bool cull_back { true }; bool cull_front { false }; - Array<u8, NUM_SAMPLERS> texcoord_generation_enabled_coordinates {}; - Array<Array<TexCoordGenerationConfig, 4>, 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 <LibGPU/Config.h> #include <LibGPU/Enums.h> 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 <jelle@gmta.nl> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <LibGPU/Enums.h> -#include <LibGfx/Vector4.h> - -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 <jelle@gmta.nl> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <LibGPU/Enums.h> +#include <LibGfx/Matrix4x4.h> +#include <LibGfx/Vector4.h> + +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<FloatVector4, GPU::NUM_SAMPLERS> tex_coords; + Array<FloatVector4, GPU::NUM_TEXTURE_UNITS> 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<GPU::Vertex>& vertices, Vector<size_t> const& enabled_texture_units) +void Device::draw_primitives(GPU::PrimitiveType primitive_type, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector<GPU::Vertex>& 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<Vector4<f32x4>, GPU::NUM_SAMPLERS> texture_stage_texel; + Array<Vector4<f32x4>, 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 <LibGPU/RasterizerOptions.h> #include <LibGPU/SamplerConfig.h> #include <LibGPU/StencilConfiguration.h> -#include <LibGPU/TexCoordGenerationConfig.h> +#include <LibGPU/TextureUnitConfiguration.h> #include <LibGPU/Vertex.h> #include <LibGfx/Bitmap.h> #include <LibGfx/Matrix4x4.h> @@ -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<GPU::Vertex>& vertices, Vector<size_t> const& enabled_texture_units) override; + virtual void draw_primitives(GPU::PrimitiveType, FloatMatrix4x4 const& model_view_transform, FloatMatrix4x4 const& projection_transform, Vector<GPU::Vertex>& 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<FloatVector4> const&) override; virtual GPU::RasterPosition raster_position() const override { return m_raster_position; } @@ -107,14 +108,14 @@ private: Vector<Triangle> m_triangle_list; Vector<Triangle> m_processed_triangles; Vector<GPU::Vertex> m_clipped_vertices; - Array<Sampler, GPU::NUM_SAMPLERS> m_samplers; - Vector<size_t> m_enabled_texture_units; + Array<Sampler, GPU::NUM_TEXTURE_UNITS> m_samplers; AlphaBlendFactors m_alpha_blend_factors; Array<GPU::Light, NUM_LIGHTS> m_lights; Array<GPU::Material, 2u> m_materials; GPU::RasterPosition m_raster_position; Vector<FloatVector4> m_clip_planes; Array<GPU::StencilConfiguration, 2u> m_stencil_configuration; + Array<GPU::TextureUnitConfiguration, GPU::NUM_TEXTURE_UNITS> 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<f32x4> barycentrics; f32x4 depth; Vector4<f32x4> vertex_color; - Array<Vector4<f32x4>, GPU::NUM_SAMPLERS> texture_coordinates; + Array<Vector4<f32x4>, GPU::NUM_TEXTURE_UNITS> texture_coordinates; Vector4<f32x4> out_color; f32x4 fog_depth; i32x4 mask; |