summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-07-20 19:36:38 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:27 +0100
commit778700ff9d6eca96945deebcd4415e70d58330d9 (patch)
tree413adfbca91e85dd3bdcae718786d2ceba549f81 /src
parentSettings: eliminate rescaling_factor. (diff)
downloadyuzu-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.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp87
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h6
-rw-r--r--src/video_core/texture_cache/texture_cache.h25
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h3
-rw-r--r--src/yuzu/configuration/config.cpp4
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
61VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t index) { 61VkViewport 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
86VkRect2D GetScissorState(const Maxwell& regs, size_t index) { 81VkRect2D 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
541template <class P> 557template <class P>
558bool TextureCache<P>::IsRescaling() {
559 return is_rescaling;
560}
561
562template <class P>
542bool TextureCache<P>::IsRegionGpuModified(VAddr addr, size_t size) { 563bool 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
173private: 175private:
@@ -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