From bd80d603e2d330d8d60f9175294c1fcc6fba179c Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 13 Mar 2026 01:55:02 -0400 Subject: [PATCH 1/2] [vulkan] Corrected mishandling of render area + rescaling logic by using wrongly push constants --- src/shader_recompiler/backend/spirv/emit_spirv.h | 4 ++-- src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 6bb8596925..06c72fc494 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project @@ -31,7 +31,7 @@ struct RenderAreaLayout { }; constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescaling_textures); constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor); -constexpr u32 RENDERAREA_LAYOUT_OFFSET = offsetof(RenderAreaLayout, render_area); +constexpr u32 RENDERAREA_LAYOUT_OFFSET = sizeof(RescalingLayout); [[nodiscard]] std::vector EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings, bool optimize); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index ffa9aa7e1a..aaa278ccd2 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -1096,7 +1096,8 @@ void EmitContext::DefineRenderArea(const Info& info) { Decorate(push_constant_struct, spv::Decoration::Block); Name(push_constant_struct, "RenderAreaInfo"); - MemberDecorate(push_constant_struct, render_are_member_index, spv::Decoration::Offset, 0); + MemberDecorate(push_constant_struct, render_are_member_index, spv::Decoration::Offset, + RENDERAREA_LAYOUT_OFFSET); MemberName(push_constant_struct, render_are_member_index, "render_area"); const Id pointer_type{TypePointer(spv::StorageClass::PushConstant, push_constant_struct)}; From 1ebdef1a0257b925794d156f5bb56d34bd5722e5 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 13 Mar 2026 02:54:14 -0400 Subject: [PATCH 2/2] [vulkan] Adjusting how surface clip is working when viewport offset gets a scaling value --- .../renderer_vulkan/vk_graphics_pipeline.cpp | 11 +++++++++-- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 13 +++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 9a4e7cfeb9..f18504e592 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -510,8 +510,15 @@ bool GraphicsPipeline::ConfigureImpl(bool is_indexed) { const auto& info{stage_infos[stage]}; if (info.uses_render_area) { render_area.uses_render_area = true; - render_area.words = {static_cast(regs.surface_clip.width), - static_cast(regs.surface_clip.height)}; + const bool is_rescaling{texture_cache.IsRescaling()}; + const auto& resolution = Settings::values.resolution_info; + const float render_area_width = static_cast( + is_rescaling ? resolution.ScaleUp(static_cast(regs.surface_clip.width)) + : static_cast(regs.surface_clip.width)); + const float render_area_height = static_cast( + is_rescaling ? resolution.ScaleUp(static_cast(regs.surface_clip.height)) + : static_cast(regs.surface_clip.height)); + render_area.words = {render_area_width, render_area_height}; } }}; if constexpr (Spec::enabled_stages[0]) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 71d68c227b..a304618088 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1572,10 +1572,16 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg return; } if (!regs.viewport_scale_offset_enabled) { + const bool is_rescaling{texture_cache.IsRescaling()}; + const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; float x = static_cast(regs.surface_clip.x); float y = static_cast(regs.surface_clip.y); float width = (std::max)(1.0f, static_cast(regs.surface_clip.width)); float height = (std::max)(1.0f, static_cast(regs.surface_clip.height)); + x *= scale; + y *= scale; + width *= scale; + height *= scale; if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) { y += height; height = -height; @@ -1639,6 +1645,13 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs if (regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft) { y = regs.surface_clip.height - (y + height); } + if (texture_cache.IsRescaling()) { + const auto& resolution = Settings::values.resolution_info; + x = resolution.ScaleUp(x); + y = resolution.ScaleUp(y); + width = resolution.ScaleUp(width); + height = resolution.ScaleUp(height); + } VkRect2D scissor{}; scissor.offset.x = static_cast(x); scissor.offset.y = static_cast(y);