diff options
| author | 2021-09-21 22:22:24 -0400 | |
|---|---|---|
| committer | 2021-11-16 22:11:30 +0100 | |
| commit | 36f261edefd2e16d34f2726f0a0295e089ed1c17 (patch) | |
| tree | bbb36acde0074110e21eb10ff2ad654bd9022a81 /src | |
| parent | gl_texture_cache: Fix scaling backup logic (diff) | |
| download | yuzu-36f261edefd2e16d34f2726f0a0295e089ed1c17.tar.gz yuzu-36f261edefd2e16d34f2726f0a0295e089ed1c17.tar.xz yuzu-36f261edefd2e16d34f2726f0a0295e089ed1c17.zip | |
vk_texture_cache: Simplify scaled image management
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 111 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 30 |
2 files changed, 34 insertions, 107 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index a34cd31f0..5b4f51a31 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -996,17 +996,14 @@ u64 TextureCacheRuntime::GetDeviceLocalMemory() const { | |||
| 996 | return device.GetDeviceLocalMemory(); | 996 | return device.GetDeviceLocalMemory(); |
| 997 | } | 997 | } |
| 998 | 998 | ||
| 999 | void TextureCacheRuntime::TickFrame() { | 999 | void TextureCacheRuntime::TickFrame() {} |
| 1000 | prescaled_images.Tick(); | ||
| 1001 | prescaled_commits.Tick(); | ||
| 1002 | } | ||
| 1003 | 1000 | ||
| 1004 | Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_, | 1001 | Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_, |
| 1005 | VAddr cpu_addr_) | 1002 | VAddr cpu_addr_) |
| 1006 | : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler}, | 1003 | : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler}, |
| 1007 | image(MakeImage(runtime_.device, info)), | 1004 | runtime{&runtime_}, original_image(MakeImage(runtime_.device, info)), |
| 1008 | commit(runtime_.memory_allocator.Commit(image, MemoryUsage::DeviceLocal)), | 1005 | commit(runtime_.memory_allocator.Commit(original_image, MemoryUsage::DeviceLocal)), |
| 1009 | aspect_mask(ImageAspectMask(info.format)), runtime{&runtime_} { | 1006 | aspect_mask(ImageAspectMask(info.format)) { |
| 1010 | if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { | 1007 | if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { |
| 1011 | if (Settings::values.accelerate_astc.GetValue()) { | 1008 | if (Settings::values.accelerate_astc.GetValue()) { |
| 1012 | flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; | 1009 | flags |= VideoCommon::ImageFlagBits::AcceleratedUpload; |
| @@ -1015,13 +1012,14 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu | |||
| 1015 | } | 1012 | } |
| 1016 | } | 1013 | } |
| 1017 | if (runtime->device.HasDebuggingToolAttached()) { | 1014 | if (runtime->device.HasDebuggingToolAttached()) { |
| 1018 | image.SetObjectNameEXT(VideoCommon::Name(*this).c_str()); | 1015 | original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str()); |
| 1019 | } | 1016 | } |
| 1020 | static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{ | 1017 | static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{ |
| 1021 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, | 1018 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, |
| 1022 | .pNext = nullptr, | 1019 | .pNext = nullptr, |
| 1023 | .usage = VK_IMAGE_USAGE_STORAGE_BIT, | 1020 | .usage = VK_IMAGE_USAGE_STORAGE_BIT, |
| 1024 | }; | 1021 | }; |
| 1022 | current_image = *original_image; | ||
| 1025 | if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { | 1023 | if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) { |
| 1026 | const auto& device = runtime->device.GetLogical(); | 1024 | const auto& device = runtime->device.GetLogical(); |
| 1027 | storage_image_views.reserve(info.resources.levels); | 1025 | storage_image_views.reserve(info.resources.levels); |
| @@ -1030,7 +1028,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu | |||
| 1030 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, | 1028 | .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| 1031 | .pNext = &storage_image_view_usage_create_info, | 1029 | .pNext = &storage_image_view_usage_create_info, |
| 1032 | .flags = 0, | 1030 | .flags = 0, |
| 1033 | .image = *image, | 1031 | .image = *original_image, |
| 1034 | .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY, | 1032 | .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY, |
| 1035 | .format = VK_FORMAT_A8B8G8R8_UNORM_PACK32, | 1033 | .format = VK_FORMAT_A8B8G8R8_UNORM_PACK32, |
| 1036 | .components{ | 1034 | .components{ |
| @@ -1059,12 +1057,12 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag | |||
| 1059 | // TODO: Move this to another API | 1057 | // TODO: Move this to another API |
| 1060 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 1058 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 1061 | if (is_rescaled) { | 1059 | if (is_rescaled) { |
| 1062 | ScaleDown(true); | 1060 | ScaleDown(); |
| 1063 | } | 1061 | } |
| 1064 | scheduler->RequestOutsideRenderPassOperationContext(); | 1062 | scheduler->RequestOutsideRenderPassOperationContext(); |
| 1065 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); | 1063 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); |
| 1066 | const VkBuffer src_buffer = map.buffer; | 1064 | const VkBuffer src_buffer = map.buffer; |
| 1067 | const VkImage vk_image = *image; | 1065 | const VkImage vk_image = *original_image; |
| 1068 | const VkImageAspectFlags vk_aspect_mask = aspect_mask; | 1066 | const VkImageAspectFlags vk_aspect_mask = aspect_mask; |
| 1069 | const bool is_initialized = std::exchange(initialized, true); | 1067 | const bool is_initialized = std::exchange(initialized, true); |
| 1070 | scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, | 1068 | scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized, |
| @@ -1072,18 +1070,14 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag | |||
| 1072 | CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); | 1070 | CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies); |
| 1073 | }); | 1071 | }); |
| 1074 | if (is_rescaled) { | 1072 | if (is_rescaled) { |
| 1075 | ScaleUp(true); | 1073 | ScaleUp(); |
| 1076 | } | 1074 | } |
| 1077 | } | 1075 | } |
| 1078 | 1076 | ||
| 1079 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { | 1077 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { |
| 1080 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | ||
| 1081 | if (is_rescaled) { | ||
| 1082 | ScaleDown(true); | ||
| 1083 | } | ||
| 1084 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); | 1078 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); |
| 1085 | scheduler->RequestOutsideRenderPassOperationContext(); | 1079 | scheduler->RequestOutsideRenderPassOperationContext(); |
| 1086 | scheduler->Record([buffer = map.buffer, image = *image, aspect_mask = aspect_mask, | 1080 | scheduler->Record([buffer = map.buffer, image = *original_image, aspect_mask = aspect_mask, |
| 1087 | vk_copies](vk::CommandBuffer cmdbuf) { | 1081 | vk_copies](vk::CommandBuffer cmdbuf) { |
| 1088 | const VkImageMemoryBarrier read_barrier{ | 1082 | const VkImageMemoryBarrier read_barrier{ |
| 1089 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, | 1083 | .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, |
| @@ -1133,51 +1127,31 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm | |||
| 1133 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 1127 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
| 1134 | 0, memory_write_barrier, nullptr, image_write_barrier); | 1128 | 0, memory_write_barrier, nullptr, image_write_barrier); |
| 1135 | }); | 1129 | }); |
| 1136 | if (is_rescaled) { | ||
| 1137 | SwapBackup(); | ||
| 1138 | } | ||
| 1139 | } | 1130 | } |
| 1140 | 1131 | ||
| 1141 | bool Image::ScaleUp(bool save_as_backup) { | 1132 | bool Image::ScaleUp() { |
| 1142 | if (True(flags & ImageFlagBits::Rescaled)) { | 1133 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1143 | return false; | 1134 | return false; |
| 1144 | } | 1135 | } |
| 1145 | ASSERT(info.type != ImageType::Linear); | 1136 | ASSERT(info.type != ImageType::Linear); |
| 1146 | scaling_count++; | ||
| 1147 | flags |= ImageFlagBits::Rescaled; | 1137 | flags |= ImageFlagBits::Rescaled; |
| 1148 | 1138 | ||
| 1149 | const auto& resolution = runtime->resolution; | 1139 | const auto& resolution = runtime->resolution; |
| 1150 | if (!resolution.active) { | 1140 | if (!resolution.active) { |
| 1151 | return true; | 1141 | return true; |
| 1152 | } | 1142 | } |
| 1153 | vk::Image rescaled_image = | 1143 | const auto& device = runtime->device; |
| 1154 | has_backup ? std::move(backup_image) | 1144 | if (!scaled_image) { |
| 1155 | : MakeImage(runtime->device, info, resolution.up_scale, resolution.down_shift); | 1145 | scaled_image = MakeImage(device, info, resolution.up_scale, resolution.down_shift); |
| 1156 | MemoryCommit new_commit = has_backup ? std::move(backup_commit) | 1146 | auto& allocator = runtime->memory_allocator; |
| 1157 | : MemoryCommit(runtime->memory_allocator.Commit( | 1147 | scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal)); |
| 1158 | rescaled_image, MemoryUsage::DeviceLocal)); | 1148 | } |
| 1159 | has_backup = false; | ||
| 1160 | |||
| 1161 | if (aspect_mask == 0) { | 1149 | if (aspect_mask == 0) { |
| 1162 | aspect_mask = ImageAspectMask(info.format); | 1150 | aspect_mask = ImageAspectMask(info.format); |
| 1163 | } | 1151 | } |
| 1164 | SCOPE_EXIT({ | ||
| 1165 | if (save_as_backup) { | ||
| 1166 | backup_image = std::move(image); | ||
| 1167 | backup_commit = std::move(commit); | ||
| 1168 | has_backup = true; | ||
| 1169 | } else { | ||
| 1170 | runtime->prescaled_images.Push(std::move(image)); | ||
| 1171 | runtime->prescaled_commits.Push(std::move(commit)); | ||
| 1172 | } | ||
| 1173 | image = std::move(rescaled_image); | ||
| 1174 | commit = std::move(new_commit); | ||
| 1175 | }); | ||
| 1176 | |||
| 1177 | const PixelFormat format = StorageFormat(info.format); | 1152 | const PixelFormat format = StorageFormat(info.format); |
| 1178 | const auto format_info = | 1153 | const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, format); |
| 1179 | MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, false, format); | 1154 | const auto similar = device.GetSupportedFormat( |
| 1180 | const auto similar = runtime->device.GetSupportedFormat( | ||
| 1181 | format_info.format, (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT), | 1155 | format_info.format, (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT), |
| 1182 | FormatType::Optimal); | 1156 | FormatType::Optimal); |
| 1183 | 1157 | ||
| @@ -1187,55 +1161,18 @@ bool Image::ScaleUp(bool save_as_backup) { | |||
| 1187 | if (aspect_mask == 0) { | 1161 | if (aspect_mask == 0) { |
| 1188 | aspect_mask = ImageAspectMask(info.format); | 1162 | aspect_mask = ImageAspectMask(info.format); |
| 1189 | } | 1163 | } |
| 1190 | BlitScale(*scheduler, *image, *rescaled_image, info, aspect_mask, resolution, true); | 1164 | BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution, true); |
| 1165 | current_image = *scaled_image; | ||
| 1191 | return true; | 1166 | return true; |
| 1192 | } | 1167 | } |
| 1193 | 1168 | ||
| 1194 | void Image::SwapBackup() { | 1169 | bool Image::ScaleDown() { |
| 1195 | if (!runtime->resolution.active) { | ||
| 1196 | return; | ||
| 1197 | } | ||
| 1198 | ASSERT(has_backup); | ||
| 1199 | runtime->prescaled_images.Push(std::move(image)); | ||
| 1200 | runtime->prescaled_commits.Push(std::move(commit)); | ||
| 1201 | image = std::move(backup_image); | ||
| 1202 | commit = std::move(backup_commit); | ||
| 1203 | has_backup = false; | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | bool Image::ScaleDown(bool save_as_backup) { | ||
| 1207 | if (False(flags & ImageFlagBits::Rescaled)) { | 1170 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 1208 | return false; | 1171 | return false; |
| 1209 | } | 1172 | } |
| 1210 | ASSERT(info.type != ImageType::Linear); | 1173 | ASSERT(info.type != ImageType::Linear); |
| 1211 | flags &= ~ImageFlagBits::Rescaled; | 1174 | flags &= ~ImageFlagBits::Rescaled; |
| 1212 | scaling_count++; | 1175 | current_image = *original_image; |
| 1213 | |||
| 1214 | const auto& resolution = runtime->resolution; | ||
| 1215 | if (!resolution.active) { | ||
| 1216 | return true; | ||
| 1217 | } | ||
| 1218 | vk::Image downscaled_image = | ||
| 1219 | has_backup ? std::move(backup_image) : MakeImage(runtime->device, info); | ||
| 1220 | MemoryCommit new_commit = has_backup ? std::move(backup_commit) | ||
| 1221 | : MemoryCommit(runtime->memory_allocator.Commit( | ||
| 1222 | downscaled_image, MemoryUsage::DeviceLocal)); | ||
| 1223 | has_backup = false; | ||
| 1224 | if (aspect_mask == 0) { | ||
| 1225 | aspect_mask = ImageAspectMask(info.format); | ||
| 1226 | } | ||
| 1227 | BlitScale(*scheduler, *image, *downscaled_image, info, aspect_mask, resolution, false); | ||
| 1228 | |||
| 1229 | if (save_as_backup) { | ||
| 1230 | backup_image = std::move(image); | ||
| 1231 | backup_commit = std::move(commit); | ||
| 1232 | has_backup = true; | ||
| 1233 | } else { | ||
| 1234 | runtime->prescaled_images.Push(std::move(image)); | ||
| 1235 | runtime->prescaled_commits.Push(std::move(commit)); | ||
| 1236 | } | ||
| 1237 | image = std::move(downscaled_image); | ||
| 1238 | commit = std::move(new_commit); | ||
| 1239 | return true; | 1176 | return true; |
| 1240 | } | 1177 | } |
| 1241 | 1178 | ||
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 84194b833..e5060e3f1 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | 8 | ||
| 9 | #include "common/settings.h" | 9 | #include "common/settings.h" |
| 10 | #include "shader_recompiler/shader_info.h" | 10 | #include "shader_recompiler/shader_info.h" |
| 11 | #include "video_core/delayed_destruction_ring.h" | ||
| 12 | #include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" | 11 | #include "video_core/renderer_vulkan/vk_staging_buffer_pool.h" |
| 13 | #include "video_core/texture_cache/image_view_base.h" | 12 | #include "video_core/texture_cache/image_view_base.h" |
| 14 | #include "video_core/texture_cache/texture_cache_base.h" | 13 | #include "video_core/texture_cache/texture_cache_base.h" |
| @@ -17,7 +16,6 @@ | |||
| 17 | 16 | ||
| 18 | namespace Vulkan { | 17 | namespace Vulkan { |
| 19 | 18 | ||
| 20 | using VideoCommon::DelayedDestructionRing; | ||
| 21 | using VideoCommon::ImageId; | 19 | using VideoCommon::ImageId; |
| 22 | using VideoCommon::NUM_RT; | 20 | using VideoCommon::NUM_RT; |
| 23 | using VideoCommon::Region2D; | 21 | using VideoCommon::Region2D; |
| @@ -36,8 +34,6 @@ class VKScheduler; | |||
| 36 | 34 | ||
| 37 | class TextureCacheRuntime { | 35 | class TextureCacheRuntime { |
| 38 | public: | 36 | public: |
| 39 | static constexpr size_t TICKS_TO_DESTROY = 6; | ||
| 40 | |||
| 41 | explicit TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, | 37 | explicit TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_, |
| 42 | MemoryAllocator& memory_allocator_, | 38 | MemoryAllocator& memory_allocator_, |
| 43 | StagingBufferPool& staging_buffer_pool_, | 39 | StagingBufferPool& staging_buffer_pool_, |
| @@ -90,9 +86,6 @@ public: | |||
| 90 | BlitImageHelper& blit_image_helper; | 86 | BlitImageHelper& blit_image_helper; |
| 91 | ASTCDecoderPass& astc_decoder_pass; | 87 | ASTCDecoderPass& astc_decoder_pass; |
| 92 | RenderPassCache& render_pass_cache; | 88 | RenderPassCache& render_pass_cache; |
| 93 | |||
| 94 | DelayedDestructionRing<vk::Image, TICKS_TO_DESTROY> prescaled_images; | ||
| 95 | DelayedDestructionRing<MemoryCommit, TICKS_TO_DESTROY> prescaled_commits; | ||
| 96 | Settings::ResolutionScalingInfo resolution; | 89 | Settings::ResolutionScalingInfo resolution; |
| 97 | }; | 90 | }; |
| 98 | 91 | ||
| @@ -117,7 +110,7 @@ public: | |||
| 117 | std::span<const VideoCommon::BufferImageCopy> copies); | 110 | std::span<const VideoCommon::BufferImageCopy> copies); |
| 118 | 111 | ||
| 119 | [[nodiscard]] VkImage Handle() const noexcept { | 112 | [[nodiscard]] VkImage Handle() const noexcept { |
| 120 | return *image; | 113 | return current_image; |
| 121 | } | 114 | } |
| 122 | 115 | ||
| 123 | [[nodiscard]] VkImageAspectFlags AspectMask() const noexcept { | 116 | [[nodiscard]] VkImageAspectFlags AspectMask() const noexcept { |
| @@ -133,25 +126,22 @@ public: | |||
| 133 | return std::exchange(initialized, true); | 126 | return std::exchange(initialized, true); |
| 134 | } | 127 | } |
| 135 | 128 | ||
| 136 | bool ScaleUp(bool save_as_backup = false); | 129 | bool ScaleUp(); |
| 137 | 130 | ||
| 138 | bool ScaleDown(bool save_as_backup = false); | 131 | bool ScaleDown(); |
| 139 | |||
| 140 | void SwapBackup(); | ||
| 141 | 132 | ||
| 142 | private: | 133 | private: |
| 143 | VKScheduler* scheduler; | 134 | VKScheduler* scheduler{}; |
| 144 | vk::Image image; | 135 | TextureCacheRuntime* runtime{}; |
| 136 | |||
| 137 | vk::Image original_image; | ||
| 145 | MemoryCommit commit; | 138 | MemoryCommit commit; |
| 146 | vk::ImageView image_view; | ||
| 147 | std::vector<vk::ImageView> storage_image_views; | 139 | std::vector<vk::ImageView> storage_image_views; |
| 148 | VkImageAspectFlags aspect_mask = 0; | 140 | VkImageAspectFlags aspect_mask = 0; |
| 149 | bool initialized = false; | 141 | bool initialized = false; |
| 150 | TextureCacheRuntime* runtime; | 142 | vk::Image scaled_image{}; |
| 151 | u32 scaling_count{}; | 143 | MemoryCommit scaled_commit{}; |
| 152 | vk::Image backup_image{}; | 144 | VkImage current_image{}; |
| 153 | MemoryCommit backup_commit{}; | ||
| 154 | bool has_backup{}; | ||
| 155 | }; | 145 | }; |
| 156 | 146 | ||
| 157 | class ImageView : public VideoCommon::ImageViewBase { | 147 | class ImageView : public VideoCommon::ImageViewBase { |