Просмотр исходного кода

OpenGL: Fix viewport/Scissor scaling on downscaling.

FernandoS27 4 лет назад
Родитель
Сommit
9189aacfe2
1 измененных файлов с 28 добавлено и 6 удалено
  1. 28 6
      src/video_core/renderer_opengl/gl_rasterizer.cpp

+ 28 - 6
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<GLfloat>(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<u32>(converted_value + acumm, 1U);
     };
     for (std::size_t index = 0; index < Maxwell::NumViewports; ++index) {
         if (!force && !flags[Dirty::Scissor0 + index]) {