summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2021-09-21 22:22:24 -0400
committerGravatar Fernando Sahmkow2021-11-16 22:11:30 +0100
commit36f261edefd2e16d34f2726f0a0295e089ed1c17 (patch)
treebbb36acde0074110e21eb10ff2ad654bd9022a81 /src
parentgl_texture_cache: Fix scaling backup logic (diff)
downloadyuzu-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.cpp111
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h30
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
999void TextureCacheRuntime::TickFrame() { 999void TextureCacheRuntime::TickFrame() {}
1000 prescaled_images.Tick();
1001 prescaled_commits.Tick();
1002}
1003 1000
1004Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_, 1001Image::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
1079void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { 1077void 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
1141bool Image::ScaleUp(bool save_as_backup) { 1132bool 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
1194void Image::SwapBackup() { 1169bool 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
1206bool 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
18namespace Vulkan { 17namespace Vulkan {
19 18
20using VideoCommon::DelayedDestructionRing;
21using VideoCommon::ImageId; 19using VideoCommon::ImageId;
22using VideoCommon::NUM_RT; 20using VideoCommon::NUM_RT;
23using VideoCommon::Region2D; 21using VideoCommon::Region2D;
@@ -36,8 +34,6 @@ class VKScheduler;
36 34
37class TextureCacheRuntime { 35class TextureCacheRuntime {
38public: 36public:
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
142private: 133private:
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
157class ImageView : public VideoCommon::ImageViewBase { 147class ImageView : public VideoCommon::ImageViewBase {