From ba6f390448987c01ae0e4b7ffe98b77bbd47c6d9 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 28 Dec 2019 22:31:00 -0300 Subject: [PATCH] gl_state_tracker: Implement dirty flags for scissors --- .../renderer_opengl/gl_rasterizer.cpp | 24 +++++++++++--- .../renderer_opengl/gl_state_tracker.cpp | 9 +++++ .../renderer_opengl/gl_state_tracker.h | 33 +++++++++++++++---- .../renderer_opengl/gl_texture_cache.cpp | 1 + .../renderer_opengl/renderer_opengl.cpp | 1 + 5 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2427b8c073..2ec4c9f551 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)); + } } } diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 6293f61021..9e1db59ae2 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -77,6 +77,14 @@ void SetupDirtyViewports(Tables& tables) { tables[1][OFF(viewport_transform_enabled)] = Viewports; } +void SetupDirtyScissors(Tables& tables) { + for (std::size_t i = 0; i < Regs::NumViewports; ++i) { + const std::size_t offset = OFF(scissor_test) + i * NUM(scissor_test[0]); + FillBlock(tables[0], offset, NUM(scissor_test[0]), Scissor0 + i); + } + FillBlock(tables[1], OFF(scissor_test), NUM(scissor_test), Scissors); +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) : system{system} {} @@ -97,6 +105,7 @@ void StateTracker::Initialize() { auto& tables = dirty.tables; SetupDirtyRenderTargets(tables); SetupDirtyViewports(tables); + SetupDirtyScissors(tables); } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 93c64a44a9..5153dc5d14 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -15,15 +15,30 @@ class System; namespace OpenGL { namespace Dirty { + enum : u8 { First = VideoCommon::Dirty::LastCommonEntry, VertexFormats, + VertexBuffers, + VertexBuffer0, + VertexBuffer31 = VertexBuffer0 + 31, + VertexInstances, - Shaders, - Viewports, + VertexInstance0, + VertexInstance31 = VertexInstance0 + 31, + ViewportTransform, + Viewports, + Viewport0, + Viewport15 = Viewport0 + 15, + + Scissors, + Scissor0, + Scissor15 = Scissor0 + 15, + + Shaders, CullTestEnable, FrontFace, CullFace, @@ -34,11 +49,11 @@ enum : u8 { BlendState, PolygonOffset, - Viewport0, - VertexBuffer0 = Viewport0 + 16, - VertexInstance0 = VertexBuffer0 + 32, + Last }; -} +static_assert(Last <= 0xff); + +} // namespace Dirty class StateTracker { public: @@ -52,6 +67,12 @@ public: flags[OpenGL::Dirty::Viewport0] = true; } + void NotifyScissor0() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::Scissors] = true; + flags[OpenGL::Dirty::Scissor0] = true; + } + void NotifyFramebuffer() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[VideoCommon::Dirty::RenderTargets] = true; diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 1cadcf2871..a02326b9f4 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -519,6 +519,7 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view, UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D); // TODO: Signal state tracker about these changes + state_tracker.NotifyScissor0(); state_tracker.NotifyFramebuffer(); if (dst_params.srgb_conversion) { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 73d2d90273..f2b07ac81c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -577,6 +577,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { // TODO: Signal state tracker about these changes state_tracker.NotifyViewport0(); + state_tracker.NotifyScissor0(); state_tracker.NotifyFramebuffer(); program_manager.UseVertexShader(vertex_program.handle);