diff options
| author | 2021-07-20 22:51:25 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:27 +0100 | |
| commit | 8704c939136e88876d65fc670bce98d8250a6588 (patch) | |
| tree | ed72be40d7eab387067678e32b285e9e5902f516 /src | |
| parent | TextureCache: Modify Viewports/Scissors according to Rescale. (diff) | |
| download | yuzu-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.cpp | 40 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 43 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
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 | ||
| 1571 | template <class P> | 1571 | template <class P> |
| 1572 | void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::span<const ImageCopy> copies) { | 1572 | void 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); |