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 +++++++++++++++++----- .../renderer_opengl/gl_state_tracker.cpp | 17 ++++++++++++ src/video_core/renderer_opengl/gl_state_tracker.h | 10 ++++++- src/video_core/renderer_opengl/renderer_opengl.cpp | 5 +++- 4 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/video_core') 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; diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 268b9351e..6293f6102 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp @@ -61,6 +61,22 @@ void SetupDirtyRenderTargets(Tables& tables) { } } +void SetupDirtyViewports(Tables& tables) { + for (std::size_t i = 0; i < Regs::NumViewports; ++i) { + const std::size_t transf_offset = OFF(viewport_transform) + i * NUM(viewport_transform[0]); + const std::size_t viewport_offset = OFF(viewports) + i * NUM(viewports[0]); + + FillBlock(tables[0], transf_offset, NUM(viewport_transform[0]), Viewport0 + i); + FillBlock(tables[0], viewport_offset, NUM(viewports[0]), Viewport0 + i); + } + + FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports); + FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports); + + tables[0][OFF(viewport_transform_enabled)] = ViewportTransform; + tables[1][OFF(viewport_transform_enabled)] = Viewports; +} + } // Anonymous namespace StateTracker::StateTracker(Core::System& system) : system{system} {} @@ -80,6 +96,7 @@ void StateTracker::Initialize() { auto& tables = dirty.tables; SetupDirtyRenderTargets(tables); + SetupDirtyViewports(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 91d4bb8d3..93c64a44a 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h @@ -23,6 +23,7 @@ enum : u8 { VertexInstances, Shaders, Viewports, + ViewportTransform, CullTestEnable, FrontFace, CullFace, @@ -33,7 +34,8 @@ enum : u8 { BlendState, PolygonOffset, - VertexBuffer0 = PolygonOffset + 8, + Viewport0, + VertexBuffer0 = Viewport0 + 16, VertexInstance0 = VertexBuffer0 + 32, }; } @@ -44,6 +46,12 @@ public: void Initialize(); + void NotifyViewport0() { + auto& flags = system.GPU().Maxwell3D().dirty.flags; + flags[OpenGL::Dirty::Viewports] = true; + flags[OpenGL::Dirty::Viewport0] = true; + } + void NotifyFramebuffer() { auto& flags = system.GPU().Maxwell3D().dirty.flags; flags[VideoCommon::Dirty::RenderTargets] = true; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 36c634e0d..73d2d9027 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -576,6 +576,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); // TODO: Signal state tracker about these changes + state_tracker.NotifyViewport0(); state_tracker.NotifyFramebuffer(); program_manager.UseVertexShader(vertex_program.handle); @@ -601,7 +602,9 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glFrontFace(GL_CW); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); - glViewport(0, 0, layout.width, layout.height); + glViewportIndexedf(0, 0.0f, 0.0f, static_cast(layout.width), + static_cast(layout.height)); + glDepthRangeIndexed(0, 0.0, 0.0); glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, offsetof(ScreenRectVertex, position)); -- cgit v1.2.3