diff options
| author | 2021-10-20 18:27:25 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:31 +0100 | |
| commit | d37d10e7a7b9037a259b27923716e5ce3084d6c3 (patch) | |
| tree | 52ee8db37b4eefed3bd24e36bfe7ca7319fc51f5 | |
| parent | Presentation: Fix turning FSR on and off in settings (diff) | |
| download | yuzu-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.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 41 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.h | 3 |
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 | |||
| 96 | VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u32 down_shift = 0) { | 96 | VkRect2D 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 | ||
| 725 | std::vector<ImageCopy> MakeShrinkImageCopies(const ImageInfo& dst, const ImageInfo& src, | 725 | std::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 | ||