From de66a69ed4b556ad96f38570ea0a31cb2a1870f1 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 21 Jul 2021 00:02:35 -0400 Subject: renderer_gl: Resolution scaling fixes --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 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 a6d9f7c43..b91e7edf8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -577,6 +577,14 @@ void RasterizerOpenGL::SyncViewport() { const bool force = flags[Dirty::ViewportTransform]; flags[Dirty::ViewportTransform] = 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]) { continue; @@ -585,8 +593,8 @@ void RasterizerOpenGL::SyncViewport() { const auto& src = regs.viewport_transform[i]; const Common::Rectangle rect{src.GetRect()}; - glViewportIndexedf(static_cast(i), rect.left, rect.bottom, rect.GetWidth(), - rect.GetHeight()); + glViewportIndexedf(static_cast(i), rect.left, rect.bottom, + scale_up(rect.GetWidth()), scale_up(rect.GetHeight())); const GLdouble reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; const GLdouble near_depth = src.translate_z - src.scale_z * reduce_z; @@ -909,6 +917,15 @@ void RasterizerOpenGL::SyncScissorTest() { flags[Dirty::Scissors] = false; const auto& regs = maxwell3d.regs; + + 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 index = 0; index < Maxwell::NumViewports; ++index) { if (!flags[Dirty::Scissor0 + index]) { continue; @@ -919,7 +936,7 @@ void RasterizerOpenGL::SyncScissorTest() { 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); + 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 From 9bc7b04ca587a349a9fc865d05e30966d6a84d65 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Thu, 29 Jul 2021 14:19:51 -0400 Subject: gl_rasterizer: Fix rescale dirty state checking --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 13 +++++++++---- 1 file changed, 9 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 b91e7edf8..615704711 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -533,7 +533,8 @@ void RasterizerOpenGL::SyncViewport() { auto& flags = maxwell3d.dirty.flags; const auto& regs = maxwell3d.regs; - const bool dirty_viewport = flags[Dirty::Viewports]; + const bool rescale_viewports = flags[VideoCommon::Dirty::RescaleViewports]; + const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports; const bool dirty_clip_control = flags[Dirty::ClipControl]; if (dirty_clip_control || flags[Dirty::FrontFace]) { @@ -574,8 +575,9 @@ void RasterizerOpenGL::SyncViewport() { if (dirty_viewport) { flags[Dirty::Viewports] = false; - const bool force = flags[Dirty::ViewportTransform]; + const bool force = flags[Dirty::ViewportTransform] || rescale_viewports; flags[Dirty::ViewportTransform] = false; + flags[VideoCommon::Dirty::RescaleViewports] = false; const auto& resolution = Settings::values.resolution_info; const auto scale_up = [&](u32 value) -> u32 { @@ -911,11 +913,14 @@ void RasterizerOpenGL::SyncLogicOpState() { void RasterizerOpenGL::SyncScissorTest() { auto& flags = maxwell3d.dirty.flags; - if (!flags[Dirty::Scissors]) { + if (!flags[Dirty::Scissors] && !flags[VideoCommon::Dirty::RescaleScissors]) { return; } flags[Dirty::Scissors] = false; + const bool force = flags[VideoCommon::Dirty::RescaleScissors]; + flags[VideoCommon::Dirty::RescaleScissors] = false; + const auto& regs = maxwell3d.regs; const auto& resolution = Settings::values.resolution_info; @@ -927,7 +932,7 @@ void RasterizerOpenGL::SyncScissorTest() { return std::max(converted_value, 1U); }; for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { - if (!flags[Dirty::Scissor0 + index]) { + if (!force && !flags[Dirty::Scissor0 + index]) { continue; } flags[Dirty::Scissor0 + index] = false; -- cgit v1.2.3 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/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 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 From 31478c6c1b841b9a820742830b136775fafe270f Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 6 Oct 2021 01:18:00 -0400 Subject: video_core: Misc resolution scaling related refactoring --- 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 d94f1e89f..bb24a0656 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -554,7 +554,7 @@ void RasterizerOpenGL::SyncViewport() { } glFrontFace(mode); } - if (dirty_viewport || flags[Dirty::ClipControl]) { + if (dirty_viewport || dirty_clip_control) { flags[Dirty::ClipControl] = false; bool flip_y = false; @@ -925,7 +925,7 @@ void RasterizerOpenGL::SyncScissorTest() { const auto& regs = maxwell3d.regs; const auto& resolution = Settings::values.resolution_info; - const auto scale_up = [&](u32 value) -> u32 { + const auto scale_up = [resolution](u32 value) -> u32 { if (value == 0) { return 0U; } -- cgit v1.2.3 From 93c9eb196f4444495f50220c3e6b89d2f0b582db Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Fri, 22 Oct 2021 22:59:30 -0400 Subject: gl_rasterizer: Fix ScissorTest and Clear when scaling --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 16 ++++++---------- 1 file changed, 6 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 bb24a0656..4df8a684a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -184,6 +184,9 @@ void RasterizerOpenGL::Clear() { SyncRasterizeEnable(); SyncStencilTestState(); + std::scoped_lock lock{texture_cache.mutex}; + texture_cache.UpdateRenderTargets(true); + state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); if (regs.clear_flags.scissor) { SyncScissorTest(); } else { @@ -192,10 +195,6 @@ void RasterizerOpenGL::Clear() { } UNIMPLEMENTED_IF(regs.clear_flags.viewport); - std::scoped_lock lock{texture_cache.mutex}; - texture_cache.UpdateRenderTargets(true); - state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); - if (use_color) { glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); } @@ -925,12 +924,9 @@ void RasterizerOpenGL::SyncScissorTest() { const auto& regs = maxwell3d.regs; const auto& resolution = Settings::values.resolution_info; - const auto scale_up = [resolution](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); + const bool is_rescaling{texture_cache.IsRescaling()}; + const auto scale_up = [resolution, is_rescaling](u32 value) { + return is_rescaling ? resolution.ScaleUp(value) : value; }; for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { if (!force && !flags[Dirty::Scissor0 + index]) { -- cgit v1.2.3 From 9189aacfe28d0114fbfff0e3f89e8912f5377454 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Sat, 23 Oct 2021 15:57:05 +0200 Subject: OpenGL: Fix viewport/Scissor scaling on downscaling. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 34 +++++++++++++++++++----- 1 file changed, 28 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 4df8a684a..d8ac46d2a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -187,6 +187,7 @@ void RasterizerOpenGL::Clear() { std::scoped_lock lock{texture_cache.mutex}; texture_cache.UpdateRenderTargets(true); state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); + SyncViewport(); if (regs.clear_flags.scissor) { SyncScissorTest(); } else { @@ -571,6 +572,15 @@ void RasterizerOpenGL::SyncViewport() { } const bool is_rescaling{texture_cache.IsRescaling()}; const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; + const auto conv = [scale](float value) -> GLfloat { + float new_value = value * scale; + if (scale < 1.0f) { + const bool sign = std::signbit(value); + new_value = std::round(std::abs(new_value)); + new_value = sign ? -new_value : new_value; + } + return static_cast(new_value); + }; if (dirty_viewport) { flags[Dirty::Viewports] = false; @@ -586,10 +596,11 @@ void RasterizerOpenGL::SyncViewport() { 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; + GLfloat x = conv(src.translate_x - src.scale_x); + GLfloat y = conv(src.translate_y - src.scale_y); + GLfloat width = conv(src.scale_x * 2.0f); + GLfloat height = conv(src.scale_y * 2.0f); + if (height < 0) { y += height; height = -height; @@ -925,8 +936,19 @@ void RasterizerOpenGL::SyncScissorTest() { const auto& resolution = Settings::values.resolution_info; const bool is_rescaling{texture_cache.IsRescaling()}; - const auto scale_up = [resolution, is_rescaling](u32 value) { - return is_rescaling ? resolution.ScaleUp(value) : value; + const u32 up_scale = is_rescaling ? resolution.up_scale : 1U; + const u32 down_shift = is_rescaling ? resolution.down_shift : 0U; + const auto scale_up = [up_scale, down_shift](u32 value) -> u32 { + if (value == 0) { + return 0U; + } + const u32 upset = value * up_scale; + u32 acumm{}; + if ((up_scale >> down_shift) == 0) { + acumm = upset % 2; + } + const u32 converted_value = upset >> down_shift; + return std::max(converted_value + acumm, 1U); }; for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) { if (!force && !flags[Dirty::Scissor0 + index]) { -- cgit v1.2.3 From de1c8c5c2c3131bb122351e676014cdc7c442e78 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Fri, 29 Oct 2021 17:02:57 +0200 Subject: Texture Cahe/Shader decompiler: Resize PointSize on rescaling, refactor and make reaper more agressive on 4Gb GPUs. --- src/video_core/renderer_opengl/gl_rasterizer.cpp | 5 +++-- 1 file changed, 3 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 d8ac46d2a..9b516c64f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -976,8 +976,9 @@ void RasterizerOpenGL::SyncPointState() { oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable); oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d.regs.vp_point_size.enable); - - glPointSize(std::max(1.0f, maxwell3d.regs.point_size)); + const bool is_rescaling{texture_cache.IsRescaling()}; + const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; + glPointSize(std::max(1.0f, maxwell3d.regs.point_size * scale)); } void RasterizerOpenGL::SyncLineState() { -- cgit v1.2.3