From bc893d361dfc6801062b409eb8fd16a22d00495c Mon Sep 17 00:00:00 2001 From: Shinmegumi Date: Thu, 21 Aug 2025 21:38:40 +0200 Subject: [PATCH] [vk] Apply fallback patch for Viewport Will add details if this solves the issue we are testing for. --- .../renderer_vulkan/vk_rasterizer.cpp | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 70ca9583f9..c33f15e710 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1032,10 +1032,18 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg return; } if (!regs.viewport_scale_offset_enabled) { - const auto x = static_cast(regs.surface_clip.x); - const auto y = static_cast(regs.surface_clip.y); - const auto width = static_cast(regs.surface_clip.width); - const auto height = static_cast(regs.surface_clip.height); + float x = static_cast(regs.surface_clip.x); + float y = static_cast(regs.surface_clip.y); + float width = static_cast(regs.surface_clip.width); + float height = static_cast(regs.surface_clip.height); + + const bool lower_left = + regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft; + if (lower_left) { + // Vulkan viewport space is top-left; emulate lower-left with negative height. + y += height; + height = -height; + } VkViewport viewport{ .x = x, .y = y, @@ -1071,15 +1079,20 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs return; } if (!regs.viewport_scale_offset_enabled) { - const auto x = static_cast(regs.surface_clip.x); - const auto y = static_cast(regs.surface_clip.y); - const auto width = static_cast(regs.surface_clip.width); - const auto height = static_cast(regs.surface_clip.height); - VkRect2D scissor; - scissor.offset.x = static_cast(x); - scissor.offset.y = static_cast(y); - scissor.extent.width = static_cast(width != 0.0f ? width : 1.0f); - scissor.extent.height = static_cast(height != 0.0f ? height : 1.0f); + u32 x = regs.surface_clip.x; + u32 y = regs.surface_clip.y; + u32 width = regs.surface_clip.width ? regs.surface_clip.width : 1u; + u32 height = regs.surface_clip.height ? regs.surface_clip.height : 1u; + + if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) { + // Vulkan scissor is top-left; convert from lower-left coordinates. + y = regs.surface_clip.height - (y + height); + } + VkRect2D scissor{}; + scissor.offset.x = static_cast(x); + scissor.offset.y = static_cast(y); + scissor.extent.width = width; + scissor.extent.height = height; scheduler.Record([scissor](vk::CommandBuffer cmdbuf) { cmdbuf.SetScissor(0, scissor); }); return; } @@ -1589,7 +1602,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) highest_dirty_attr = index; } } - for (size_t index = 0; index < highest_dirty_attr; ++index) { + for (size_t index = 0; index <= highest_dirty_attr; ++index) { const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]}; const u32 binding{attribute.buffer}; dirty[Dirty::VertexAttribute0 + index] = false;