From 4a512d6827609b13cf991d8e8efb0c789936167f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 31 Jul 2021 02:37:06 -0300 Subject: gl_rasterizer: Properly scale viewports and scissors --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 47 ++++++++++++------------ 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 615704711..d94f1e89f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -214,8 +214,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { query_cache.UpdateCounters(); - SyncState(); - GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; if (!pipeline) { return; @@ -223,6 +221,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; pipeline->Configure(is_indexed); + SyncState(); + const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology); BeginTransformFeedback(pipeline, primitive_mode); @@ -554,7 +554,6 @@ void RasterizerOpenGL::SyncViewport() { } glFrontFace(mode); } - if (dirty_viewport || flags[Dirty::ClipControl]) { flags[Dirty::ClipControl] = false; @@ -571,6 +570,8 @@ void RasterizerOpenGL::SyncViewport() { state_tracker.ClipControl(origin, depth); state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0); } + const bool is_rescaling{texture_cache.IsRescaling()}; + const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; if (dirty_viewport) { flags[Dirty::Viewports] = false; @@ -579,38 +580,38 @@ void RasterizerOpenGL::SyncViewport() { flags[Dirty::ViewportTransform] = false; flags[VideoCommon::Dirty::RescaleViewports] = false; - const auto& resolution = Settings::values.resolution_info; - const auto scale_up = [&](u32 value) -> u32 { - if (value == 0) { - return 0U; - } - const u32 converted_value = (value * resolution.up_scale) >> resolution.down_shift; - return std::max(converted_value, 1U); - }; - for (std::size_t i = 0; i < Maxwell::NumViewports; ++i) { - if (!force && !flags[Dirty::Viewport0 + i]) { + for (size_t index = 0; index < Maxwell::NumViewports; ++index) { + if (!force && !flags[Dirty::Viewport0 + index]) { continue; } - flags[Dirty::Viewport0 + i] = false; - - const auto& src = regs.viewport_transform[i]; - const Common::Rectangle rect{src.GetRect()}; - glViewportIndexedf(static_cast(i), rect.left, rect.bottom, - scale_up(rect.GetWidth()), scale_up(rect.GetHeight())); + flags[Dirty::Viewport0 + index] = false; + + const auto& src = regs.viewport_transform[index]; + GLfloat x = (src.translate_x - src.scale_x) * scale; + GLfloat y = (src.translate_y - src.scale_y) * scale; + GLfloat width = src.scale_x * 2.0f * scale; + GLfloat height = src.scale_y * 2.0f * scale; + if (height < 0) { + y += height; + height = -height; + } + glViewportIndexedf(static_cast(index), x, y, width != 0.0f ? width : 1.0f, + height != 0.0f ? height : 1.0f); const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z; const GLdouble far_depth = src.translate_z + src.scale_z; if (device.HasDepthBufferFloat()) { - glDepthRangeIndexeddNV(static_cast(i), near_depth, far_depth); + glDepthRangeIndexeddNV(static_cast(index), near_depth, far_depth); } else { - glDepthRangeIndexed(static_cast(i), near_depth, far_depth); + glDepthRangeIndexed(static_cast(index), near_depth, far_depth); } if (!GLAD_GL_NV_viewport_swizzle) { continue; } - glViewportSwizzleNV(static_cast(i), MaxwellToGL::ViewportSwizzle(src.swizzle.x), + glViewportSwizzleNV(static_cast(index), + MaxwellToGL::ViewportSwizzle(src.swizzle.x), MaxwellToGL::ViewportSwizzle(src.swizzle.y), MaxwellToGL::ViewportSwizzle(src.swizzle.z), MaxwellToGL::ViewportSwizzle(src.swizzle.w)); @@ -940,7 +941,7 @@ void RasterizerOpenGL::SyncScissorTest() { const auto& src = regs.scissor_test[index]; if (src.enable) { glEnablei(GL_SCISSOR_TEST, static_cast(index)); - glScissorIndexed(static_cast(index), src.min_x, src.min_y, + glScissorIndexed(static_cast(index), scale_up(src.min_x), scale_up(src.min_y), scale_up(src.max_x - src.min_x), scale_up(src.max_y - src.min_y)); } else { glDisablei(GL_SCISSOR_TEST, static_cast(index)); -- cgit v1.2.3