Sfoglia il codice sorgente

Vulkan Texture Cache: Limit render area to the max width/height of the targets.

Fernando Sahmkow 4 anni fa
parent
commit
ada09778d9

+ 23 - 7
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@@ -1474,13 +1474,14 @@ bool Image::BlitScaleHelper(bool scale_up) {
     };
     const VkExtent2D extent{
         .width = std::max(scaled_width, info.size.width),
-        .height = std::max(scaled_height, info.size.width),
+        .height = std::max(scaled_height, info.size.height),
     };
 
     auto* view_ptr = blit_view.get();
     if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
         if (!blit_framebuffer) {
-            blit_framebuffer = std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
+            blit_framebuffer =
+                std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent, scale_up);
         }
         const auto color_view = blit_view->Handle(Shader::TextureType::Color2D);
 
@@ -1488,7 +1489,8 @@ bool Image::BlitScaleHelper(bool scale_up) {
                                              src_region, operation, BLIT_OPERATION);
     } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
         if (!blit_framebuffer) {
-            blit_framebuffer = std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent);
+            blit_framebuffer =
+                std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent, scale_up);
         }
         runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), blit_view->DepthView(),
                                                     blit_view->StencilView(), dst_region,
@@ -1756,34 +1758,42 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
           .width = key.size.width,
           .height = key.size.height,
       }} {
-    CreateFramebuffer(runtime, color_buffers, depth_buffer);
+    CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled);
     if (runtime.device.HasDebuggingToolAttached()) {
         framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str());
     }
 }
 
 Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
-                         ImageView* depth_buffer, VkExtent2D extent)
+                         ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled)
     : render_area{extent} {
     std::array<ImageView*, NUM_RT> color_buffers{color_buffer};
-    CreateFramebuffer(runtime, color_buffers, depth_buffer);
+    CreateFramebuffer(runtime, color_buffers, depth_buffer, is_rescaled);
 }
 
 Framebuffer::~Framebuffer() = default;
 
 void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
                                     std::span<ImageView*, NUM_RT> color_buffers,
-                                    ImageView* depth_buffer) {
+                                    ImageView* depth_buffer, bool is_rescaled) {
     std::vector<VkImageView> attachments;
     RenderPassKey renderpass_key{};
     s32 num_layers = 1;
 
+    const auto& resolution = runtime.resolution;
+
+    u32 width = 0;
+    u32 height = 0;
     for (size_t index = 0; index < NUM_RT; ++index) {
         const ImageView* const color_buffer = color_buffers[index];
         if (!color_buffer) {
             renderpass_key.color_formats[index] = PixelFormat::Invalid;
             continue;
         }
+        width = std::max(width, is_rescaled ? resolution.ScaleUp(color_buffer->size.width)
+                                            : color_buffer->size.width);
+        height = std::max(height, is_rescaled ? resolution.ScaleUp(color_buffer->size.height)
+                                              : color_buffer->size.height);
         attachments.push_back(color_buffer->RenderTarget());
         renderpass_key.color_formats[index] = color_buffer->format;
         num_layers = std::max(num_layers, color_buffer->range.extent.layers);
@@ -1794,6 +1804,10 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
     }
     const size_t num_colors = attachments.size();
     if (depth_buffer) {
+        width = std::max(width, is_rescaled ? resolution.ScaleUp(depth_buffer->size.width)
+                                            : depth_buffer->size.width);
+        height = std::max(height, is_rescaled ? resolution.ScaleUp(depth_buffer->size.height)
+                                              : depth_buffer->size.height);
         attachments.push_back(depth_buffer->RenderTarget());
         renderpass_key.depth_format = depth_buffer->format;
         num_layers = std::max(num_layers, depth_buffer->range.extent.layers);
@@ -1810,6 +1824,8 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
     renderpass_key.samples = samples;
 
     renderpass = runtime.render_pass_cache.Get(renderpass_key);
+    render_area.width = std::min(render_area.width, width);
+    render_area.height = std::min(render_area.height, height);
 
     num_color_buffers = static_cast<u32>(num_colors);
     framebuffer = runtime.device.GetLogical().CreateFramebuffer({

+ 3 - 2
src/video_core/renderer_vulkan/vk_texture_cache.h

@@ -268,7 +268,7 @@ public:
                          ImageView* depth_buffer, const VideoCommon::RenderTargets& key);
 
     explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
-                         ImageView* depth_buffer, VkExtent2D extent);
+                         ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled);
 
     ~Framebuffer();
 
@@ -279,7 +279,8 @@ public:
     Framebuffer& operator=(Framebuffer&&) = default;
 
     void CreateFramebuffer(TextureCacheRuntime& runtime,
-                           std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer);
+                           std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer,
+                           bool is_rescaled = false);
 
     [[nodiscard]] VkFramebuffer Handle() const noexcept {
         return *framebuffer;

+ 1 - 0
src/video_core/texture_cache/render_targets.h

@@ -26,6 +26,7 @@ struct RenderTargets {
     ImageViewId depth_buffer_id{};
     std::array<u8, NUM_RT> draw_buffers{};
     Extent2D size{};
+    bool is_rescaled{};
 };
 
 } // namespace VideoCommon

+ 2 - 0
src/video_core/texture_cache/texture_cache.h

@@ -357,6 +357,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
         (maxwell3d->regs.render_area.width * up_scale) >> down_shift,
         (maxwell3d->regs.render_area.height * up_scale) >> down_shift,
     };
+    render_targets.is_rescaled = is_rescaling;
 
     flags[Dirty::DepthBiasGlobal] = true;
 }
@@ -1962,6 +1963,7 @@ std::pair<FramebufferId, ImageViewId> TextureCache<P>::RenderTargetFromImage(
         .color_buffer_ids = {color_view_id},
         .depth_buffer_id = depth_view_id,
         .size = {extent.width >> samples_x, extent.height >> samples_y},
+        .is_rescaled = is_rescaled,
     });
     return {framebuffer_id, view_id};
 }