summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar FernandoS272021-10-20 18:27:25 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:31 +0100
commitd37d10e7a7b9037a259b27923716e5ce3084d6c3 (patch)
tree52ee8db37b4eefed3bd24e36bfe7ca7319fc51f5
parentPresentation: Fix turning FSR on and off in settings (diff)
downloadyuzu-d37d10e7a7b9037a259b27923716e5ce3084d6c3.tar.gz
yuzu-d37d10e7a7b9037a259b27923716e5ce3084d6c3.tar.xz
yuzu-d37d10e7a7b9037a259b27923716e5ce3084d6c3.zip
TextureCache: fix rescaling in aliases and overlap joins.
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp19
-rw-r--r--src/video_core/texture_cache/texture_cache.h41
-rw-r--r--src/video_core/texture_cache/util.cpp8
-rw-r--r--src/video_core/texture_cache/util.h3
4 files changed, 48 insertions, 23 deletions
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 5ca67c413..fd334a146 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -63,7 +63,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
63 const auto conv = [scale](float value) { 63 const auto conv = [scale](float value) {
64 float new_value = value * scale; 64 float new_value = value * scale;
65 if (scale < 1.0f) { 65 if (scale < 1.0f) {
66 bool sign = std::signbit(new_value); 66 const bool sign = std::signbit(value);
67 new_value = std::round(std::abs(new_value)); 67 new_value = std::round(std::abs(new_value));
68 new_value = sign ? -new_value : new_value; 68 new_value = sign ? -new_value : new_value;
69 } 69 }
@@ -96,21 +96,22 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
96VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) { 96VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) {
97 const auto& src = regs.scissor_test[index]; 97 const auto& src = regs.scissor_test[index];
98 VkRect2D scissor; 98 VkRect2D scissor;
99 const auto scale_up = [&](u32 value) -> u32 { 99 const auto scale_up = [&](s32 value) -> s32 {
100 if (value == 0) { 100 if (value == 0) {
101 return 0U; 101 return 0U;
102 } 102 }
103 const u32 upset = value * up_scale; 103 const s32 upset = value * up_scale;
104 u32 acumm = 0; 104 s32 acumm = 0;
105 if ((up_scale >> down_shift) == 0) { 105 if ((up_scale >> down_shift) == 0) {
106 acumm = upset & 0x1; 106 acumm = upset % 2;
107 } 107 }
108 const u32 converted_value = (value * up_scale) >> down_shift; 108 const s32 converted_value = (value * up_scale) >> down_shift;
109 return std::max<u32>(converted_value + acumm, 1U); 109 return value < 0 ? std::min<s32>(converted_value - acumm, -1)
110 : std::max<s32>(converted_value + acumm, 1);
110 }; 111 };
111 if (src.enable) { 112 if (src.enable) {
112 scissor.offset.x = static_cast<s32>(scale_up(src.min_x)); 113 scissor.offset.x = scale_up(static_cast<s32>(src.min_x));
113 scissor.offset.y = static_cast<s32>(scale_up(src.min_y)); 114 scissor.offset.y = scale_up(static_cast<s32>(src.min_y));
114 scissor.extent.width = scale_up(src.max_x - src.min_x); 115 scissor.extent.width = scale_up(src.max_x - src.min_x);
115 scissor.extent.height = scale_up(src.max_y - src.min_y); 116 scissor.extent.height = scale_up(src.max_y - src.min_y);
116 } else { 117 } else {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 13914dc8b..a32c11d04 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1037,8 +1037,11 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
1037 if (overlap.info.num_samples != new_image.info.num_samples) { 1037 if (overlap.info.num_samples != new_image.info.num_samples) {
1038 LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented"); 1038 LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented");
1039 } else { 1039 } else {
1040 const auto& resolution = Settings::values.resolution_info;
1040 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); 1041 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
1041 auto copies = MakeShrinkImageCopies(new_info, overlap.info, base); 1042 const u32 up_scale = can_rescale ? resolution.up_scale : 1;
1043 const u32 down_shift = can_rescale ? resolution.down_shift : 0;
1044 auto copies = MakeShrinkImageCopies(new_info, overlap.info, base, up_scale, down_shift);
1042 runtime.CopyImage(new_image, overlap, std::move(copies)); 1045 runtime.CopyImage(new_image, overlap, std::move(copies));
1043 } 1046 }
1044 if (True(overlap.flags & ImageFlagBits::Tracked)) { 1047 if (True(overlap.flags & ImageFlagBits::Tracked)) {
@@ -1659,19 +1662,35 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
1659 const ImageBase& rhs_image = slot_images[rhs->id]; 1662 const ImageBase& rhs_image = slot_images[rhs->id];
1660 return lhs_image.modification_tick < rhs_image.modification_tick; 1663 return lhs_image.modification_tick < rhs_image.modification_tick;
1661 }); 1664 });
1665 const auto& resolution = Settings::values.resolution_info;
1662 for (const AliasedImage* const aliased : aliased_images) { 1666 for (const AliasedImage* const aliased : aliased_images) {
1663 if (any_rescaled) { 1667 if (!resolution.active | !any_rescaled) {
1664 Image& aliased_image = slot_images[aliased->id]; 1668 CopyImage(image_id, aliased->id, aliased->copies);
1665 if (can_rescale) { 1669 continue;
1666 ScaleUp(aliased_image); 1670 }
1667 } else { 1671 Image& aliased_image = slot_images[aliased->id];
1668 ScaleDown(aliased_image); 1672 if (!can_rescale) {
1669 if (any_blacklisted) { 1673 ScaleDown(aliased_image);
1670 aliased_image.flags |= ImageFlagBits::Blacklisted; 1674 if (any_blacklisted) {
1671 } 1675 aliased_image.flags |= ImageFlagBits::Blacklisted;
1676 }
1677 CopyImage(image_id, aliased->id, aliased->copies);
1678 continue;
1679 }
1680 ScaleUp(aliased_image);
1681
1682 const bool both_2d{image.info.type == ImageType::e2D &&
1683 aliased_image.info.type == ImageType::e2D};
1684 auto copies = aliased->copies;
1685 for (auto copy : copies) {
1686 copy.extent.width = std::max<u32>(
1687 (copy.extent.width * resolution.up_scale) >> resolution.down_shift, 1);
1688 if (both_2d) {
1689 copy.extent.height = std::max<u32>(
1690 (copy.extent.height * resolution.up_scale) >> resolution.down_shift, 1);
1672 } 1691 }
1673 } 1692 }
1674 CopyImage(image_id, aliased->id, aliased->copies); 1693 CopyImage(image_id, aliased->id, copies);
1675 } 1694 }
1676} 1695}
1677 1696
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 59cf2f561..9922aa0cc 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -723,7 +723,7 @@ ImageViewType RenderTargetImageViewType(const ImageInfo& info) noexcept {
723} 723}
724 724
725std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src, 725std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src,
726 SubresourceBase base) { 726 SubresourceBase base, u32 up_scale, u32 down_shift) {
727 ASSERT(dst.resources.levels >= src.resources.levels); 727 ASSERT(dst.resources.levels >= src.resources.levels);
728 ASSERT(dst.num_samples == src.num_samples); 728 ASSERT(dst.num_samples == src.num_samples);
729 729
@@ -732,7 +732,7 @@ std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageIn
732 ASSERT(src.type == ImageType::e3D); 732 ASSERT(src.type == ImageType::e3D);
733 ASSERT(src.resources.levels == 1); 733 ASSERT(src.resources.levels == 1);
734 } 734 }
735 735 const bool both_2d{src.type == ImageType::e2D && dst.type == ImageType::e2D};
736 std::vector<ImageCopy> copies; 736 std::vector<ImageCopy> copies;
737 copies.reserve(src.resources.levels); 737 copies.reserve(src.resources.levels);
738 for (s32 level = 0; level < src.resources.levels; ++level) { 738 for (s32 level = 0; level < src.resources.levels; ++level) {
@@ -762,6 +762,10 @@ std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageIn
762 if (is_dst_3d) { 762 if (is_dst_3d) {
763 copy.extent.depth = src.size.depth; 763 copy.extent.depth = src.size.depth;
764 } 764 }
765 copy.extent.width = std::max<u32>((copy.extent.width * up_scale) >> down_shift, 1);
766 if (both_2d) {
767 copy.extent.height = std::max<u32>((copy.extent.height * up_scale) >> down_shift, 1);
768 }
765 } 769 }
766 return copies; 770 return copies;
767} 771}
diff --git a/src/video_core/texture_cache/util.h b/src/video_core/texture_cache/util.h
index 766502908..7af52de2e 100644
--- a/src/video_core/texture_cache/util.h
+++ b/src/video_core/texture_cache/util.h
@@ -55,7 +55,8 @@ struct OverlapResult {
55 55
56[[nodiscard]] std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, 56[[nodiscard]] std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst,
57 const ImageInfo& src, 57 const ImageInfo& src,
58 SubresourceBase base); 58 SubresourceBase base, u32 up_scale = 1,
59 u32 down_shift = 0);
59 60
60[[nodiscard]] bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config); 61[[nodiscard]] bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config);
61 62