summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-07-20 22:51:25 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:27 +0100
commit8704c939136e88876d65fc670bce98d8250a6588 (patch)
treeed72be40d7eab387067678e32b285e9e5902f516 /src
parentTextureCache: Modify Viewports/Scissors according to Rescale. (diff)
downloadyuzu-8704c939136e88876d65fc670bce98d8250a6588.tar.gz
yuzu-8704c939136e88876d65fc670bce98d8250a6588.tar.xz
yuzu-8704c939136e88876d65fc670bce98d8250a6588.zip
TextureCache: Fix rescaling of ImageCopies
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp40
-rw-r--r--src/video_core/texture_cache/texture_cache.h43
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
3 files changed, 67 insertions, 18 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 5fd190825..54236e87f 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -136,6 +136,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
136 if (info.type == ImageType::e3D) { 136 if (info.type == ImageType::e3D) {
137 flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT; 137 flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
138 } 138 }
139 const auto scale_up = [&](u32 value) { return std::max<u32>((value * up) >> down, 1U); };
139 const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples); 140 const auto [samples_x, samples_y] = VideoCommon::SamplesLog2(info.num_samples);
140 const bool is_2d = info.type == ImageType::e2D; 141 const bool is_2d = info.type == ImageType::e2D;
141 return VkImageCreateInfo{ 142 return VkImageCreateInfo{
@@ -145,8 +146,8 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {
145 .imageType = ConvertImageType(info.type), 146 .imageType = ConvertImageType(info.type),
146 .format = format_info.format, 147 .format = format_info.format,
147 .extent{ 148 .extent{
148 .width = ((info.size.width * up) >> down) >> samples_x, 149 .width = scale_up(info.size.width) >> samples_x,
149 .height = (is_2d ? ((info.size.height * up) >> down) : info.size.height) >> samples_y, 150 .height = (is_2d ? scale_up(info.size.height) : info.size.height) >> samples_y,
150 .depth = info.size.depth, 151 .depth = info.size.depth,
151 }, 152 },
152 .mipLevels = static_cast<u32>(info.resources.levels), 153 .mipLevels = static_cast<u32>(info.resources.levels),
@@ -1078,12 +1079,35 @@ bool Image::ScaleUp(bool save_as_backup) {
1078 MemoryCommit new_commit( 1079 MemoryCommit new_commit(
1079 runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal)); 1080 runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal));
1080 1081
1082 SCOPE_EXIT({
1083 if (save_as_backup) {
1084 backup_image = std::move(image);
1085 backup_commit = std::move(commit);
1086 has_backup = true;
1087 } else {
1088 runtime->prescaled_images.Push(std::move(image));
1089 runtime->prescaled_commits.Push(std::move(commit));
1090 }
1091 image = std::move(rescaled_image);
1092 commit = std::move(new_commit);
1093 });
1094
1095 const PixelFormat format = StorageFormat(info.format);
1096 const auto format_info =
1097 MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, false, format);
1098 const auto similar = runtime->device.GetSupportedFormat(
1099 format_info.format, (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT),
1100 FormatType::Optimal);
1101
1102 if (similar != format_info.format) {
1103 return true;
1104 }
1081 if (aspect_mask == 0) { 1105 if (aspect_mask == 0) {
1082 aspect_mask = ImageAspectMask(info.format); 1106 aspect_mask = ImageAspectMask(info.format);
1083 } 1107 }
1084 1108
1085 const auto scale_up = [&](u32 value) { 1109 const auto scale_up = [&](u32 value) {
1086 return (value * resolution.up_scale) >> resolution.down_shift; 1110 return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
1087 }; 1111 };
1088 1112
1089 const bool is_2d = info.type == ImageType::e2D; 1113 const bool is_2d = info.type == ImageType::e2D;
@@ -1130,16 +1154,6 @@ bool Image::ScaleUp(bool save_as_backup) {
1130 vkRegions.push_back(blit); 1154 vkRegions.push_back(blit);
1131 } 1155 }
1132 BlitScale(*scheduler, *image, *rescaled_image, vkRegions, aspect_mask); 1156 BlitScale(*scheduler, *image, *rescaled_image, vkRegions, aspect_mask);
1133 if (save_as_backup) {
1134 backup_image = std::move(image);
1135 backup_commit = std::move(commit);
1136 has_backup = true;
1137 } else {
1138 runtime->prescaled_images.Push(std::move(image));
1139 runtime->prescaled_commits.Push(std::move(commit));
1140 }
1141 image = std::move(rescaled_image);
1142 commit = std::move(new_commit);
1143 return true; 1157 return true;
1144} 1158}
1145 1159
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 4e5031acc..df697cdeb 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -929,8 +929,8 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
929 LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented"); 929 LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented");
930 } else { 930 } else {
931 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value(); 931 const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
932 const auto copies = MakeShrinkImageCopies(new_info, overlap.info, base); 932 auto copies = MakeShrinkImageCopies(new_info, overlap.info, base);
933 runtime.CopyImage(new_image, overlap, copies); 933 runtime.CopyImage(new_image, overlap, std::move(copies));
934 } 934 }
935 if (True(overlap.flags & ImageFlagBits::Tracked)) { 935 if (True(overlap.flags & ImageFlagBits::Tracked)) {
936 UntrackImage(overlap, overlap_id); 936 UntrackImage(overlap, overlap_id);
@@ -1569,9 +1569,33 @@ void TextureCache<P>::PrepareImageView(ImageViewId image_view_id, bool is_modifi
1569} 1569}
1570 1570
1571template <class P> 1571template <class P>
1572void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies) { 1572void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<ImageCopy> copies) {
1573 Image& dst = slot_images[dst_id]; 1573 Image& dst = slot_images[dst_id];
1574 Image& src = slot_images[src_id]; 1574 Image& src = slot_images[src_id];
1575 const bool is_rescaled = True(src.flags & ImageFlagBits::Rescaled);
1576 if (is_rescaled) {
1577 ASSERT(True(dst.flags & ImageFlagBits::Rescaled));
1578 const bool both_2d{src.info.type == ImageType::e2D && dst.info.type == ImageType::e2D};
1579 const auto& resolution = Settings::values.resolution_info;
1580 const auto scale_up = [&](u32 value) -> u32 {
1581 if (value == 0) {
1582 return 0U;
1583 }
1584 return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
1585 };
1586 for (auto& copy : copies) {
1587 copy.src_offset.x = scale_up(copy.src_offset.x);
1588
1589 copy.dst_offset.x = scale_up(copy.dst_offset.x);
1590
1591 copy.extent.width = scale_up(copy.extent.width);
1592 if (both_2d) {
1593 copy.src_offset.y = scale_up(copy.src_offset.y);
1594 copy.dst_offset.y = scale_up(copy.dst_offset.y);
1595 copy.extent.height = scale_up(copy.extent.height);
1596 }
1597 }
1598 }
1575 const auto dst_format_type = GetFormatType(dst.info.format); 1599 const auto dst_format_type = GetFormatType(dst.info.format);
1576 const auto src_format_type = GetFormatType(src.info.format); 1600 const auto src_format_type = GetFormatType(src.info.format);
1577 if (src_format_type == dst_format_type) { 1601 if (src_format_type == dst_format_type) {
@@ -1639,10 +1663,21 @@ std::pair<FramebufferId, ImageViewId> TextureCache<P>::RenderTargetFromImage(
1639 ImageId image_id, const ImageViewInfo& view_info) { 1663 ImageId image_id, const ImageViewInfo& view_info) {
1640 const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info); 1664 const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info);
1641 const ImageBase& image = slot_images[image_id]; 1665 const ImageBase& image = slot_images[image_id];
1666 const bool is_rescaled = True(image.flags & ImageFlagBits::Rescaled);
1642 const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture; 1667 const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture;
1643 const ImageViewId color_view_id = is_color ? view_id : ImageViewId{}; 1668 const ImageViewId color_view_id = is_color ? view_id : ImageViewId{};
1644 const ImageViewId depth_view_id = is_color ? ImageViewId{} : view_id; 1669 const ImageViewId depth_view_id = is_color ? ImageViewId{} : view_id;
1645 const Extent3D extent = MipSize(image.info.size, view_info.range.base.level); 1670 Extent3D extent = MipSize(image.info.size, view_info.range.base.level);
1671 if (is_rescaled) {
1672 const auto& resolution = Settings::values.resolution_info;
1673 const auto scale_up = [&](u32 value) {
1674 return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
1675 };
1676 extent.width = scale_up(extent.width);
1677 if (image.info.type == ImageType::e2D) {
1678 extent.height = scale_up(extent.height);
1679 }
1680 }
1646 const u32 num_samples = image.info.num_samples; 1681 const u32 num_samples = image.info.num_samples;
1647 const auto [samples_x, samples_y] = SamplesLog2(num_samples); 1682 const auto [samples_x, samples_y] = SamplesLog2(num_samples);
1648 const FramebufferId framebuffer_id = GetFramebufferId(RenderTargets{ 1683 const FramebufferId framebuffer_id = GetFramebufferId(RenderTargets{
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 1f51fcee8..deddf0d30 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -316,7 +316,7 @@ private:
316 void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate); 316 void PrepareImageView(ImageViewId image_view_id, bool is_modification, bool invalidate);
317 317
318 /// Execute copies from one image to the other, even if they are incompatible 318 /// Execute copies from one image to the other, even if they are incompatible
319 void CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies); 319 void CopyImage(ImageId dst_id, ImageId src_id, std::vector<ImageCopy> copies);
320 320
321 /// Bind an image view as render target, downloading resources preemtively if needed 321 /// Bind an image view as render target, downloading resources preemtively if needed
322 void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id); 322 void BindRenderTarget(ImageViewId* old_id, ImageViewId new_id);