Просмотр исходного кода

vk_texture_cache: Simplify and optimize scaling blits

ReinUsesLisp 5 лет назад
Родитель
Сommit
0fb4b84383
1 измененных файлов с 62 добавлено и 106 удалено
  1. 62 106
      src/video_core/renderer_vulkan/vk_texture_cache.cpp

+ 62 - 106
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@@ -594,12 +594,67 @@ struct RangedBarrierRange {
     return VK_FORMAT_R32_UINT;
 }
 
-void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image,
-               boost::container::small_vector<VkImageBlit, 4>&& blit_regions,
-               VkImageAspectFlags aspect_mask) {
+void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info,
+               VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution) {
+    const auto type = info.type;
+    const auto resources = info.resources;
+    const VkExtent2D extent{
+        .width = info.size.width,
+        .height = info.size.height,
+    };
     scheduler.RequestOutsideRenderPassOperationContext();
-    scheduler.Record([dst_image, src_image, aspect_mask,
-                      regions = std::move(blit_regions)](vk::CommandBuffer cmdbuf) {
+    scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution,
+                      type](vk::CommandBuffer cmdbuf) {
+        const auto scale_up = [&](u32 value) {
+            return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
+        };
+        const bool is_2d = type == ImageType::e2D;
+        const VkOffset2D mip0_size{
+            .x = static_cast<s32>(scale_up(extent.width)),
+            .y = static_cast<s32>(is_2d ? scale_up(extent.height) : extent.height),
+        };
+        boost::container::small_vector<VkImageBlit, 4> regions;
+        regions.reserve(resources.levels);
+        for (s32 level = 0; level < resources.levels; level++) {
+            regions.push_back({
+                .srcSubresource{
+                    .aspectMask = aspect_mask,
+                    .mipLevel = static_cast<u32>(level),
+                    .baseArrayLayer = 0,
+                    .layerCount = static_cast<u32>(resources.layers),
+                },
+                .srcOffsets{
+                    {
+                        .x = 0,
+                        .y = 0,
+                        .z = 0,
+                    },
+                    {
+                        .x = static_cast<s32>(extent.width),
+                        .y = static_cast<s32>(extent.height),
+                        .z = 1,
+                    },
+                },
+                .dstSubresource{
+                    .aspectMask = aspect_mask,
+                    .mipLevel = static_cast<u32>(level),
+                    .baseArrayLayer = 0,
+                    .layerCount = static_cast<u32>(resources.layers),
+                },
+                .dstOffsets{
+                    {
+                        .x = 0,
+                        .y = 0,
+                        .z = 0,
+                    },
+                    {
+                        .x = std::max(1, mip0_size.x >> level),
+                        .y = std::max(1, mip0_size.y >> level),
+                        .z = 1,
+                    },
+                },
+            });
+        }
         const VkImageSubresourceRange subresource_range{
             .aspectMask = aspect_mask,
             .baseMipLevel = 0,
@@ -1102,57 +1157,7 @@ bool Image::ScaleUp(bool save_as_backup) {
     if (aspect_mask == 0) {
         aspect_mask = ImageAspectMask(info.format);
     }
-
-    const auto scale_up = [&](u32 value) {
-        return std::max<u32>((value * resolution.up_scale) >> resolution.down_shift, 1U);
-    };
-
-    const bool is_2d = info.type == ImageType::e2D;
-    boost::container::small_vector<VkImageBlit, 4> regions;
-    regions.reserve(info.resources.levels);
-    for (s32 level = 0; level < info.resources.levels; level++) {
-        regions.push_back({
-            .srcSubresource{
-                .aspectMask = aspect_mask,
-                .mipLevel = u32(level),
-                .baseArrayLayer = 0,
-                .layerCount = u32(info.resources.layers),
-            },
-            .srcOffsets{
-                {
-                    .x = 0,
-                    .y = 0,
-                    .z = 0,
-                },
-                {
-                    .x = static_cast<s32>(info.size.width),
-                    .y = static_cast<s32>(info.size.height),
-                    .z = 1,
-                },
-            },
-            .dstSubresource{
-                .aspectMask = aspect_mask,
-                .mipLevel = u32(level),
-                .baseArrayLayer = 0,
-                .layerCount = u32(info.resources.layers),
-            },
-            .dstOffsets{
-                {
-                    .x = 0,
-                    .y = 0,
-                    .z = 0,
-                },
-                {
-                    .x = std::max(1, static_cast<s32>(scale_up(info.size.width)) >> level),
-                    .y = std::max(1, static_cast<s32>(is_2d ? scale_up(info.size.height)
-                                                            : info.size.height) >>
-                                         level),
-                    .z = 1,
-                },
-            },
-        });
-    }
-    BlitScale(*scheduler, *image, *rescaled_image, std::move(regions), aspect_mask);
+    BlitScale(*scheduler, *image, *rescaled_image, info, aspect_mask, resolution);
     return true;
 }
 
@@ -1183,60 +1188,11 @@ bool Image::ScaleDown(bool save_as_backup) {
     MemoryCommit new_commit(
         runtime->memory_allocator.Commit(downscaled_image, MemoryUsage::DeviceLocal));
 
-    const auto scale_up = [&](u32 value) {
-        return (value * resolution.up_scale) >> resolution.down_shift;
-    };
-
     if (aspect_mask == 0) {
         aspect_mask = ImageAspectMask(info.format);
     }
+    BlitScale(*scheduler, *image, *downscaled_image, info, aspect_mask, resolution);
 
-    const bool is_2d = info.type == ImageType::e2D;
-    boost::container::small_vector<VkImageBlit, 4> regions;
-    regions.reserve(info.resources.levels);
-    for (s32 level = 0; level < info.resources.levels; level++) {
-        regions.push_back({
-            .srcSubresource{
-                .aspectMask = aspect_mask,
-                .mipLevel = static_cast<u32>(level),
-                .baseArrayLayer = 0,
-                .layerCount = static_cast<u32>(info.resources.layers),
-            },
-            .srcOffsets{
-                {
-                    .x = 0,
-                    .y = 0,
-                    .z = 0,
-                },
-                {
-                    .x = std::max(1, static_cast<s32>(scale_up(info.size.width)) >> level),
-                    .y = std::max(1, static_cast<s32>(is_2d ? scale_up(info.size.height)
-                                                            : info.size.height) >>
-                                         level),
-                    .z = 1,
-                },
-            },
-            .dstSubresource{
-                .aspectMask = aspect_mask,
-                .mipLevel = static_cast<u32>(level),
-                .baseArrayLayer = 0,
-                .layerCount = static_cast<u32>(info.resources.layers),
-            },
-            .dstOffsets{
-                {
-                    .x = 0,
-                    .y = 0,
-                    .z = 0,
-                },
-                {
-                    .x = std::max(1, static_cast<s32>(info.size.width) >> level),
-                    .y = std::max(1, static_cast<s32>(info.size.height) >> level),
-                    .z = 1,
-                },
-            },
-        });
-    }
-    BlitScale(*scheduler, *image, *downscaled_image, std::move(regions), aspect_mask);
     if (save_as_backup) {
         backup_image = std::move(image);
         backup_commit = std::move(commit);