From 96ac3d518a9882a2a040f319c47a567467c9266d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 17:02:17 -0300 Subject: gl_rasterizer: Remove dirty flags --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 70 +----------------------- 1 file changed, 2 insertions(+), 68 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e1965fb21..1d203fd08 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -117,11 +117,6 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; - if (!gpu.dirty.vertex_attrib_format) { - return state.draw.vertex_array; - } - gpu.dirty.vertex_attrib_format = false; - MICROPROFILE_SCOPE(OpenGL_VAO); auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); @@ -173,30 +168,18 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { } } - // Rebinding the VAO invalidates the vertex buffer bindings. - gpu.dirty.ResetVertexArrays(); - state.draw.vertex_array = vao_entry.handle; return vao_entry.handle; } void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { auto& gpu = system.GPU().Maxwell3D(); - if (!gpu.dirty.vertex_array_buffers) - return; - gpu.dirty.vertex_array_buffers = false; - const auto& regs = gpu.regs; MICROPROFILE_SCOPE(OpenGL_VB); // Upload all guest vertex arrays sequentially to our buffer for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { - if (!gpu.dirty.vertex_array[index]) - continue; - gpu.dirty.vertex_array[index] = false; - gpu.dirty.vertex_instance[index] = false; - const auto& vertex_array = regs.vertex_array[index]; if (!vertex_array.IsEnabled()) continue; @@ -224,19 +207,10 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { auto& gpu = system.GPU().Maxwell3D(); - - if (!gpu.dirty.vertex_instances) - return; - gpu.dirty.vertex_instances = false; - const auto& regs = gpu.regs; - // Upload all guest vertex arrays sequentially to our buffer - for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { - if (!gpu.dirty.vertex_instance[index]) - continue; - - gpu.dirty.vertex_instance[index] = false; + // Upload all guest vertex arrays sequentially to our buffer + for (u32 index = 0; index < 16; ++index) { if (regs.instanced_arrays.IsInstancingEnabled(index) && regs.vertex_array[index].divisor != 0) { // Enable vertex buffer instancing with the specified divisor. @@ -334,8 +308,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { } SyncClipEnabled(clip_distances); - - gpu.dirty.shaders = false; } std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { @@ -371,10 +343,6 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, void RasterizerOpenGL::ConfigureFramebuffers() { MICROPROFILE_SCOPE(OpenGL_Framebuffer); auto& gpu = system.GPU().Maxwell3D(); - if (!gpu.dirty.render_settings) { - return; - } - gpu.dirty.render_settings = false; texture_cache.GuardRenderTargets(true); @@ -453,7 +421,6 @@ void RasterizerOpenGL::Clear() { OpenGLState prev_state{OpenGLState::GetCurState()}; SCOPE_EXIT({ - prev_state.AllDirty(); prev_state.Apply(); }); @@ -528,7 +495,6 @@ void RasterizerOpenGL::Clear() { clear_state.EmulateViewportWithScissor(); } - clear_state.AllDirty(); clear_state.Apply(); if (use_color) { @@ -631,12 +597,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - if (invalidate) { - // As all cached buffers are invalidated, we need to recheck their state. - gpu.dirty.ResetVertexArrays(); - } - gpu.dirty.memory_general = false; - shader_program_manager->ApplyTo(state); state.Apply(); @@ -1084,14 +1044,8 @@ void RasterizerOpenGL::SyncDepthTestState() { void RasterizerOpenGL::SyncStencilTestState() { auto& maxwell3d = system.GPU().Maxwell3D(); - if (!maxwell3d.dirty.stencil_test) { - return; - } - maxwell3d.dirty.stencil_test = false; - const auto& regs = maxwell3d.regs; state.stencil.test_enabled = regs.stencil_enable != 0; - state.MarkDirtyStencilState(); if (!regs.stencil_enable) { return; @@ -1130,9 +1084,6 @@ void RasterizerOpenGL::SyncRasterizeEnable(OpenGLState& current_state) { void RasterizerOpenGL::SyncColorMask() { auto& maxwell3d = system.GPU().Maxwell3D(); - if (!maxwell3d.dirty.color_mask) { - return; - } const auto& regs = maxwell3d.regs; const std::size_t count = @@ -1145,9 +1096,6 @@ void RasterizerOpenGL::SyncColorMask() { dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE; dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE; } - - state.MarkDirtyColorMask(); - maxwell3d.dirty.color_mask = false; } void RasterizerOpenGL::SyncMultiSampleState() { @@ -1163,9 +1111,6 @@ void RasterizerOpenGL::SyncFragmentColorClampState() { void RasterizerOpenGL::SyncBlendState() { auto& maxwell3d = system.GPU().Maxwell3D(); - if (!maxwell3d.dirty.blend_state) { - return; - } const auto& regs = maxwell3d.regs; state.blend_color.red = regs.blend_color.r; @@ -1189,8 +1134,6 @@ void RasterizerOpenGL::SyncBlendState() { for (std::size_t i = 1; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { state.blend[i].enabled = false; } - maxwell3d.dirty.blend_state = false; - state.MarkDirtyBlendState(); return; } @@ -1207,9 +1150,6 @@ void RasterizerOpenGL::SyncBlendState() { blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a); blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a); } - - state.MarkDirtyBlendState(); - maxwell3d.dirty.blend_state = false; } void RasterizerOpenGL::SyncLogicOpState() { @@ -1264,9 +1204,6 @@ void RasterizerOpenGL::SyncPointState() { void RasterizerOpenGL::SyncPolygonOffset() { auto& maxwell3d = system.GPU().Maxwell3D(); - if (!maxwell3d.dirty.polygon_offset) { - return; - } const auto& regs = maxwell3d.regs; state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0; @@ -1277,9 +1214,6 @@ void RasterizerOpenGL::SyncPolygonOffset() { state.polygon_offset.units = regs.polygon_offset_units / 2.0f; state.polygon_offset.factor = regs.polygon_offset_factor; state.polygon_offset.clamp = regs.polygon_offset_clamp; - - state.MarkDirtyPolygonOffset(); - maxwell3d.dirty.polygon_offset = false; } void RasterizerOpenGL::SyncAlphaTest() { -- cgit v1.2.3 From 1698143a1d3af8d743c4204007995f7b26251233 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 00:28:46 -0300 Subject: gl_rasterizer: Add OpenGL enable/disable helper --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1d203fd08..1fc05e041 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -88,6 +88,10 @@ std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer, return buffer.size; } +void oglEnable(GLenum cap, bool state) { + (state ? glEnable : glDisable)(cap); +} + } // Anonymous namespace RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, -- cgit v1.2.3 From b95f064b51cf5638e356f455a834809a76778c89 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:27:43 -0300 Subject: gl_rasterizer: Add oglEnablei helper --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1fc05e041..7cd522da0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -92,6 +92,10 @@ void oglEnable(GLenum cap, bool state) { (state ? glEnable : glDisable)(cap); } +void oglEnablei(GLenum cap, bool state, GLuint index) { + (state ? glEnablei : glDisablei)(cap, index); +} + } // Anonymous namespace RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, -- cgit v1.2.3 From d2d55542965e969a73ddd400e8290b5f4f4101a2 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 19:30:05 -0300 Subject: gl_state: Remove point size tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7cd522da0..a0b0274fb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -428,9 +428,7 @@ void RasterizerOpenGL::Clear() { bool use_stencil{}; OpenGLState prev_state{OpenGLState::GetCurState()}; - SCOPE_EXIT({ - prev_state.Apply(); - }); + SCOPE_EXIT({ prev_state.Apply(); }); OpenGLState clear_state{OpenGLState::GetCurState()}; clear_state.SetDefaultViewports(); @@ -1205,9 +1203,9 @@ void RasterizerOpenGL::SyncPointState() { const auto& regs = system.GPU().Maxwell3D().regs; // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid // in OpenGL). - state.point.program_control = regs.vp_point_size.enable != 0; - state.point.sprite = regs.point_sprite_enable != 0; - state.point.size = std::max(1.0f, regs.point_size); + oglEnable(GL_PROGRAM_POINT_SIZE, regs.vp_point_size.enable); + oglEnable(GL_POINT_SPRITE, regs.point_sprite_enable); + glPointSize(std::max(1.0f, regs.point_size)); } void RasterizerOpenGL::SyncPolygonOffset() { -- cgit v1.2.3 From 925521da5fbc1096f56933eba1683b60c6c19b20 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 19:46:04 -0300 Subject: gl_state: Remove front face tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a0b0274fb..e9e9f9794 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1025,7 +1025,7 @@ void RasterizerOpenGL::SyncCullMode() { state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face); } - state.cull.front_face = MaxwellToGL::FrontFace(regs.cull.front_face); + glFrontFace(MaxwellToGL::FrontFace(regs.cull.front_face)); } void RasterizerOpenGL::SyncPrimitiveRestart() { -- cgit v1.2.3 From c8f5f54a44e9873134fab74eef97e875b9e6c565 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 19:56:17 -0300 Subject: gl_state: Remove cull mode tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e9e9f9794..a080c3e81 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1020,10 +1020,8 @@ void RasterizerOpenGL::SyncClipCoef() { void RasterizerOpenGL::SyncCullMode() { const auto& regs = system.GPU().Maxwell3D().regs; - state.cull.enabled = regs.cull.enabled != 0; - if (state.cull.enabled) { - state.cull.mode = MaxwellToGL::CullFace(regs.cull.cull_face); - } + oglEnable(GL_CULL_FACE, regs.cull.enabled); + glCullFace(MaxwellToGL::CullFace(regs.cull.cull_face)); glFrontFace(MaxwellToGL::FrontFace(regs.cull.front_face)); } -- cgit v1.2.3 From f646321dd060572f94c2d4f2f3aa2c5307e21b14 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 20:03:40 -0300 Subject: gl_state: Remove alpha test tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a080c3e81..d1034c2a2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1225,12 +1225,10 @@ void RasterizerOpenGL::SyncAlphaTest() { UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1, "Alpha Testing is enabled with more than one rendertarget"); - state.alpha_test.enabled = regs.alpha_test_enabled; - if (!state.alpha_test.enabled) { - return; + oglEnable(GL_ALPHA_TEST, regs.alpha_test_enabled); + if (regs.alpha_test_enabled) { + glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref); } - state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func); - state.alpha_test.ref = regs.alpha_test_ref; } } // namespace OpenGL -- cgit v1.2.3 From a0321b984fc03610ad7b20d2ee345fd978103b19 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 00:25:53 -0300 Subject: gl_state: Remove polygon offset tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d1034c2a2..744892618 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1210,14 +1210,13 @@ void RasterizerOpenGL::SyncPolygonOffset() { auto& maxwell3d = system.GPU().Maxwell3D(); const auto& regs = maxwell3d.regs; - state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0; - state.polygon_offset.line_enable = regs.polygon_offset_line_enable != 0; - state.polygon_offset.point_enable = regs.polygon_offset_point_enable != 0; + oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); + oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); + oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); // Hardware divides polygon offset units by two - state.polygon_offset.units = regs.polygon_offset_units / 2.0f; - state.polygon_offset.factor = regs.polygon_offset_factor; - state.polygon_offset.clamp = regs.polygon_offset_clamp; + glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f, + regs.polygon_offset_clamp); } void RasterizerOpenGL::SyncAlphaTest() { -- cgit v1.2.3 From 915d73f3b8871fc31b9b6571d645ced6f766bc43 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 20:13:43 -0300 Subject: gl_state: Remove blend color tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 744892618..5c5273b5d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1117,10 +1117,7 @@ void RasterizerOpenGL::SyncBlendState() { auto& maxwell3d = system.GPU().Maxwell3D(); const auto& regs = maxwell3d.regs; - state.blend_color.red = regs.blend_color.r; - state.blend_color.green = regs.blend_color.g; - state.blend_color.blue = regs.blend_color.b; - state.blend_color.alpha = regs.blend_color.a; + glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a); state.independant_blend.enabled = regs.independent_blend_enable; if (!state.independant_blend.enabled) { -- cgit v1.2.3 From 42708c762edee4f5bf2fa1d15a4ab764525fb044 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 20:21:53 -0300 Subject: gl_state: Remove logic op tracker --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5c5273b5d..9d4b351fb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1156,15 +1156,10 @@ void RasterizerOpenGL::SyncBlendState() { void RasterizerOpenGL::SyncLogicOpState() { const auto& regs = system.GPU().Maxwell3D().regs; - state.logic_op.enabled = regs.logic_op.enable != 0; - - if (!state.logic_op.enabled) - return; - - ASSERT_MSG(regs.blend.enable[0] == 0, - "Blending and logic op can't be enabled at the same time."); - - state.logic_op.operation = MaxwellToGL::LogicOp(regs.logic_op.operation); + oglEnable(GL_COLOR_LOGIC_OP, regs.logic_op.enable); + if (regs.logic_op.enable) { + glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); + } } void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) { -- cgit v1.2.3 From 0f343d32c41efc411fddb1a66a9f11fb68eebf06 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 21:00:38 -0300 Subject: gl_state: Remove primitive restart tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9d4b351fb..975cd2f12 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1029,8 +1029,8 @@ void RasterizerOpenGL::SyncCullMode() { void RasterizerOpenGL::SyncPrimitiveRestart() { const auto& regs = system.GPU().Maxwell3D().regs; - state.primitive_restart.enabled = regs.primitive_restart.enabled; - state.primitive_restart.index = regs.primitive_restart.index; + oglEnable(GL_PRIMITIVE_RESTART, regs.primitive_restart.enabled); + glPrimitiveRestartIndex(regs.primitive_restart.index); } void RasterizerOpenGL::SyncDepthTestState() { -- cgit v1.2.3 From e1a16a52fa14835efe6ba9b7418be419cdc4e5d5 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 21:52:39 -0300 Subject: gl_state: Remove depth tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 975cd2f12..6bb6f9f47 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -446,12 +446,8 @@ void RasterizerOpenGL::Clear() { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); use_depth = true; - // Always enable the depth write when clearing the depth buffer. The depth write mask is - // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to - // true. - clear_state.depth.test_enabled = true; - clear_state.depth.test_func = GL_ALWAYS; - clear_state.depth.write_mask = GL_TRUE; + // TODO: Signal state tracker about these changes + glDepthMask(GL_TRUE); } if (regs.clear_buffers.S) { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!"); @@ -1036,14 +1032,12 @@ void RasterizerOpenGL::SyncPrimitiveRestart() { void RasterizerOpenGL::SyncDepthTestState() { const auto& regs = system.GPU().Maxwell3D().regs; - state.depth.test_enabled = regs.depth_test_enable != 0; - state.depth.write_mask = regs.depth_write_enabled ? GL_TRUE : GL_FALSE; + glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); - if (!state.depth.test_enabled) { - return; + oglEnable(GL_DEPTH_TEST, regs.depth_test_enable); + if (regs.depth_test_enable) { + glDepthFunc(MaxwellToGL::ComparisonOp(regs.depth_test_func)); } - - state.depth.test_func = MaxwellToGL::ComparisonOp(regs.depth_test_func); } void RasterizerOpenGL::SyncStencilTestState() { -- cgit v1.2.3 From 2a662fea363027817a73a62a5e4a9d0066fb43ee Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 21:57:10 -0300 Subject: gl_state: Remove depth clamp tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6bb6f9f47..acdae849c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -977,8 +977,6 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { viewport.depth_range_far = src.depth_range_far; viewport.depth_range_near = src.depth_range_near; } - state.depth_clamp.far_plane = regs.view_volume_clip_control.depth_clamp_far != 0; - state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; bool flip_y = false; if (regs.viewport_transform[0].scale_y < 0.0) { @@ -994,6 +992,16 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { : GL_NEGATIVE_ONE_TO_ONE; } +void RasterizerOpenGL::SyncDepthClamp() { + const auto& regs = system.GPU().Maxwell3D().regs; + const auto& state = regs.view_volume_clip_control; + + UNIMPLEMENTED_IF_MSG(state.depth_clamp_far != state.depth_clamp_near, + "Unimplemented Depth clamp separation!"); + + oglEnable(GL_DEPTH_CLAMP, state.depth_clamp_far || state.depth_clamp_near); +} + void RasterizerOpenGL::SyncClipEnabled( const std::array& clip_mask) { -- cgit v1.2.3 From d5ab0358b64266be928a15265c4071744eed061e Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 00:16:52 -0300 Subject: gl_state: Remove VAO cache and tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 100 +++++++++-------------- 1 file changed, 37 insertions(+), 63 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index acdae849c..9658d379c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind state.draw.shader_program = 0; state.Apply(); - LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here"); CheckExtensions(); } @@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() { } } -GLuint RasterizerOpenGL::SetupVertexFormat() { +void RasterizerOpenGL::SetupVertexFormat() { auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; MICROPROFILE_SCOPE(OpenGL_VAO); - auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); - auto& vao_entry = iter->second; - - if (is_cache_miss) { - vao_entry.Create(); - const GLuint vao = vao_entry.handle; - - // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob - // that fails to properly create the vertex array if it's not bound even after creating it - // with glCreateVertexArrays - state.draw.vertex_array = vao; - state.ApplyVertexArrayState(); - - // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. - // Enables the first 16 vertex attributes always, as we don't know which ones are actually - // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16 - // for now to avoid OpenGL errors. - // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't - // assume every shader uses them all. - for (u32 index = 0; index < 16; ++index) { - const auto& attrib = regs.vertex_attrib_format[index]; - - // Ignore invalid attributes. - if (!attrib.IsValid()) - continue; - - const auto& buffer = regs.vertex_array[attrib.buffer]; - LOG_TRACE(Render_OpenGL, - "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", - index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), - attrib.offset.Value(), attrib.IsNormalized()); - - ASSERT(buffer.IsEnabled()); - - glEnableVertexArrayAttrib(vao, index); - if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || - attrib.type == - Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { - glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(), - MaxwellToGL::VertexType(attrib), attrib.offset); - } else { - glVertexArrayAttribFormat( - vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); - } - glVertexArrayAttribBinding(vao, index, attrib.buffer); + // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. Enables + // the first 16 vertex attributes always, as we don't know which ones are actually used until + // shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now to + // avoid OpenGL errors. + // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't + // assume every shader uses them all. + for (u32 index = 0; index < 16; ++index) { + const auto& attrib = regs.vertex_attrib_format[index]; + + // Ignore invalid attributes. + if (!attrib.IsValid()) { + glDisableVertexAttribArray(index); + continue; } - } + glEnableVertexAttribArray(index); - state.draw.vertex_array = vao_entry.handle; - return vao_entry.handle; + if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || + attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { + glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.offset); + } else { + glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); + } + glVertexAttribBinding(index, attrib.buffer); + } } -void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { +void RasterizerOpenGL::SetupVertexBuffer() { auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; @@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { // Upload all guest vertex arrays sequentially to our buffer for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { const auto& vertex_array = regs.vertex_array[index]; - if (!vertex_array.IsEnabled()) + if (!vertex_array.IsEnabled()) { continue; + } const GPUVAddr start = vertex_array.StartAddress(); const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); @@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { // Enable vertex buffer instancing with the specified divisor. - glVertexArrayBindingDivisor(vao, index, vertex_array.divisor); + glVertexBindingDivisor(index, vertex_array.divisor); } else { // Disable the vertex buffer instancing. - glVertexArrayBindingDivisor(vao, index, 0); + glVertexBindingDivisor(index, 0); } } } -void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { +void RasterizerOpenGL::SetupVertexInstances() { auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; @@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { if (regs.instanced_arrays.IsInstancingEnabled(index) && regs.vertex_array[index].divisor != 0) { // Enable vertex buffer instancing with the specified divisor. - glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor); + glVertexBindingDivisor(index, regs.vertex_array[index].divisor); } else { // Disable the vertex buffer instancing. - glVertexArrayBindingDivisor(vao, index, 0); + glVertexBindingDivisor(index, 0); } } } @@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { buffer_cache.Map(buffer_size); // Prepare vertex array format. - const GLuint vao = SetupVertexFormat(); - vertex_array_pushbuffer.Setup(vao); + SetupVertexFormat(); + vertex_array_pushbuffer.Setup(); // Upload vertex and index data. - SetupVertexBuffer(vao); - SetupVertexInstances(vao); - + SetupVertexBuffer(); + SetupVertexInstances(); GLintptr index_buffer_offset; if (is_indexed) { index_buffer_offset = SetupIndexBuffer(); -- cgit v1.2.3 From 04d11341911a0c9ed3558fc6084d305ae262399a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:01:41 -0300 Subject: gl_state: Remove framebuffer sRGB tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 9658d379c..f5aa84a16 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -332,7 +332,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() { View depth_surface = texture_cache.GetDepthBufferSurface(true); const auto& regs = gpu.regs; - state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0; UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); // Bind the framebuffer surfaces @@ -455,6 +454,9 @@ void RasterizerOpenGL::Clear() { } } + // TODO: Signal state tracker about these changes + SyncFramebufferSRGB(); + if (!use_color && !use_depth && !use_stencil) { // No color surface nor depth/stencil surface are enabled return; @@ -511,6 +513,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { SyncPointState(); SyncPolygonOffset(); SyncAlphaTest(); + SyncFramebufferSRGB(); buffer_cache.Acquire(); @@ -1198,4 +1201,9 @@ void RasterizerOpenGL::SyncAlphaTest() { } } +void RasterizerOpenGL::SyncFramebufferSRGB() { + const auto& regs = system.GPU().Maxwell3D().regs; + oglEnable(GL_FRAMEBUFFER_SRGB, regs.framebuffer_srgb); +} + } // namespace OpenGL -- cgit v1.2.3 From f92236976b870cfb8be5a9efa03e4fb171d0ce00 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:04:36 -0300 Subject: gl_state: Remove multisample tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f5aa84a16..dc2d60156 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1083,8 +1083,8 @@ void RasterizerOpenGL::SyncColorMask() { void RasterizerOpenGL::SyncMultiSampleState() { const auto& regs = system.GPU().Maxwell3D().regs; - state.multisample_control.alpha_to_coverage = regs.multisample_control.alpha_to_coverage != 0; - state.multisample_control.alpha_to_one = regs.multisample_control.alpha_to_one != 0; + oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); + oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); } void RasterizerOpenGL::SyncFragmentColorClampState() { -- cgit v1.2.3 From 2392b548bee87553b39f50c1159640b0dabc4b13 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:07:34 -0300 Subject: gl_state: Remove clamp framebuffer color tracking This commit doesn't reset it for screen draws because clamping doesn't change anything there. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index dc2d60156..d7971f86f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -415,6 +415,11 @@ void RasterizerOpenGL::Clear() { clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE; clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE; + + // TODO: Signal state tracker about these changes + SyncFramebufferSRGB(); + // TODO(Rodrigo): Determine if clamping is used on clears + SyncFragmentColorClampState(); } if (regs.clear_buffers.Z) { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); @@ -454,9 +459,6 @@ void RasterizerOpenGL::Clear() { } } - // TODO: Signal state tracker about these changes - SyncFramebufferSRGB(); - if (!use_color && !use_depth && !use_stencil) { // No color surface nor depth/stencil surface are enabled return; @@ -1089,7 +1091,7 @@ void RasterizerOpenGL::SyncMultiSampleState() { void RasterizerOpenGL::SyncFragmentColorClampState() { const auto& regs = system.GPU().Maxwell3D().regs; - state.fragment_color_clamp.enabled = regs.frag_color_clamp != 0; + glClampColor(GL_CLAMP_FRAGMENT_COLOR, regs.frag_color_clamp ? GL_TRUE : GL_FALSE); } void RasterizerOpenGL::SyncBlendState() { -- cgit v1.2.3 From 0914c70b7f9d68e71779fa32c474ed896b225704 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:19:15 -0300 Subject: gl_state: Remove color mask tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d7971f86f..d0c811929 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -411,12 +411,10 @@ void RasterizerOpenGL::Clear() { use_color = true; } if (use_color) { - clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE; - clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE; - clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE; - clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE; - // TODO: Signal state tracker about these changes + glColorMaski(0, regs.clear_buffers.R, regs.clear_buffers.G, regs.clear_buffers.B, + regs.clear_buffers.A); + SyncFramebufferSRGB(); // TODO(Rodrigo): Determine if clamping is used on clears SyncFragmentColorClampState(); @@ -1071,15 +1069,14 @@ void RasterizerOpenGL::SyncColorMask() { auto& maxwell3d = system.GPU().Maxwell3D(); const auto& regs = maxwell3d.regs; - const std::size_t count = - regs.independent_blend_enable ? Tegra::Engines::Maxwell3D::Regs::NumRenderTargets : 1; - for (std::size_t i = 0; i < count; i++) { - const auto& source = regs.color_mask[regs.color_mask_common ? 0 : i]; - auto& dest = state.color_mask[i]; - dest.red_enabled = (source.R == 0) ? GL_FALSE : GL_TRUE; - dest.green_enabled = (source.G == 0) ? GL_FALSE : GL_TRUE; - dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE; - dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE; + if (regs.color_mask_common) { + auto& mask = regs.color_mask[0]; + glColorMask(mask.R, mask.B, mask.G, mask.A); + } else { + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { + const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : i]; + glColorMaski(static_cast(i), mask.R, mask.G, mask.B, mask.A); + } } } -- cgit v1.2.3 From 7c16b3551b5294d86a7dc8e0721c081bd88547ed Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:28:17 -0300 Subject: gl_state: Remove scissor test tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 32 +++++++----------------- 1 file changed, 9 insertions(+), 23 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d0c811929..3ccedcf55 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -467,12 +467,10 @@ void RasterizerOpenGL::Clear() { SyncViewport(clear_state); SyncRasterizeEnable(clear_state); if (regs.clear_flags.scissor) { - SyncScissorTest(clear_state); + SyncScissorTest(); } - if (regs.clear_flags.viewport) { - clear_state.EmulateViewportWithScissor(); - } + UNIMPLEMENTED_IF(regs.clear_flags.viewport); clear_state.Apply(); @@ -508,7 +506,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { SyncLogicOpState(); SyncCullMode(); SyncPrimitiveRestart(); - SyncScissorTest(state); + SyncScissorTest(); SyncTransformFeedback(); SyncPointState(); SyncPolygonOffset(); @@ -1140,25 +1138,13 @@ void RasterizerOpenGL::SyncLogicOpState() { } } -void RasterizerOpenGL::SyncScissorTest(OpenGLState& current_state) { +void RasterizerOpenGL::SyncScissorTest() { const auto& regs = system.GPU().Maxwell3D().regs; - const bool geometry_shaders_enabled = - regs.IsShaderConfigEnabled(static_cast(Maxwell::ShaderProgram::Geometry)); - const std::size_t viewport_count = - geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1; - for (std::size_t i = 0; i < viewport_count; i++) { - const auto& src = regs.scissor_test[i]; - auto& dst = current_state.viewports[i].scissor; - dst.enabled = (src.enable != 0); - if (dst.enabled == 0) { - return; - } - const u32 width = src.max_x - src.min_x; - const u32 height = src.max_y - src.min_y; - dst.x = src.min_x; - dst.y = src.min_y; - dst.width = width; - dst.height = height; + for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { + const auto& src = regs.scissor_test[index]; + oglEnablei(GL_SCISSOR_TEST, src.enable, static_cast(index)); + glScissorIndexed(static_cast(index), src.min_x, src.min_y, src.max_x - src.min_x, + src.max_y - src.min_y); } } -- cgit v1.2.3 From d3e433a38048c5d32c0929446008586e975ccd0e Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 01:50:38 -0300 Subject: gl_state: Remove viewport and depth range tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3ccedcf55..63295761a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -360,7 +360,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() { texture_cache.GuardRenderTargets(false); state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key); - SyncViewport(state); } void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, @@ -405,7 +404,6 @@ void RasterizerOpenGL::Clear() { SCOPE_EXIT({ prev_state.Apply(); }); OpenGLState clear_state{OpenGLState::GetCurState()}; - clear_state.SetDefaultViewports(); if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || regs.clear_buffers.A) { use_color = true; @@ -464,7 +462,6 @@ void RasterizerOpenGL::Clear() { ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); - SyncViewport(clear_state); SyncRasterizeEnable(clear_state); if (regs.clear_flags.scissor) { SyncScissorTest(); @@ -496,6 +493,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { query_cache.UpdateCounters(); + SyncViewport(); SyncRasterizeEnable(state); SyncColorMask(); SyncFragmentColorClampState(); @@ -935,22 +933,14 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t state.images[binding] = view->GetTexture(); } -void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { +void RasterizerOpenGL::SyncViewport() { const auto& regs = system.GPU().Maxwell3D().regs; - const bool geometry_shaders_enabled = - regs.IsShaderConfigEnabled(static_cast(Maxwell::ShaderProgram::Geometry)); - const std::size_t viewport_count = - geometry_shaders_enabled ? Tegra::Engines::Maxwell3D::Regs::NumViewports : 1; - for (std::size_t i = 0; i < viewport_count; i++) { - auto& viewport = current_state.viewports[i]; + for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { const auto& src = regs.viewports[i]; - const Common::Rectangle viewport_rect{regs.viewport_transform[i].GetRect()}; - viewport.x = viewport_rect.left; - viewport.y = viewport_rect.bottom; - viewport.width = viewport_rect.GetWidth(); - viewport.height = viewport_rect.GetHeight(); - viewport.depth_range_far = src.depth_range_far; - viewport.depth_range_near = src.depth_range_near; + const Common::Rectangle rect{regs.viewport_transform[i].GetRect()}; + glViewportIndexedf(static_cast(i), rect.left, rect.bottom, rect.GetWidth(), + rect.GetHeight()); + glDepthRangef(src.depth_range_near, src.depth_range_far); } bool flip_y = false; -- cgit v1.2.3 From e8125af8dd8efac3f7171e234b5aee6edfadc626 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 02:11:01 -0300 Subject: gl_state: Remove rasterizer disable tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 63295761a..cb3c81398 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -462,7 +462,7 @@ void RasterizerOpenGL::Clear() { ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); - SyncRasterizeEnable(clear_state); + SyncRasterizeEnable(); if (regs.clear_flags.scissor) { SyncScissorTest(); } @@ -494,7 +494,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { query_cache.UpdateCounters(); SyncViewport(); - SyncRasterizeEnable(state); + SyncRasterizeEnable(); SyncColorMask(); SyncFragmentColorClampState(); SyncMultiSampleState(); @@ -1048,9 +1048,9 @@ void RasterizerOpenGL::SyncStencilTestState() { } } -void RasterizerOpenGL::SyncRasterizeEnable(OpenGLState& current_state) { +void RasterizerOpenGL::SyncRasterizeEnable() { const auto& regs = system.GPU().Maxwell3D().regs; - current_state.rasterizer_discard = regs.rasterize_enable == 0; + oglEnable(GL_RASTERIZER_DISCARD, regs.rasterize_enable == 0); } void RasterizerOpenGL::SyncColorMask() { -- cgit v1.2.3 From 1eee891f6e73423a9aa6147f980be5aea799e7ce Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 02:20:08 -0300 Subject: gl_state: Remove clip distances tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index cb3c81398..f4efddcc0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -969,16 +969,10 @@ void RasterizerOpenGL::SyncDepthClamp() { void RasterizerOpenGL::SyncClipEnabled( const std::array& clip_mask) { - const auto& regs = system.GPU().Maxwell3D().regs; - const std::array reg_state{ - regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0, - regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0, - regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0, - regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0}; - for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) { - state.clip_distance[i] = reg_state[i] && clip_mask[i]; + oglEnable(static_cast(GL_CLIP_DISTANCE0 + i), + clip_mask[i] && ((regs.clip_distance_enabled >> i) & 1)); } } -- cgit v1.2.3 From 07a954e67f786fad4b6324837489af705788a6b9 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 02:27:26 -0300 Subject: gl_state: Remove clip control tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f4efddcc0..8f9bb4c93 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -467,6 +467,9 @@ void RasterizerOpenGL::Clear() { SyncScissorTest(); } + // TODO: Signal state tracker about these changes + glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); + UNIMPLEMENTED_IF(regs.clear_flags.viewport); clear_state.Apply(); @@ -950,11 +953,9 @@ void RasterizerOpenGL::SyncViewport() { if (regs.screen_y_control.y_negate != 0) { flip_y = !flip_y; } - state.clip_control.origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT; - state.clip_control.depth_mode = - regs.depth_mode == Tegra::Engines::Maxwell3D::Regs::DepthMode::ZeroToOne - ? GL_ZERO_TO_ONE - : GL_NEGATIVE_ONE_TO_ONE; + glClipControl(flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT, + regs.depth_mode == Maxwell::DepthMode::ZeroToOne ? GL_ZERO_TO_ONE + : GL_NEGATIVE_ONE_TO_ONE); } void RasterizerOpenGL::SyncDepthClamp() { -- cgit v1.2.3 From 7d9a5e9e30b9e197e5fe3bfd10116e7ea078494a Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 03:34:29 -0300 Subject: gl_state: Remove stencil test tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 65 +++++++----------------- 1 file changed, 17 insertions(+), 48 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8f9bb4c93..573f14cab 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -427,32 +427,6 @@ void RasterizerOpenGL::Clear() { if (regs.clear_buffers.S) { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!"); use_stencil = true; - clear_state.stencil.test_enabled = true; - - if (regs.clear_flags.stencil) { - // Stencil affects the clear so fill it with the used masks - clear_state.stencil.front.test_func = GL_ALWAYS; - clear_state.stencil.front.test_mask = regs.stencil_front_func_mask; - clear_state.stencil.front.action_stencil_fail = GL_KEEP; - clear_state.stencil.front.action_depth_fail = GL_KEEP; - clear_state.stencil.front.action_depth_pass = GL_KEEP; - clear_state.stencil.front.write_mask = regs.stencil_front_mask; - if (regs.stencil_two_side_enable) { - clear_state.stencil.back.test_func = GL_ALWAYS; - clear_state.stencil.back.test_mask = regs.stencil_back_func_mask; - clear_state.stencil.back.action_stencil_fail = GL_KEEP; - clear_state.stencil.back.action_depth_fail = GL_KEEP; - clear_state.stencil.back.action_depth_pass = GL_KEEP; - clear_state.stencil.back.write_mask = regs.stencil_back_mask; - } else { - clear_state.stencil.back.test_func = GL_ALWAYS; - clear_state.stencil.back.test_mask = 0xFFFFFFFF; - clear_state.stencil.back.write_mask = 0xFFFFFFFF; - clear_state.stencil.back.action_stencil_fail = GL_KEEP; - clear_state.stencil.back.action_depth_fail = GL_KEEP; - clear_state.stencil.back.action_depth_pass = GL_KEEP; - } - } } if (!use_color && !use_depth && !use_stencil) { @@ -1011,35 +985,30 @@ void RasterizerOpenGL::SyncDepthTestState() { void RasterizerOpenGL::SyncStencilTestState() { auto& maxwell3d = system.GPU().Maxwell3D(); const auto& regs = maxwell3d.regs; - state.stencil.test_enabled = regs.stencil_enable != 0; + oglEnable(GL_STENCIL_TEST, regs.stencil_enable); if (!regs.stencil_enable) { return; } - state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func); - state.stencil.front.test_ref = regs.stencil_front_func_ref; - state.stencil.front.test_mask = regs.stencil_front_func_mask; - state.stencil.front.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_fail); - state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail); - state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass); - state.stencil.front.write_mask = regs.stencil_front_mask; + glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), + regs.stencil_front_func_ref, regs.stencil_front_func_mask); + glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), + MaxwellToGL::StencilOp(regs.stencil_front_op_zfail), + MaxwellToGL::StencilOp(regs.stencil_front_op_zpass)); + glStencilMaskSeparate(GL_FRONT, regs.stencil_front_mask); + if (regs.stencil_two_side_enable) { - state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func); - state.stencil.back.test_ref = regs.stencil_back_func_ref; - state.stencil.back.test_mask = regs.stencil_back_func_mask; - state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail); - state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail); - state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass); - state.stencil.back.write_mask = regs.stencil_back_mask; + glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_func_func), + regs.stencil_back_func_ref, regs.stencil_back_func_mask); + glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op_fail), + MaxwellToGL::StencilOp(regs.stencil_back_op_zfail), + MaxwellToGL::StencilOp(regs.stencil_back_op_zpass)); + glStencilMaskSeparate(GL_BACK, regs.stencil_back_mask); } else { - state.stencil.back.test_func = GL_ALWAYS; - state.stencil.back.test_ref = 0; - state.stencil.back.test_mask = 0xFFFFFFFF; - state.stencil.back.write_mask = 0xFFFFFFFF; - state.stencil.back.action_stencil_fail = GL_KEEP; - state.stencil.back.action_depth_fail = GL_KEEP; - state.stencil.back.action_depth_pass = GL_KEEP; + glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF); + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP); + glStencilMaskSeparate(GL_BACK, 0xFFFFFFFF); } } -- cgit v1.2.3 From 1bc0da3dea5a8502e63f5c123151328ccb2ba8d6 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 03:51:50 -0300 Subject: gl_state: Remove blend state tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 49 ++++++++++++------------ 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 573f14cab..f916f348f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -442,7 +442,9 @@ void RasterizerOpenGL::Clear() { } // TODO: Signal state tracker about these changes + // TODO(Rodrigo): Find out if these changes affect clearing glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); + glDisablei(GL_BLEND, 0); UNIMPLEMENTED_IF(regs.clear_flags.viewport); @@ -1049,37 +1051,34 @@ void RasterizerOpenGL::SyncBlendState() { glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a); - state.independant_blend.enabled = regs.independent_blend_enable; - if (!state.independant_blend.enabled) { - auto& blend = state.blend[0]; + if (!regs.independent_blend_enable) { const auto& src = regs.blend; - blend.enabled = src.enable[0] != 0; - if (blend.enabled) { - blend.rgb_equation = MaxwellToGL::BlendEquation(src.equation_rgb); - blend.src_rgb_func = MaxwellToGL::BlendFunc(src.factor_source_rgb); - blend.dst_rgb_func = MaxwellToGL::BlendFunc(src.factor_dest_rgb); - blend.a_equation = MaxwellToGL::BlendEquation(src.equation_a); - blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a); - blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a); - } - for (std::size_t i = 1; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { - state.blend[i].enabled = false; + oglEnable(GL_BLEND, src.enable[0]); + if (!src.enable[0]) { + return; } + glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb), + MaxwellToGL::BlendFunc(src.factor_dest_rgb), + MaxwellToGL::BlendFunc(src.factor_source_a), + MaxwellToGL::BlendFunc(src.factor_dest_a)); + glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb), + MaxwellToGL::BlendEquation(src.equation_a)); return; } - for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { - auto& blend = state.blend[i]; - const auto& src = regs.independent_blend[i]; - blend.enabled = regs.blend.enable[i] != 0; - if (!blend.enabled) + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { + oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast(i)); + if (!regs.blend.enable[i]) { continue; - blend.rgb_equation = MaxwellToGL::BlendEquation(src.equation_rgb); - blend.src_rgb_func = MaxwellToGL::BlendFunc(src.factor_source_rgb); - blend.dst_rgb_func = MaxwellToGL::BlendFunc(src.factor_dest_rgb); - blend.a_equation = MaxwellToGL::BlendEquation(src.equation_a); - blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a); - blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a); + } + const auto& src = regs.independent_blend[i]; + glBlendFuncSeparatei(static_cast(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), + MaxwellToGL::BlendFunc(src.factor_dest_rgb), + MaxwellToGL::BlendFunc(src.factor_source_a), + MaxwellToGL::BlendFunc(src.factor_dest_a)); + glBlendEquationSeparatei(static_cast(i), + MaxwellToGL::BlendEquation(src.equation_rgb), + MaxwellToGL::BlendEquation(src.equation_a)); } } -- cgit v1.2.3 From 9677db03da37a61248c2ced49a9a5e53c872cc63 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 04:01:11 -0300 Subject: gl_state: Remove texture and sampler tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f916f348f..669a7c335 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -633,7 +633,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - state.ApplyTextures(); state.ApplyImages(); state.ApplyShaderProgram(); state.ApplyProgramPipeline(); @@ -861,20 +860,20 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu const auto view = texture_cache.GetTextureSurface(texture.tic, entry); if (!view) { // Can occur when texture addr is null or its memory is unmapped/invalid - state.samplers[binding] = 0; - state.textures[binding] = 0; + glBindSampler(binding, 0); + glBindTextureUnit(binding, 0); return; } - state.textures[binding] = view->GetTexture(); + glBindTextureUnit(binding, view->GetTexture()); if (view->GetSurfaceParams().IsBuffer()) { return; } - state.samplers[binding] = sampler_cache.GetSampler(texture.tsc); - // Apply swizzle to textures that are not buffers. view->ApplySwizzle(texture.tic.x_source, texture.tic.y_source, texture.tic.z_source, texture.tic.w_source); + + glBindSampler(binding, sampler_cache.GetSampler(texture.tsc)); } void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) { -- cgit v1.2.3 From 17a7fa751b34ae67c600bd741969dc1bde40fbf3 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 04:17:02 -0300 Subject: gl_state: Remove image tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 669a7c335..1f94f759d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -633,7 +633,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - state.ApplyImages(); state.ApplyShaderProgram(); state.ApplyProgramPipeline(); @@ -899,7 +898,7 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t const GLShader::ImageEntry& entry) { const auto view = texture_cache.GetImageSurface(tic, entry); if (!view) { - state.images[binding] = 0; + glBindImageTexture(binding, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); return; } if (!tic.IsBuffer()) { @@ -908,7 +907,8 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t if (entry.IsWritten()) { view->MarkAsModified(texture_cache.Tick()); } - state.images[binding] = view->GetTexture(); + glBindImageTexture(binding, view->GetTexture(), 0, GL_TRUE, 0, GL_READ_WRITE, + view->GetFormat()); } void RasterizerOpenGL::SyncViewport() { -- cgit v1.2.3 From 5ccb07933ac0f33d0ecb909d29bf65ee4ab70d8e Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 05:01:43 -0300 Subject: gl_state: Remove framebuffer tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 1f94f759d..b826146fb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -359,7 +359,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() { texture_cache.GuardRenderTargets(false); - state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key)); } void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, @@ -384,8 +384,7 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, boo key.colors[0] = color_surface; key.zeta = depth_surface; - current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key); - current_state.ApplyFramebufferState(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key)); } void RasterizerOpenGL::Clear() { -- cgit v1.2.3 From 1c4bf9cbfa4e4303890f73be11eb1dee88d070fe Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 16:04:41 -0300 Subject: gl_state: Remove program tracking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 ++++++++++-------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b826146fb..84c4d110c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -99,14 +99,11 @@ void oglEnablei(GLenum cap, bool state, GLuint index) { } // Anonymous namespace RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, - ScreenInfo& info) + ScreenInfo& info, GLShader::ProgramManager& program_manager) : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, - screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { - shader_program_manager = std::make_unique(); - state.draw.shader_program = 0; - state.Apply(); - + screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device, + STREAM_BUFFER_SIZE} { CheckExtensions(); } @@ -228,10 +225,10 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { if (!gpu.regs.IsShaderConfigEnabled(index)) { switch (program) { case Maxwell::ShaderProgram::Geometry: - shader_program_manager->UseTrivialGeometryShader(); + program_manager.UseGeometryShader(0); break; case Maxwell::ShaderProgram::Fragment: - shader_program_manager->UseTrivialFragmentShader(); + program_manager.UseFragmentShader(0); break; default: break; @@ -262,13 +259,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { switch (program) { case Maxwell::ShaderProgram::VertexA: case Maxwell::ShaderProgram::VertexB: - shader_program_manager->UseProgrammableVertexShader(program_handle); + program_manager.UseVertexShader(program_handle); break; case Maxwell::ShaderProgram::Geometry: - shader_program_manager->UseProgrammableGeometryShader(program_handle); + program_manager.UseGeometryShader(program_handle); break; case Maxwell::ShaderProgram::Fragment: - shader_program_manager->UseProgrammableFragmentShader(program_handle); + program_manager.UseFragmentShader(program_handle); break; default: UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index, @@ -550,7 +547,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - shader_program_manager->ApplyTo(state); + program_manager.Update(); state.Apply(); if (texture_cache.TextureBarrier()) { @@ -613,8 +610,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y, launch_desc.block_dim_z, launch_desc.shared_alloc, launch_desc.local_pos_alloc); - state.draw.shader_program = kernel->GetHandle(variant); - state.draw.program_pipeline = 0; + glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT, + kernel->GetHandle(variant)); const std::size_t buffer_size = Tegra::Engines::KeplerCompute::NumConstBuffers * @@ -632,9 +629,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { bind_ubo_pushbuffer.Bind(); bind_ssbo_pushbuffer.Bind(); - state.ApplyShaderProgram(); - state.ApplyProgramPipeline(); - glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); ++num_queued_commands; } -- cgit v1.2.3 From b92dfcd7f2a03b04a1d6090d7dd2684986f7adee Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 26 Dec 2019 16:15:24 -0300 Subject: gl_state: Remove completely --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 84c4d110c..3ce2a7124 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -359,8 +359,8 @@ void RasterizerOpenGL::ConfigureFramebuffers() { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key)); } -void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb, - bool using_depth_fb, bool using_stencil_fb) { +void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using_depth_fb, + bool using_stencil_fb) { using VideoCore::Surface::SurfaceType; auto& gpu = system.GPU().Maxwell3D(); @@ -396,10 +396,6 @@ void RasterizerOpenGL::Clear() { bool use_depth{}; bool use_stencil{}; - OpenGLState prev_state{OpenGLState::GetCurState()}; - SCOPE_EXIT({ prev_state.Apply(); }); - - OpenGLState clear_state{OpenGLState::GetCurState()}; if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || regs.clear_buffers.A) { use_color = true; @@ -430,7 +426,7 @@ void RasterizerOpenGL::Clear() { return; } - ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); + ConfigureClearFramebuffer(use_color, use_depth, use_stencil); SyncRasterizeEnable(); if (regs.clear_flags.scissor) { @@ -444,8 +440,6 @@ void RasterizerOpenGL::Clear() { UNIMPLEMENTED_IF(regs.clear_flags.viewport); - clear_state.Apply(); - if (use_color) { glClearBufferfv(GL_COLOR, 0, regs.clear_color); } @@ -548,7 +542,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { bind_ssbo_pushbuffer.Bind(); program_manager.Update(); - state.Apply(); if (texture_cache.TextureBarrier()) { glTextureBarrier(); -- cgit v1.2.3 From 9e74e6988b881c6889074bd2335239eb2e491e91 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 21:41:41 -0300 Subject: maxwell_3d: Flatten cull and front face registers --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3ce2a7124..2fb8ec33b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -945,10 +945,10 @@ void RasterizerOpenGL::SyncClipCoef() { void RasterizerOpenGL::SyncCullMode() { const auto& regs = system.GPU().Maxwell3D().regs; - oglEnable(GL_CULL_FACE, regs.cull.enabled); - glCullFace(MaxwellToGL::CullFace(regs.cull.cull_face)); + oglEnable(GL_CULL_FACE, regs.cull_test_enabled); + glCullFace(MaxwellToGL::CullFace(regs.cull_face)); - glFrontFace(MaxwellToGL::FrontFace(regs.cull.front_face)); + glFrontFace(MaxwellToGL::FrontFace(regs.front_face)); } void RasterizerOpenGL::SyncPrimitiveRestart() { -- cgit v1.2.3 From dacf83ac0257727a48c971ca1cfcd220976c461f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 21:45:56 -0300 Subject: renderer_opengl: Reintroduce dirty flags for render targets --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2fb8ec33b..a1675355e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -99,11 +99,12 @@ void oglEnablei(GLenum cap, bool state, GLuint index) { } // Anonymous namespace RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, - ScreenInfo& info, GLShader::ProgramManager& program_manager) - : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device}, + ScreenInfo& info, GLShader::ProgramManager& program_manager, + StateTracker& state_tracker) + : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device, state_tracker}, shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, - screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device, - STREAM_BUFFER_SIZE} { + screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, + buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { CheckExtensions(); } @@ -320,9 +321,17 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, shader_cache.LoadDiskCache(stop_loading, callback); } +void RasterizerOpenGL::SetupDirtyFlags() { + state_tracker.Initialize(); +} + void RasterizerOpenGL::ConfigureFramebuffers() { MICROPROFILE_SCOPE(OpenGL_Framebuffer); auto& gpu = system.GPU().Maxwell3D(); + if (!gpu.dirty.flags[VideoCommon::Dirty::RenderTargets]) { + return; + } + gpu.dirty.flags[VideoCommon::Dirty::RenderTargets] = false; texture_cache.GuardRenderTargets(true); @@ -361,8 +370,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() { void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using_depth_fb, bool using_stencil_fb) { - using VideoCore::Surface::SurfaceType; - auto& gpu = system.GPU().Maxwell3D(); const auto& regs = gpu.regs; @@ -381,6 +388,7 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using key.colors[0] = color_surface; key.zeta = depth_surface; + state_tracker.NotifyFramebuffer(); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key)); } -- cgit v1.2.3 From 7f52efdf61d16d6eaa7eea2500ceb28d9f1041e1 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 22:12:12 -0300 Subject: gl_state_tracker: Implement dirty flags for viewports --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 31 ++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a1675355e..2427b8c07 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -906,13 +906,30 @@ void RasterizerOpenGL::SetupImage(u32 binding, const Tegra::Texture::TICEntry& t } void RasterizerOpenGL::SyncViewport() { - const auto& regs = system.GPU().Maxwell3D().regs; - for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { - const auto& src = regs.viewports[i]; - const Common::Rectangle rect{regs.viewport_transform[i].GetRect()}; - glViewportIndexedf(static_cast(i), rect.left, rect.bottom, rect.GetWidth(), - rect.GetHeight()); - glDepthRangef(src.depth_range_near, src.depth_range_far); + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + const auto& regs = gpu.regs; + + if (flags[Dirty::Viewports]) { + flags[Dirty::Viewports] = false; + + const bool force = flags[Dirty::ViewportTransform]; + flags[Dirty::ViewportTransform] = false; + + for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { + if (!force && !flags[Dirty::Viewport0 + i]) { + continue; + } + flags[Dirty::Viewport0 + i] = false; + + const Common::Rectangle rect{regs.viewport_transform[i].GetRect()}; + glViewportIndexedf(static_cast(i), rect.left, rect.bottom, rect.GetWidth(), + rect.GetHeight()); + + const auto& src = regs.viewports[i]; + glDepthRangeIndexed(static_cast(i), static_cast(src.depth_range_near), + static_cast(src.depth_range_far)); + } } bool flip_y = false; -- cgit v1.2.3 From ba6f390448987c01ae0e4b7ffe98b77bbd47c6d9 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 22:31:00 -0300 Subject: gl_state_tracker: Implement dirty flags for scissors --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2427b8c07..2ec4c9f55 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1102,12 +1102,28 @@ void RasterizerOpenGL::SyncLogicOpState() { } void RasterizerOpenGL::SyncScissorTest() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::Scissors]) { + return; + } + flags[Dirty::Scissors] = false; + + const auto& regs = gpu.regs; for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { + if (!flags[Dirty::Scissor0 + index]) { + continue; + } + flags[Dirty::Scissor0 + index] = false; + const auto& src = regs.scissor_test[index]; - oglEnablei(GL_SCISSOR_TEST, src.enable, static_cast(index)); - glScissorIndexed(static_cast(index), src.min_x, src.min_y, src.max_x - src.min_x, - src.max_y - src.min_y); + if (src.enable) { + glEnablei(GL_SCISSOR_TEST, static_cast(index)); + glScissorIndexed(static_cast(index), src.min_x, src.min_y, + src.max_x - src.min_x, src.max_y - src.min_y); + } else { + glDisablei(GL_SCISSOR_TEST, static_cast(index)); + } } } -- cgit v1.2.3 From 6530144ccb0adccf101fcc443f9b21a027faa7a7 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 22:51:04 -0300 Subject: gl_state_tracker: Implement dirty flags for color masks --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 39 ++++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2ec4c9f55..b4cec274d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -410,8 +410,9 @@ void RasterizerOpenGL::Clear() { } if (use_color) { // TODO: Signal state tracker about these changes - glColorMaski(0, regs.clear_buffers.R, regs.clear_buffers.G, regs.clear_buffers.B, - regs.clear_buffers.A); + state_tracker.NotifyColorMask0(); + glColorMaski(0, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0, + regs.clear_buffers.B != 0, regs.clear_buffers.A != 0); SyncFramebufferSRGB(); // TODO(Rodrigo): Determine if clamping is used on clears @@ -1030,17 +1031,37 @@ void RasterizerOpenGL::SyncRasterizeEnable() { } void RasterizerOpenGL::SyncColorMask() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::ColorMasks]) { + return; + } + flags[Dirty::ColorMasks] = false; + + const bool force = flags[Dirty::ColorMaskCommon]; + flags[Dirty::ColorMaskCommon] = false; + const auto& regs = gpu.regs; if (regs.color_mask_common) { + if (!force && !flags[Dirty::ColorMask0]) { + return; + } + flags[Dirty::ColorMask0] = false; + auto& mask = regs.color_mask[0]; - glColorMask(mask.R, mask.B, mask.G, mask.A); - } else { - for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { - const auto& mask = regs.color_mask[regs.color_mask_common ? 0 : i]; - glColorMaski(static_cast(i), mask.R, mask.G, mask.B, mask.A); + glColorMask(mask.R != 0, mask.B != 0, mask.G != 0, mask.A != 0); + return; + } + + // Path without color_mask_common set + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { + if (!force && !flags[Dirty::ColorMask0 + i]) { + continue; } + flags[Dirty::ColorMask0 + i] = false; + + const auto& mask = regs.color_mask[i]; + glColorMaski(static_cast(i), mask.R != 0, mask.G != 0, mask.B != 0, mask.A != 0); } } -- cgit v1.2.3 From 69ad6279e45db408ba3add0b540660ae34ba8e3f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 23:08:40 -0300 Subject: gl_state_tracker: Implement dirty flags for vertex formats --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b4cec274d..211b11489 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -120,7 +120,11 @@ void RasterizerOpenGL::CheckExtensions() { void RasterizerOpenGL::SetupVertexFormat() { auto& gpu = system.GPU().Maxwell3D(); - const auto& regs = gpu.regs; + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::VertexFormats]) { + return; + } + flags[Dirty::VertexFormats] = false; MICROPROFILE_SCOPE(OpenGL_VAO); @@ -130,25 +134,31 @@ void RasterizerOpenGL::SetupVertexFormat() { // avoid OpenGL errors. // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't // assume every shader uses them all. - for (u32 index = 0; index < 16; ++index) { - const auto& attrib = regs.vertex_attrib_format[index]; + for (std::size_t index = 0; index < 16; ++index) { + if (!flags[Dirty::VertexFormat0 + index]) { + continue; + } + flags[Dirty::VertexFormat0 + index] = false; + + const auto attrib = gpu.regs.vertex_attrib_format[index]; + const auto gl_index = static_cast(index); // Ignore invalid attributes. if (!attrib.IsValid()) { - glDisableVertexAttribArray(index); + glDisableVertexAttribArray(gl_index); continue; } - glEnableVertexAttribArray(index); + glEnableVertexAttribArray(gl_index); if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { - glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), - attrib.offset); + glVertexAttribIFormat(gl_index, attrib.ComponentCount(), + MaxwellToGL::VertexType(attrib), attrib.offset); } else { - glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), + glVertexAttribFormat(gl_index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); } - glVertexAttribBinding(index, attrib.buffer); + glVertexAttribBinding(gl_index, attrib.buffer); } } -- cgit v1.2.3 From 758ad3f75d49be811237c297265038f80c16ee8c Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 01:28:53 -0300 Subject: gl_state_tracker: Add dirty flags for buffers and divisors --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 51 ++++++++++++++---------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 211b11489..bb89985cc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -164,12 +164,22 @@ void RasterizerOpenGL::SetupVertexFormat() { void RasterizerOpenGL::SetupVertexBuffer() { auto& gpu = system.GPU().Maxwell3D(); - const auto& regs = gpu.regs; + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::VertexBuffers]) { + return; + } + flags[Dirty::VertexBuffers] = false; MICROPROFILE_SCOPE(OpenGL_VB); // Upload all guest vertex arrays sequentially to our buffer - for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { + const auto& regs = gpu.regs; + for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { + if (!flags[Dirty::VertexBuffer0 + index]) { + continue; + } + flags[Dirty::VertexBuffer0 + index] = false; + const auto& vertex_array = regs.vertex_array[index]; if (!vertex_array.IsEnabled()) { continue; @@ -183,33 +193,30 @@ void RasterizerOpenGL::SetupVertexBuffer() { const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); // Bind the vertex array to the buffer at the current offset. - vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset, - vertex_array.stride); - - if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { - // Enable vertex buffer instancing with the specified divisor. - glVertexBindingDivisor(index, vertex_array.divisor); - } else { - // Disable the vertex buffer instancing. - glVertexBindingDivisor(index, 0); - } + vertex_array_pushbuffer.SetVertexBuffer(static_cast(index), vertex_buffer, + vertex_buffer_offset, vertex_array.stride); } } void RasterizerOpenGL::SetupVertexInstances() { auto& gpu = system.GPU().Maxwell3D(); - const auto& regs = gpu.regs; + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::VertexInstances]) { + return; + } + flags[Dirty::VertexInstances] = false; - // Upload all guest vertex arrays sequentially to our buffer - for (u32 index = 0; index < 16; ++index) { - if (regs.instanced_arrays.IsInstancingEnabled(index) && - regs.vertex_array[index].divisor != 0) { - // Enable vertex buffer instancing with the specified divisor. - glVertexBindingDivisor(index, regs.vertex_array[index].divisor); - } else { - // Disable the vertex buffer instancing. - glVertexBindingDivisor(index, 0); + const auto& regs = gpu.regs; + for (std::size_t index = 0; index < 16; ++index) { + if (!flags[Dirty::VertexInstance0 + index]) { + continue; } + flags[Dirty::VertexInstance0 + index] = false; + + const auto gl_index = static_cast(index); + const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index); + const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0; + glVertexBindingDivisor(gl_index, divisor); } } -- cgit v1.2.3 From f7ec078592468fa22ff377b996a720c8be82c2dc Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 02:03:05 -0300 Subject: gl_state_tracker: Implement dirty flags for clip distances and shaders --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 28 +++++++++++++++--------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bb89985cc..717f127e9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -232,8 +232,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() { void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { MICROPROFILE_SCOPE(OpenGL_Shader); auto& gpu = system.GPU().Maxwell3D(); - - std::array clip_distances{}; + u32 clip_distances = 0; for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { const auto& shader_config = gpu.regs.shader_config[index]; @@ -294,9 +293,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { // When a clip distance is enabled but not set in the shader it crops parts of the screen // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the // clip distances only when it's written by a shader stage. - for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) { - clip_distances[i] = clip_distances[i] || shader->GetShaderEntries().clip_distances[i]; - } + clip_distances |= shader->GetShaderEntries().clip_distances; // When VertexA is enabled, we have dual vertex shaders if (program == Maxwell::ShaderProgram::VertexA) { @@ -306,6 +303,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { } SyncClipEnabled(clip_distances); + gpu.dirty.flags[Dirty::Shaders] = false; } std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { @@ -972,12 +970,22 @@ void RasterizerOpenGL::SyncDepthClamp() { oglEnable(GL_DEPTH_CLAMP, state.depth_clamp_far || state.depth_clamp_near); } -void RasterizerOpenGL::SyncClipEnabled( - const std::array& clip_mask) { - const auto& regs = system.GPU().Maxwell3D().regs; +void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) { + return; + } + flags[Dirty::ClipDistances] = false; + + clip_mask &= gpu.regs.clip_distance_enabled; + if (clip_mask == last_clip_distance_mask) { + return; + } + last_clip_distance_mask = clip_mask; + for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) { - oglEnable(static_cast(GL_CLIP_DISTANCE0 + i), - clip_mask[i] && ((regs.clip_distance_enabled >> i) & 1)); + oglEnable(static_cast(GL_CLIP_DISTANCE0 + i), (clip_mask >> i) & 1); } } -- cgit v1.2.3 From b01dd7d1c86265dd19508ea15e4ff4db31681470 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 18:14:40 -0300 Subject: gl_state_tracker: Implement dirty flags for blending --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 49 +++++++++++++++++------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 717f127e9..cedfe5db1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -458,6 +458,7 @@ void RasterizerOpenGL::Clear() { } // TODO: Signal state tracker about these changes + state_tracker.NotifyBlend0(); // TODO(Rodrigo): Find out if these changes affect clearing glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glDisablei(GL_BLEND, 0); @@ -1102,31 +1103,53 @@ void RasterizerOpenGL::SyncFragmentColorClampState() { } void RasterizerOpenGL::SyncBlendState() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + const auto& regs = gpu.regs; + + if (flags[Dirty::BlendColor]) { + flags[Dirty::BlendColor] = false; + glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, + regs.blend_color.a); + } - glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a); + // TODO(Rodrigo): Revisit blending, there are several registers we are not reading + + if (!flags[Dirty::BlendStates]) { + return; + } + flags[Dirty::BlendStates] = false; if (!regs.independent_blend_enable) { - const auto& src = regs.blend; - oglEnable(GL_BLEND, src.enable[0]); - if (!src.enable[0]) { + if (!regs.blend.enable[0]) { + glDisable(GL_BLEND); return; } - glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb), - MaxwellToGL::BlendFunc(src.factor_dest_rgb), - MaxwellToGL::BlendFunc(src.factor_source_a), - MaxwellToGL::BlendFunc(src.factor_dest_a)); - glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb), - MaxwellToGL::BlendEquation(src.equation_a)); + glEnable(GL_BLEND); + glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb), + MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb), + MaxwellToGL::BlendFunc(regs.blend.factor_source_a), + MaxwellToGL::BlendFunc(regs.blend.factor_dest_a)); + glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb), + MaxwellToGL::BlendEquation(regs.blend.equation_a)); return; } + const bool force = flags[Dirty::BlendIndependentEnabled]; + flags[Dirty::BlendIndependentEnabled] = false; + for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { - oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast(i)); + if (!force && !flags[Dirty::BlendState0 + i]) { + continue; + } + flags[Dirty::BlendState0 + i] = false; + if (!regs.blend.enable[i]) { + glDisablei(GL_BLEND, static_cast(i)); continue; } + glEnablei(GL_BLEND, static_cast(i)); + const auto& src = regs.independent_blend[i]; glBlendFuncSeparatei(static_cast(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), MaxwellToGL::BlendFunc(src.factor_dest_rgb), -- cgit v1.2.3 From b910a83a47a2b566a760dbd20ff5902f303044d4 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 19:23:40 -0300 Subject: gl_state_tracker: Implement dirty flags for front face and culling --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index cedfe5db1..6d87b4e29 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -995,12 +995,25 @@ void RasterizerOpenGL::SyncClipCoef() { } void RasterizerOpenGL::SyncCullMode() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + const auto& regs = gpu.regs; - oglEnable(GL_CULL_FACE, regs.cull_test_enabled); - glCullFace(MaxwellToGL::CullFace(regs.cull_face)); + if (flags[Dirty::CullTest]) { + flags[Dirty::CullTest] = false; - glFrontFace(MaxwellToGL::FrontFace(regs.front_face)); + if (regs.cull_test_enabled) { + glEnable(GL_CULL_FACE); + glCullFace(MaxwellToGL::CullFace(regs.cull_face)); + } else { + glDisable(GL_CULL_FACE); + } + } + + if (flags[Dirty::FrontFace]) { + flags[Dirty::FrontFace] = false; + glFrontFace(MaxwellToGL::FrontFace(regs.front_face)); + } } void RasterizerOpenGL::SyncPrimitiveRestart() { -- cgit v1.2.3 From 40a2c57df5459ff965f1ea507bbca0e36ab17c94 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 22:56:21 -0300 Subject: gl_state_tracker: Implement depth dirty flags --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 6d87b4e29..d747e29ad 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1024,13 +1024,23 @@ void RasterizerOpenGL::SyncPrimitiveRestart() { } void RasterizerOpenGL::SyncDepthTestState() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; - glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); + const auto& regs = gpu.regs; + if (flags[Dirty::DepthMask]) { + flags[Dirty::DepthMask] = false; + glDepthMask(regs.depth_write_enabled ? GL_TRUE : GL_FALSE); + } - oglEnable(GL_DEPTH_TEST, regs.depth_test_enable); - if (regs.depth_test_enable) { - glDepthFunc(MaxwellToGL::ComparisonOp(regs.depth_test_func)); + if (flags[Dirty::DepthTest]) { + flags[Dirty::DepthTest] = false; + if (regs.depth_test_enable) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(MaxwellToGL::ComparisonOp(regs.depth_test_func)); + } else { + glDisable(GL_DEPTH_TEST); + } } } -- cgit v1.2.3 From 37536d7a4996d0008d8988f50dcbc7c126a99c14 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 23:08:32 -0300 Subject: gl_state_tracker: Implement dirty flags for stencil testing --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d747e29ad..bc4542b69 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1045,14 +1045,20 @@ void RasterizerOpenGL::SyncDepthTestState() { } void RasterizerOpenGL::SyncStencilTestState() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::StencilTest]) { + return; + } + flags[Dirty::StencilTest] = false; - oglEnable(GL_STENCIL_TEST, regs.stencil_enable); + const auto& regs = gpu.regs; if (!regs.stencil_enable) { + glDisable(GL_STENCIL_TEST); return; } + glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), regs.stencil_front_func_ref, regs.stencil_front_func_mask); glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), -- cgit v1.2.3 From 46a1888e02f04c1478fbf61ae003f14d09c70a42 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 29 Dec 2019 23:25:53 -0300 Subject: gl_state_tracker: Implement dirty flags for primitive restart --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bc4542b69..ebb072d91 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1017,10 +1017,19 @@ void RasterizerOpenGL::SyncCullMode() { } void RasterizerOpenGL::SyncPrimitiveRestart() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::PrimitiveRestart]) { + return; + } + flags[Dirty::PrimitiveRestart] = false; - oglEnable(GL_PRIMITIVE_RESTART, regs.primitive_restart.enabled); - glPrimitiveRestartIndex(regs.primitive_restart.index); + if (gpu.regs.primitive_restart.enabled) { + glEnable(GL_PRIMITIVE_RESTART); + glPrimitiveRestartIndex(gpu.regs.primitive_restart.index); + } else { + glDisable(GL_PRIMITIVE_RESTART); + } } void RasterizerOpenGL::SyncDepthTestState() { -- cgit v1.2.3 From 9e46953580eab7b5b1e7b813db0284a9d2f78f27 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:22:43 -0300 Subject: gl_state_tracker: Implement dirty flags for polygon offsets --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ebb072d91..78838b8d1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1249,9 +1249,14 @@ void RasterizerOpenGL::SyncPointState() { } void RasterizerOpenGL::SyncPolygonOffset() { - auto& maxwell3d = system.GPU().Maxwell3D(); - const auto& regs = maxwell3d.regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::PolygonOffset]) { + return; + } + flags[Dirty::PolygonOffset] = false; + const auto& regs = gpu.regs; oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable); oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); -- cgit v1.2.3 From 3c22bd92d878fcfe7b710e84b478b962fd325417 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:37:35 -0300 Subject: gl_state_tracker: Implement dirty flags for alpha testing --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 78838b8d1..5949f53ab 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1267,13 +1267,23 @@ void RasterizerOpenGL::SyncPolygonOffset() { } void RasterizerOpenGL::SyncAlphaTest() { - const auto& regs = system.GPU().Maxwell3D().regs; - UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1, - "Alpha Testing is enabled with more than one rendertarget"); + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::AlphaTest]) { + return; + } + flags[Dirty::AlphaTest] = false; + + const auto& regs = gpu.regs; + if (regs.alpha_test_enabled && regs.rt_control.count > 1) { + LOG_WARNING(Render_OpenGL, "Alpha testing with more than one render target is not tested"); + } - oglEnable(GL_ALPHA_TEST, regs.alpha_test_enabled); if (regs.alpha_test_enabled) { + glEnable(GL_ALPHA_TEST); glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref); + } else { + glDisable(GL_ALPHA_TEST); } } -- cgit v1.2.3 From b727d99441e20893faf24410947e158c8faf2d09 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:43:15 -0300 Subject: gl_state_tracker: Implement dirty flags for multisample --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5949f53ab..e4875608a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1130,6 +1130,13 @@ void RasterizerOpenGL::SyncColorMask() { } void RasterizerOpenGL::SyncMultiSampleState() { + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::MultisampleControl]) { + return; + } + flags[Dirty::MultisampleControl] = false; + const auto& regs = system.GPU().Maxwell3D().regs; oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); -- cgit v1.2.3 From d8f5c450516c3956b422f0487293ea02620a3518 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:49:19 -0300 Subject: gl_state_tracker: Implement dirty flags for rasterize enable --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e4875608a..a650113ca 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1090,8 +1090,14 @@ void RasterizerOpenGL::SyncStencilTestState() { } void RasterizerOpenGL::SyncRasterizeEnable() { - const auto& regs = system.GPU().Maxwell3D().regs; - oglEnable(GL_RASTERIZER_DISCARD, regs.rasterize_enable == 0); + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::RasterizeEnable]) { + return; + } + flags[Dirty::RasterizeEnable] = false; + + oglEnable(GL_RASTERIZER_DISCARD, gpu.regs.rasterize_enable == 0); } void RasterizerOpenGL::SyncColorMask() { -- cgit v1.2.3 From 13afd0e5b0a5e84f2a979515185ece5b54d3fed4 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:53:53 -0300 Subject: gl_state_tracker: Implement dirty flags for sRGB --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a650113ca..47ad834aa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1301,8 +1301,14 @@ void RasterizerOpenGL::SyncAlphaTest() { } void RasterizerOpenGL::SyncFramebufferSRGB() { - const auto& regs = system.GPU().Maxwell3D().regs; - oglEnable(GL_FRAMEBUFFER_SRGB, regs.framebuffer_srgb); + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::FramebufferSRGB]) { + return; + } + flags[Dirty::FramebufferSRGB] = false; + + oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb); } } // namespace OpenGL -- cgit v1.2.3 From bf1a1d989f03b6597a34de8d97b29c189e293134 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 00:57:50 -0300 Subject: gl_state_tracker: Implement dirty flags for logic op --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 47ad834aa..4cb050da6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1213,11 +1213,19 @@ void RasterizerOpenGL::SyncBlendState() { } void RasterizerOpenGL::SyncLogicOpState() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::LogicOp]) { + return; + } + flags[Dirty::LogicOp] = false; - oglEnable(GL_COLOR_LOGIC_OP, regs.logic_op.enable); + const auto& regs = gpu.regs; if (regs.logic_op.enable) { + glEnable(GL_COLOR_LOGIC_OP); glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); + } else { + glDisable(GL_COLOR_LOGIC_OP); } } -- cgit v1.2.3 From 231601763c4717f8d7978341994a479e4283fa3d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 01:20:08 -0300 Subject: gl_state_tracker: Implement dirty flags for fragment color clamp --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 4cb050da6..7ffb8fa09 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1149,8 +1149,14 @@ void RasterizerOpenGL::SyncMultiSampleState() { } void RasterizerOpenGL::SyncFragmentColorClampState() { - const auto& regs = system.GPU().Maxwell3D().regs; - glClampColor(GL_CLAMP_FRAGMENT_COLOR, regs.frag_color_clamp ? GL_TRUE : GL_FALSE); + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::FragmentClampColor]) { + return; + } + flags[Dirty::FragmentClampColor] = false; + + glClampColor(GL_CLAMP_FRAGMENT_COLOR, gpu.regs.frag_color_clamp ? GL_TRUE : GL_FALSE); } void RasterizerOpenGL::SyncBlendState() { -- cgit v1.2.3 From 4f8d152b1810bbfb2900de6520dbf9df93f9a67d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 01:27:42 -0300 Subject: gl_state_tracker: Implement dirty flags for point sizes --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7ffb8fa09..ec1936927 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1267,12 +1267,25 @@ void RasterizerOpenGL::SyncTransformFeedback() { } void RasterizerOpenGL::SyncPointState() { - const auto& regs = system.GPU().Maxwell3D().regs; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::PointSize]) { + return; + } + flags[Dirty::PointSize] = false; + + oglEnable(GL_POINT_SPRITE, gpu.regs.point_sprite_enable); + + if (gpu.regs.vp_point_size.enable) { + // By definition of GL_POINT_SIZE, it only matters if GL_PROGRAM_POINT_SIZE is disabled. + glEnable(GL_PROGRAM_POINT_SIZE); + return; + } + // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid // in OpenGL). - oglEnable(GL_PROGRAM_POINT_SIZE, regs.vp_point_size.enable); - oglEnable(GL_POINT_SPRITE, regs.point_sprite_enable); - glPointSize(std::max(1.0f, regs.point_size)); + glPointSize(std::max(1.0f, gpu.regs.point_size)); + glDisable(GL_PROGRAM_POINT_SIZE); } void RasterizerOpenGL::SyncPolygonOffset() { -- cgit v1.2.3 From a42a6e1a2c41b59a779d92a94123f38d88c3fec3 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 30 Dec 2019 01:40:27 -0300 Subject: gl_state_tracker: Implement dirty flags for clip control --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 30 ++++++++++++++---------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ec1936927..133ac6c0f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -460,7 +460,6 @@ void RasterizerOpenGL::Clear() { // TODO: Signal state tracker about these changes state_tracker.NotifyBlend0(); // TODO(Rodrigo): Find out if these changes affect clearing - glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); glDisablei(GL_BLEND, 0); UNIMPLEMENTED_IF(regs.clear_flags.viewport); @@ -927,7 +926,23 @@ void RasterizerOpenGL::SyncViewport() { auto& flags = gpu.dirty.flags; const auto& regs = gpu.regs; - if (flags[Dirty::Viewports]) { + const bool dirty_viewport = flags[Dirty::Viewports]; + if (dirty_viewport || flags[Dirty::ClipControl]) { + flags[Dirty::ClipControl] = false; + + bool flip_y = false; + if (regs.viewport_transform[0].scale_y < 0.0) { + flip_y = !flip_y; + } + if (regs.screen_y_control.y_negate != 0) { + flip_y = !flip_y; + } + glClipControl(flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT, + regs.depth_mode == Maxwell::DepthMode::ZeroToOne ? GL_ZERO_TO_ONE + : GL_NEGATIVE_ONE_TO_ONE); + } + + if (dirty_viewport) { flags[Dirty::Viewports] = false; const bool force = flags[Dirty::ViewportTransform]; @@ -948,17 +963,6 @@ void RasterizerOpenGL::SyncViewport() { static_cast(src.depth_range_far)); } } - - bool flip_y = false; - if (regs.viewport_transform[0].scale_y < 0.0) { - flip_y = !flip_y; - } - if (regs.screen_y_control.y_negate != 0) { - flip_y = !flip_y; - } - glClipControl(flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT, - regs.depth_mode == Maxwell::DepthMode::ZeroToOne ? GL_ZERO_TO_ONE - : GL_NEGATIVE_ONE_TO_ONE); } void RasterizerOpenGL::SyncDepthClamp() { -- cgit v1.2.3 From 98c8948b238793271154c1718eaabeaeb2f0bb1b Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 2 Jan 2020 22:30:41 -0300 Subject: gl_rasterizer: Minor sort changes to clearing --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 133ac6c0f..dabb22ae8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -408,13 +408,12 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using } void RasterizerOpenGL::Clear() { - const auto& maxwell3d = system.GPU().Maxwell3D(); - - if (!maxwell3d.ShouldExecute()) { + const auto& gpu = system.GPU().Maxwell3D(); + if (!gpu.ShouldExecute()) { return; } - const auto& regs = maxwell3d.regs; + const auto& regs = gpu.regs; bool use_color{}; bool use_depth{}; bool use_stencil{}; @@ -424,14 +423,13 @@ void RasterizerOpenGL::Clear() { use_color = true; } if (use_color) { - // TODO: Signal state tracker about these changes state_tracker.NotifyColorMask0(); glColorMaski(0, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0, regs.clear_buffers.B != 0, regs.clear_buffers.A != 0); - SyncFramebufferSRGB(); // TODO(Rodrigo): Determine if clamping is used on clears SyncFragmentColorClampState(); + SyncFramebufferSRGB(); } if (regs.clear_buffers.Z) { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); @@ -441,7 +439,7 @@ void RasterizerOpenGL::Clear() { glDepthMask(GL_TRUE); } if (regs.clear_buffers.S) { - ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear stencil but buffer is not enabled!"); + ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!"); use_stencil = true; } @@ -450,20 +448,20 @@ void RasterizerOpenGL::Clear() { return; } - ConfigureClearFramebuffer(use_color, use_depth, use_stencil); - SyncRasterizeEnable(); + if (regs.clear_flags.scissor) { SyncScissorTest(); } - // TODO: Signal state tracker about these changes + // TODO(Rodrigo): Find out if blending affects clearing state_tracker.NotifyBlend0(); - // TODO(Rodrigo): Find out if these changes affect clearing glDisablei(GL_BLEND, 0); UNIMPLEMENTED_IF(regs.clear_flags.viewport); + ConfigureClearFramebuffer(use_color, use_depth, use_stencil); + if (use_color) { glClearBufferfv(GL_COLOR, 0, regs.clear_color); } -- cgit v1.2.3 From 35bb9239cae38a173204cfc36bdfa22aec88fb00 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 2 Jan 2020 22:31:04 -0300 Subject: gl_rasterizer: Notify depth mask changes on clear --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index dabb22ae8..c8aa342ef 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -435,7 +435,7 @@ void RasterizerOpenGL::Clear() { ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); use_depth = true; - // TODO: Signal state tracker about these changes + state_tracker.NotifyDepthMask(); glDepthMask(GL_TRUE); } if (regs.clear_buffers.S) { -- cgit v1.2.3 From 3ce66776eccc23a3c1af69ce6ce079e28361fd58 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 2 Jan 2020 22:31:33 -0300 Subject: gl_rasterizer: Disable scissor 0 when scissor is not used on clear --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index c8aa342ef..e035be867 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -452,6 +452,9 @@ void RasterizerOpenGL::Clear() { if (regs.clear_flags.scissor) { SyncScissorTest(); + } else { + state_tracker.NotifyScissor0(); + glDisablei(GL_SCISSOR_TEST, 0); } // TODO(Rodrigo): Find out if blending affects clearing -- cgit v1.2.3 From 2eeea907138926e7d712bf20f92c1f3d1cc2d594 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 2 Jan 2020 22:41:20 -0300 Subject: gl_state_tracker: Implement dirty flags for depth clamp enabling --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e035be867..3ffa9988e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -493,6 +493,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { SyncFragmentColorClampState(); SyncMultiSampleState(); SyncDepthTestState(); + SyncDepthClamp(); SyncStencilTestState(); SyncBlendState(); SyncLogicOpState(); @@ -967,11 +968,16 @@ void RasterizerOpenGL::SyncViewport() { } void RasterizerOpenGL::SyncDepthClamp() { - const auto& regs = system.GPU().Maxwell3D().regs; - const auto& state = regs.view_volume_clip_control; + auto& gpu = system.GPU().Maxwell3D(); + auto& flags = gpu.dirty.flags; + if (!flags[Dirty::DepthClampEnabled]) { + return; + } + flags[Dirty::DepthClampEnabled] = false; + const auto& state = gpu.regs.view_volume_clip_control; UNIMPLEMENTED_IF_MSG(state.depth_clamp_far != state.depth_clamp_near, - "Unimplemented Depth clamp separation!"); + "Unimplemented depth clamp separation!"); oglEnable(GL_DEPTH_CLAMP, state.depth_clamp_far || state.depth_clamp_near); } -- cgit v1.2.3 From 62437943a72d5ec2d5e0734767855ea54ea257a0 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 2 Jan 2020 22:42:56 -0300 Subject: gl_rasterizer: Only apply polygon offset clamp if enabled --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 3ffa9988e..8a762fd0d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -1312,9 +1312,12 @@ void RasterizerOpenGL::SyncPolygonOffset() { oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable); oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable); - // Hardware divides polygon offset units by two - glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f, - regs.polygon_offset_clamp); + if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable || + regs.polygon_offset_point_enable) { + // Hardware divides polygon offset units by two + glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f, + regs.polygon_offset_clamp); + } } void RasterizerOpenGL::SyncAlphaTest() { -- cgit v1.2.3 From b1498d2c54b11b9a9c0ab307f03377f6661ab873 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 13 Jan 2020 17:20:02 -0300 Subject: gl_rasterizer: Remove num vertex buffers magic number --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 8a762fd0d..84c285db8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -54,6 +54,8 @@ MICROPROFILE_DEFINE(OpenGL_PrimitiveAssembly, "OpenGL", "Prim Asmbl", MP_RGB(255 namespace { +constexpr std::size_t NumSupportedVertexAttributes = 16; + template Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry, Tegra::Engines::ShaderType shader_type, @@ -134,7 +136,7 @@ void RasterizerOpenGL::SetupVertexFormat() { // avoid OpenGL errors. // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't // assume every shader uses them all. - for (std::size_t index = 0; index < 16; ++index) { + for (std::size_t index = 0; index < NumSupportedVertexAttributes; ++index) { if (!flags[Dirty::VertexFormat0 + index]) { continue; } @@ -207,7 +209,7 @@ void RasterizerOpenGL::SetupVertexInstances() { flags[Dirty::VertexInstances] = false; const auto& regs = gpu.regs; - for (std::size_t index = 0; index < 16; ++index) { + for (std::size_t index = 0; index < NumSupportedVertexAttributes; ++index) { if (!flags[Dirty::VertexInstance0 + index]) { continue; } -- cgit v1.2.3 From 887d5288efab9b98141c9d042bc2fba3fbe230d2 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 21 Feb 2020 02:55:08 -0300 Subject: gl_rasterizer: Don't disable blending on clears Blending doesn't affect clears. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 84c285db8..8f977985b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -459,10 +459,6 @@ void RasterizerOpenGL::Clear() { glDisablei(GL_SCISSOR_TEST, 0); } - // TODO(Rodrigo): Find out if blending affects clearing - state_tracker.NotifyBlend0(); - glDisablei(GL_BLEND, 0); - UNIMPLEMENTED_IF(regs.clear_flags.viewport); ConfigureClearFramebuffer(use_color, use_depth, use_stencil); -- cgit v1.2.3