Vulkan Texture Cache: Limit render area to the max width/height of the targets.
This commit is contained in:
		| @@ -1474,13 +1474,14 @@ bool Image::BlitScaleHelper(bool scale_up) { | |||||||
|     }; |     }; | ||||||
|     const VkExtent2D extent{ |     const VkExtent2D extent{ | ||||||
|         .width = std::max(scaled_width, info.size.width), |         .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(); |     auto* view_ptr = blit_view.get(); | ||||||
|     if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { |     if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { | ||||||
|         if (!blit_framebuffer) { |         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); |         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); |                                              src_region, operation, BLIT_OPERATION); | ||||||
|     } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { |     } else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { | ||||||
|         if (!blit_framebuffer) { |         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(), |         runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), blit_view->DepthView(), | ||||||
|                                                     blit_view->StencilView(), dst_region, |                                                     blit_view->StencilView(), dst_region, | ||||||
| @@ -1756,34 +1758,42 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM | |||||||
|           .width = key.size.width, |           .width = key.size.width, | ||||||
|           .height = key.size.height, |           .height = key.size.height, | ||||||
|       }} { |       }} { | ||||||
|     CreateFramebuffer(runtime, color_buffers, depth_buffer); |     CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled); | ||||||
|     if (runtime.device.HasDebuggingToolAttached()) { |     if (runtime.device.HasDebuggingToolAttached()) { | ||||||
|         framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str()); |         framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, | Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, | ||||||
|                          ImageView* depth_buffer, VkExtent2D extent) |                          ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled) | ||||||
|     : render_area{extent} { |     : render_area{extent} { | ||||||
|     std::array<ImageView*, NUM_RT> color_buffers{color_buffer}; |     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; | Framebuffer::~Framebuffer() = default; | ||||||
|  |  | ||||||
| void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, | void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, | ||||||
|                                     std::span<ImageView*, NUM_RT> color_buffers, |                                     std::span<ImageView*, NUM_RT> color_buffers, | ||||||
|                                     ImageView* depth_buffer) { |                                     ImageView* depth_buffer, bool is_rescaled) { | ||||||
|     std::vector<VkImageView> attachments; |     std::vector<VkImageView> attachments; | ||||||
|     RenderPassKey renderpass_key{}; |     RenderPassKey renderpass_key{}; | ||||||
|     s32 num_layers = 1; |     s32 num_layers = 1; | ||||||
|  |  | ||||||
|  |     const auto& resolution = runtime.resolution; | ||||||
|  |  | ||||||
|  |     u32 width = 0; | ||||||
|  |     u32 height = 0; | ||||||
|     for (size_t index = 0; index < NUM_RT; ++index) { |     for (size_t index = 0; index < NUM_RT; ++index) { | ||||||
|         const ImageView* const color_buffer = color_buffers[index]; |         const ImageView* const color_buffer = color_buffers[index]; | ||||||
|         if (!color_buffer) { |         if (!color_buffer) { | ||||||
|             renderpass_key.color_formats[index] = PixelFormat::Invalid; |             renderpass_key.color_formats[index] = PixelFormat::Invalid; | ||||||
|             continue; |             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()); |         attachments.push_back(color_buffer->RenderTarget()); | ||||||
|         renderpass_key.color_formats[index] = color_buffer->format; |         renderpass_key.color_formats[index] = color_buffer->format; | ||||||
|         num_layers = std::max(num_layers, color_buffer->range.extent.layers); |         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(); |     const size_t num_colors = attachments.size(); | ||||||
|     if (depth_buffer) { |     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()); |         attachments.push_back(depth_buffer->RenderTarget()); | ||||||
|         renderpass_key.depth_format = depth_buffer->format; |         renderpass_key.depth_format = depth_buffer->format; | ||||||
|         num_layers = std::max(num_layers, depth_buffer->range.extent.layers); |         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_key.samples = samples; | ||||||
|  |  | ||||||
|     renderpass = runtime.render_pass_cache.Get(renderpass_key); |     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); |     num_color_buffers = static_cast<u32>(num_colors); | ||||||
|     framebuffer = runtime.device.GetLogical().CreateFramebuffer({ |     framebuffer = runtime.device.GetLogical().CreateFramebuffer({ | ||||||
|   | |||||||
| @@ -268,7 +268,7 @@ public: | |||||||
|                          ImageView* depth_buffer, const VideoCommon::RenderTargets& key); |                          ImageView* depth_buffer, const VideoCommon::RenderTargets& key); | ||||||
|  |  | ||||||
|     explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, |     explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer, | ||||||
|                          ImageView* depth_buffer, VkExtent2D extent); |                          ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled); | ||||||
|  |  | ||||||
|     ~Framebuffer(); |     ~Framebuffer(); | ||||||
|  |  | ||||||
| @@ -279,7 +279,8 @@ public: | |||||||
|     Framebuffer& operator=(Framebuffer&&) = default; |     Framebuffer& operator=(Framebuffer&&) = default; | ||||||
|  |  | ||||||
|     void CreateFramebuffer(TextureCacheRuntime& runtime, |     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 { |     [[nodiscard]] VkFramebuffer Handle() const noexcept { | ||||||
|         return *framebuffer; |         return *framebuffer; | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ struct RenderTargets { | |||||||
|     ImageViewId depth_buffer_id{}; |     ImageViewId depth_buffer_id{}; | ||||||
|     std::array<u8, NUM_RT> draw_buffers{}; |     std::array<u8, NUM_RT> draw_buffers{}; | ||||||
|     Extent2D size{}; |     Extent2D size{}; | ||||||
|  |     bool is_rescaled{}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } // namespace VideoCommon | } // namespace VideoCommon | ||||||
|   | |||||||
| @@ -357,6 +357,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) { | |||||||
|         (maxwell3d->regs.render_area.width * up_scale) >> down_shift, |         (maxwell3d->regs.render_area.width * up_scale) >> down_shift, | ||||||
|         (maxwell3d->regs.render_area.height * up_scale) >> down_shift, |         (maxwell3d->regs.render_area.height * up_scale) >> down_shift, | ||||||
|     }; |     }; | ||||||
|  |     render_targets.is_rescaled = is_rescaling; | ||||||
|  |  | ||||||
|     flags[Dirty::DepthBiasGlobal] = true; |     flags[Dirty::DepthBiasGlobal] = true; | ||||||
| } | } | ||||||
| @@ -1962,6 +1963,7 @@ std::pair<FramebufferId, ImageViewId> TextureCache<P>::RenderTargetFromImage( | |||||||
|         .color_buffer_ids = {color_view_id}, |         .color_buffer_ids = {color_view_id}, | ||||||
|         .depth_buffer_id = depth_view_id, |         .depth_buffer_id = depth_view_id, | ||||||
|         .size = {extent.width >> samples_x, extent.height >> samples_y}, |         .size = {extent.width >> samples_x, extent.height >> samples_y}, | ||||||
|  |         .is_rescaled = is_rescaled, | ||||||
|     }); |     }); | ||||||
|     return {framebuffer_id, view_id}; |     return {framebuffer_id, view_id}; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user