diff options
| author | 2021-07-20 19:36:38 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:27 +0100 | |
| commit | 778700ff9d6eca96945deebcd4415e70d58330d9 (patch) | |
| tree | 413adfbca91e85dd3bdcae718786d2ceba549f81 /src | |
| parent | Settings: eliminate rescaling_factor. (diff) | |
| download | yuzu-778700ff9d6eca96945deebcd4415e70d58330d9.tar.gz yuzu-778700ff9d6eca96945deebcd4415e70d58330d9.tar.xz yuzu-778700ff9d6eca96945deebcd4415e70d58330d9.zip | |
TextureCache: Modify Viewports/Scissors according to Rescale.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/dirty_flags.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 87 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_state_tracker.h | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 25 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 3 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 4 |
6 files changed, 93 insertions, 35 deletions
diff --git a/src/video_core/dirty_flags.h b/src/video_core/dirty_flags.h index f11ff5d94..d63ad5a35 100644 --- a/src/video_core/dirty_flags.h +++ b/src/video_core/dirty_flags.h | |||
| @@ -29,7 +29,8 @@ enum : u8 { | |||
| 29 | ColorBuffer6, | 29 | ColorBuffer6, |
| 30 | ColorBuffer7, | 30 | ColorBuffer7, |
| 31 | ZetaBuffer, | 31 | ZetaBuffer, |
| 32 | Rescale, | 32 | RescaleViewports, |
| 33 | RescaleScissors, | ||
| 33 | 34 | ||
| 34 | VertexBuffers, | 35 | VertexBuffers, |
| 35 | VertexBuffer0, | 36 | VertexBuffer0, |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 30b47a7a0..7a7374b78 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -58,19 +58,14 @@ struct DrawParams { | |||
| 58 | bool is_indexed; | 58 | bool is_indexed; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index) { | 61 | VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index, float scale) { |
| 62 | const auto& src = regs.viewport_transform[index]; | 62 | const auto& src = regs.viewport_transform[index]; |
| 63 | const float width = src.scale_x * 2.0f; | 63 | const float width = src.scale_x * 2.0f * scale; |
| 64 | float y = src.translate_y - src.scale_y; | 64 | const float height = src.scale_y * 2.0f * scale; |
| 65 | float height = src.scale_y * 2.0f; | ||
| 66 | if (regs.screen_y_control.y_negate) { | ||
| 67 | y += height; | ||
| 68 | height = -height; | ||
| 69 | } | ||
| 70 | const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f; | 65 | const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f; |
| 71 | VkViewport viewport{ | 66 | VkViewport viewport{ |
| 72 | .x = src.translate_x - src.scale_x, | 67 | .x = (src.translate_x - src.scale_x) * scale, |
| 73 | .y = y, | 68 | .y = (src.translate_y - src.scale_y) * scale, |
| 74 | .width = width != 0.0f ? width : 1.0f, | 69 | .width = width != 0.0f ? width : 1.0f, |
| 75 | .height = height != 0.0f ? height : 1.0f, | 70 | .height = height != 0.0f ? height : 1.0f, |
| 76 | .minDepth = src.translate_z - src.scale_z * reduce_z, | 71 | .minDepth = src.translate_z - src.scale_z * reduce_z, |
| @@ -83,14 +78,21 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in | |||
| 83 | return viewport; | 78 | return viewport; |
| 84 | } | 79 | } |
| 85 | 80 | ||
| 86 | VkRect2D GetScissorState(const Maxwell& regs, size_t index) { | 81 | VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) { |
| 87 | const auto& src = regs.scissor_test[index]; | 82 | const auto& src = regs.scissor_test[index]; |
| 88 | VkRect2D scissor; | 83 | VkRect2D scissor; |
| 84 | const auto scale_up = [&](u32 value) -> u32 { | ||
| 85 | if (value == 0) { | ||
| 86 | return 0U; | ||
| 87 | } | ||
| 88 | const u32 converted_value = (value * up_scale) >> down_shift; | ||
| 89 | return std::max<u32>(converted_value, 1U); | ||
| 90 | }; | ||
| 89 | if (src.enable) { | 91 | if (src.enable) { |
| 90 | scissor.offset.x = static_cast<s32>(src.min_x); | 92 | scissor.offset.x = static_cast<s32>(scale_up(src.min_x)); |
| 91 | scissor.offset.y = static_cast<s32>(src.min_y); | 93 | scissor.offset.y = static_cast<s32>(scale_up(src.min_y)); |
| 92 | scissor.extent.width = src.max_x - src.min_x; | 94 | scissor.extent.width = scale_up(src.max_x - src.min_x); |
| 93 | scissor.extent.height = src.max_y - src.min_y; | 95 | scissor.extent.height = scale_up(src.max_y - src.min_y); |
| 94 | } else { | 96 | } else { |
| 95 | scissor.offset.x = 0; | 97 | scissor.offset.x = 0; |
| 96 | scissor.offset.y = 0; | 98 | scissor.offset.y = 0; |
| @@ -214,8 +216,15 @@ void RasterizerVulkan::Clear() { | |||
| 214 | const VkExtent2D render_area = framebuffer->RenderArea(); | 216 | const VkExtent2D render_area = framebuffer->RenderArea(); |
| 215 | scheduler.RequestRenderpass(framebuffer); | 217 | scheduler.RequestRenderpass(framebuffer); |
| 216 | 218 | ||
| 219 | u32 up_scale = 1; | ||
| 220 | u32 down_shift = 0; | ||
| 221 | if (texture_cache.IsRescaling()) { | ||
| 222 | up_scale = Settings::values.resolution_info.up_scale; | ||
| 223 | down_shift = Settings::values.resolution_info.down_shift; | ||
| 224 | } | ||
| 225 | |||
| 217 | VkClearRect clear_rect{ | 226 | VkClearRect clear_rect{ |
| 218 | .rect = GetScissorState(regs, 0), | 227 | .rect = GetScissorState(regs, 0, up_scale, down_shift), |
| 219 | .baseArrayLayer = regs.clear_buffers.layer, | 228 | .baseArrayLayer = regs.clear_buffers.layer, |
| 220 | .layerCount = 1, | 229 | .layerCount = 1, |
| 221 | }; | 230 | }; |
| @@ -595,15 +604,17 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg | |||
| 595 | if (!state_tracker.TouchViewports()) { | 604 | if (!state_tracker.TouchViewports()) { |
| 596 | return; | 605 | return; |
| 597 | } | 606 | } |
| 607 | const float scale = | ||
| 608 | texture_cache.IsRescaling() ? Settings::values.resolution_info.up_factor : 1.0f; | ||
| 598 | const std::array viewports{ | 609 | const std::array viewports{ |
| 599 | GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), | 610 | GetViewportState(device, regs, 0, scale), GetViewportState(device, regs, 1, scale), |
| 600 | GetViewportState(device, regs, 2), GetViewportState(device, regs, 3), | 611 | GetViewportState(device, regs, 2, scale), GetViewportState(device, regs, 3, scale), |
| 601 | GetViewportState(device, regs, 4), GetViewportState(device, regs, 5), | 612 | GetViewportState(device, regs, 4, scale), GetViewportState(device, regs, 5, scale), |
| 602 | GetViewportState(device, regs, 6), GetViewportState(device, regs, 7), | 613 | GetViewportState(device, regs, 6, scale), GetViewportState(device, regs, 7, scale), |
| 603 | GetViewportState(device, regs, 8), GetViewportState(device, regs, 9), | 614 | GetViewportState(device, regs, 8, scale), GetViewportState(device, regs, 9, scale), |
| 604 | GetViewportState(device, regs, 10), GetViewportState(device, regs, 11), | 615 | GetViewportState(device, regs, 10, scale), GetViewportState(device, regs, 11, scale), |
| 605 | GetViewportState(device, regs, 12), GetViewportState(device, regs, 13), | 616 | GetViewportState(device, regs, 12, scale), GetViewportState(device, regs, 13, scale), |
| 606 | GetViewportState(device, regs, 14), GetViewportState(device, regs, 15), | 617 | GetViewportState(device, regs, 14, scale), GetViewportState(device, regs, 15, scale), |
| 607 | }; | 618 | }; |
| 608 | scheduler.Record([viewports](vk::CommandBuffer cmdbuf) { cmdbuf.SetViewport(0, viewports); }); | 619 | scheduler.Record([viewports](vk::CommandBuffer cmdbuf) { cmdbuf.SetViewport(0, viewports); }); |
| 609 | } | 620 | } |
| @@ -612,13 +623,29 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs | |||
| 612 | if (!state_tracker.TouchScissors()) { | 623 | if (!state_tracker.TouchScissors()) { |
| 613 | return; | 624 | return; |
| 614 | } | 625 | } |
| 626 | u32 up_scale = 1; | ||
| 627 | u32 down_shift = 0; | ||
| 628 | if (texture_cache.IsRescaling()) { | ||
| 629 | up_scale = Settings::values.resolution_info.up_scale; | ||
| 630 | down_shift = Settings::values.resolution_info.down_shift; | ||
| 631 | } | ||
| 615 | const std::array scissors{ | 632 | const std::array scissors{ |
| 616 | GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), | 633 | GetScissorState(regs, 0, up_scale, down_shift), |
| 617 | GetScissorState(regs, 3), GetScissorState(regs, 4), GetScissorState(regs, 5), | 634 | GetScissorState(regs, 1, up_scale, down_shift), |
| 618 | GetScissorState(regs, 6), GetScissorState(regs, 7), GetScissorState(regs, 8), | 635 | GetScissorState(regs, 2, up_scale, down_shift), |
| 619 | GetScissorState(regs, 9), GetScissorState(regs, 10), GetScissorState(regs, 11), | 636 | GetScissorState(regs, 3, up_scale, down_shift), |
| 620 | GetScissorState(regs, 12), GetScissorState(regs, 13), GetScissorState(regs, 14), | 637 | GetScissorState(regs, 4, up_scale, down_shift), |
| 621 | GetScissorState(regs, 15), | 638 | GetScissorState(regs, 5, up_scale, down_shift), |
| 639 | GetScissorState(regs, 6, up_scale, down_shift), | ||
| 640 | GetScissorState(regs, 7, up_scale, down_shift), | ||
| 641 | GetScissorState(regs, 8, up_scale, down_shift), | ||
| 642 | GetScissorState(regs, 9, up_scale, down_shift), | ||
| 643 | GetScissorState(regs, 10, up_scale, down_shift), | ||
| 644 | GetScissorState(regs, 11, up_scale, down_shift), | ||
| 645 | GetScissorState(regs, 12, up_scale, down_shift), | ||
| 646 | GetScissorState(regs, 13, up_scale, down_shift), | ||
| 647 | GetScissorState(regs, 14, up_scale, down_shift), | ||
| 648 | GetScissorState(regs, 15, up_scale, down_shift), | ||
| 622 | }; | 649 | }; |
| 623 | scheduler.Record([scissors](vk::CommandBuffer cmdbuf) { cmdbuf.SetScissor(0, scissors); }); | 650 | scheduler.Record([scissors](vk::CommandBuffer cmdbuf) { cmdbuf.SetScissor(0, scissors); }); |
| 624 | } | 651 | } |
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h index 2f2d6b31f..ac2bbebe0 100644 --- a/src/video_core/renderer_vulkan/vk_state_tracker.h +++ b/src/video_core/renderer_vulkan/vk_state_tracker.h | |||
| @@ -71,11 +71,13 @@ public: | |||
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | bool TouchViewports() { | 73 | bool TouchViewports() { |
| 74 | return Exchange(Dirty::Viewports, false); | 74 | return Exchange(Dirty::Viewports, false) || |
| 75 | Exchange(VideoCommon::Dirty::RescaleViewports, false); | ||
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | bool TouchScissors() { | 78 | bool TouchScissors() { |
| 78 | return Exchange(Dirty::Scissors, false); | 79 | return Exchange(Dirty::Scissors, false) || |
| 80 | Exchange(VideoCommon::Dirty::RescaleScissors, false); | ||
| 79 | } | 81 | } |
| 80 | 82 | ||
| 81 | bool TouchDepthBias() { | 83 | bool TouchDepthBias() { |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index b7d1ae92d..4e5031acc 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <unordered_set> | 7 | #include <unordered_set> |
| 8 | 8 | ||
| 9 | #include "common/alignment.h" | 9 | #include "common/alignment.h" |
| 10 | #include "common/settings.h" | ||
| 10 | #include "video_core/dirty_flags.h" | 11 | #include "video_core/dirty_flags.h" |
| 11 | #include "video_core/engines/kepler_compute.h" | 12 | #include "video_core/engines/kepler_compute.h" |
| 12 | #include "video_core/texture_cache/image_view_base.h" | 13 | #include "video_core/texture_cache/image_view_base.h" |
| @@ -205,6 +206,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 205 | return; | 206 | return; |
| 206 | } | 207 | } |
| 207 | 208 | ||
| 209 | bool rescaled; | ||
| 208 | do { | 210 | do { |
| 209 | flags[Dirty::RenderTargets] = false; | 211 | flags[Dirty::RenderTargets] = false; |
| 210 | 212 | ||
| @@ -243,6 +245,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 243 | check_rescale(render_targets.depth_buffer_id, tmp_depth_image); | 245 | check_rescale(render_targets.depth_buffer_id, tmp_depth_image); |
| 244 | 246 | ||
| 245 | if (can_rescale) { | 247 | if (can_rescale) { |
| 248 | rescaled = true; | ||
| 246 | const auto scale_up = [this](ImageId image_id) { | 249 | const auto scale_up = [this](ImageId image_id) { |
| 247 | if (image_id != CORRUPT_ID) { | 250 | if (image_id != CORRUPT_ID) { |
| 248 | Image& image = slot_images[image_id]; | 251 | Image& image = slot_images[image_id]; |
| @@ -254,6 +257,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 254 | } | 257 | } |
| 255 | scale_up(tmp_depth_image); | 258 | scale_up(tmp_depth_image); |
| 256 | } else { | 259 | } else { |
| 260 | rescaled = false; | ||
| 257 | const auto scale_down = [this](ImageId image_id) { | 261 | const auto scale_down = [this](ImageId image_id) { |
| 258 | if (image_id != CORRUPT_ID) { | 262 | if (image_id != CORRUPT_ID) { |
| 259 | Image& image = slot_images[image_id]; | 263 | Image& image = slot_images[image_id]; |
| @@ -268,6 +272,12 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 268 | } while (has_deleted_images); | 272 | } while (has_deleted_images); |
| 269 | // Rescale End | 273 | // Rescale End |
| 270 | 274 | ||
| 275 | if (is_rescaling != rescaled) { | ||
| 276 | flags[Dirty::RescaleViewports] = true; | ||
| 277 | flags[Dirty::RescaleScissors] = true; | ||
| 278 | is_rescaling = rescaled; | ||
| 279 | } | ||
| 280 | |||
| 271 | for (size_t index = 0; index < NUM_RT; ++index) { | 281 | for (size_t index = 0; index < NUM_RT; ++index) { |
| 272 | ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; | 282 | ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; |
| 273 | PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id)); | 283 | PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id)); |
| @@ -279,9 +289,15 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||
| 279 | for (size_t index = 0; index < NUM_RT; ++index) { | 289 | for (size_t index = 0; index < NUM_RT; ++index) { |
| 280 | render_targets.draw_buffers[index] = static_cast<u8>(maxwell3d.regs.rt_control.Map(index)); | 290 | render_targets.draw_buffers[index] = static_cast<u8>(maxwell3d.regs.rt_control.Map(index)); |
| 281 | } | 291 | } |
| 292 | u32 up_scale = 1; | ||
| 293 | u32 down_shift = 0; | ||
| 294 | if (is_rescaling) { | ||
| 295 | up_scale = Settings::values.resolution_info.up_scale; | ||
| 296 | down_shift = Settings::values.resolution_info.down_shift; | ||
| 297 | } | ||
| 282 | render_targets.size = Extent2D{ | 298 | render_targets.size = Extent2D{ |
| 283 | maxwell3d.regs.render_area.width, | 299 | (maxwell3d.regs.render_area.width * up_scale) >> down_shift, |
| 284 | maxwell3d.regs.render_area.height, | 300 | (maxwell3d.regs.render_area.height * up_scale) >> down_shift, |
| 285 | }; | 301 | }; |
| 286 | 302 | ||
| 287 | flags[Dirty::DepthBiasGlobal] = true; | 303 | flags[Dirty::DepthBiasGlobal] = true; |
| @@ -539,6 +555,11 @@ void TextureCache<P>::PopAsyncFlushes() { | |||
| 539 | } | 555 | } |
| 540 | 556 | ||
| 541 | template <class P> | 557 | template <class P> |
| 558 | bool TextureCache<P>::IsRescaling() { | ||
| 559 | return is_rescaling; | ||
| 560 | } | ||
| 561 | |||
| 562 | template <class P> | ||
| 542 | bool TextureCache<P>::IsRegionGpuModified(VAddr addr, size_t size) { | 563 | bool TextureCache<P>::IsRegionGpuModified(VAddr addr, size_t size) { |
| 543 | bool is_modified = false; | 564 | bool is_modified = false; |
| 544 | ForEachImageInRegion(addr, size, [&is_modified](ImageId, ImageBase& image) { | 565 | ForEachImageInRegion(addr, size, [&is_modified](ImageId, ImageBase& image) { |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index cdd99242b..1f51fcee8 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -168,6 +168,8 @@ public: | |||
| 168 | /// Return true when a CPU region is modified from the GPU | 168 | /// Return true when a CPU region is modified from the GPU |
| 169 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); | 169 | [[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size); |
| 170 | 170 | ||
| 171 | [[nodiscard]] bool IsRescaling(); | ||
| 172 | |||
| 171 | std::mutex mutex; | 173 | std::mutex mutex; |
| 172 | 174 | ||
| 173 | private: | 175 | private: |
| @@ -362,6 +364,7 @@ private: | |||
| 362 | VAddr virtual_invalid_space{}; | 364 | VAddr virtual_invalid_space{}; |
| 363 | 365 | ||
| 364 | bool has_deleted_images = false; | 366 | bool has_deleted_images = false; |
| 367 | bool is_rescaling = false; | ||
| 365 | u64 total_used_memory = 0; | 368 | u64 total_used_memory = 0; |
| 366 | u64 minimum_memory; | 369 | u64 minimum_memory; |
| 367 | u64 expected_memory; | 370 | u64 expected_memory; |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 7ddc40b00..7ed833203 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -849,6 +849,8 @@ void Config::ReadRendererValues() { | |||
| 849 | ReadBasicSetting(Settings::values.disable_shader_loop_safety_checks); | 849 | ReadBasicSetting(Settings::values.disable_shader_loop_safety_checks); |
| 850 | } | 850 | } |
| 851 | 851 | ||
| 852 | Settings::UpdateRescalingInfo(); | ||
| 853 | |||
| 852 | qt_config->endGroup(); | 854 | qt_config->endGroup(); |
| 853 | } | 855 | } |
| 854 | 856 | ||
| @@ -1402,6 +1404,8 @@ void Config::SaveRendererValues() { | |||
| 1402 | WriteBasicSetting(Settings::values.disable_shader_loop_safety_checks); | 1404 | WriteBasicSetting(Settings::values.disable_shader_loop_safety_checks); |
| 1403 | } | 1405 | } |
| 1404 | 1406 | ||
| 1407 | Settings::UpdateRescalingInfo(); | ||
| 1408 | |||
| 1405 | qt_config->endGroup(); | 1409 | qt_config->endGroup(); |
| 1406 | } | 1410 | } |
| 1407 | 1411 | ||