From 97cf3f770eb96da115d3d0926b137ff411dd6074 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 28 Feb 2021 04:00:00 +1000 Subject: [PATCH] GPU: Fix previous frame adaptive downsample leaking in --- src/common/vulkan/texture.h | 3 +++ src/core/gpu_hw_d3d11.cpp | 7 +++++++ src/core/gpu_hw_vulkan.cpp | 31 +++++++++++++++++-------------- src/core/gpu_hw_vulkan.h | 3 ++- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/common/vulkan/texture.h b/src/common/vulkan/texture.h index 2f1f0cc80..232220ca2 100644 --- a/src/common/vulkan/texture.h +++ b/src/common/vulkan/texture.h @@ -6,6 +6,7 @@ #pragma once #include "../types.h" #include "vulkan_loader.h" +#include #include namespace Vulkan { @@ -29,6 +30,8 @@ public: ALWAYS_INLINE u32 GetHeight() const { return m_height; } ALWAYS_INLINE u32 GetLevels() const { return m_levels; } ALWAYS_INLINE u32 GetLayers() const { return m_layers; } + ALWAYS_INLINE u32 GetMipWidth(u32 level) const { return std::max(m_width >> level, 1u); } + ALWAYS_INLINE u32 GetMipHeight(u32 level) const { return std::max(m_height >> level, 1u); } ALWAYS_INLINE VkFormat GetFormat() const { return m_format; } ALWAYS_INLINE VkSampleCountFlagBits GetSamples() const { return m_samples; } ALWAYS_INLINE VkImageLayout GetLayout() const { return m_layout; } diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 018a1dd5a..11b398623 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -1149,7 +1149,10 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11::Texture& source, u32 lef const u32 levels = m_downsample_texture.GetLevels(); for (u32 level = 1; level < levels; level++) { + static constexpr float clear_color[4] = {}; + SetViewportAndScissor(left >> level, top >> level, width >> level, height >> level); + m_context->ClearRenderTargetView(m_downsample_mip_views[level].second.Get(), clear_color); m_context->OMSetRenderTargets(1, m_downsample_mip_views[level].second.GetAddressOf(), nullptr); m_context->PSSetShaderResources(0, 1, m_downsample_mip_views[level - 1].first.GetAddressOf()); @@ -1164,8 +1167,10 @@ void GPU_HW_D3D11::DownsampleFramebufferAdaptive(D3D11::Texture& source, u32 lef // blur pass at lowest level { const u32 last_level = levels - 1; + static constexpr float clear_color[4] = {}; SetViewportAndScissor(left >> last_level, top >> last_level, width >> last_level, height >> last_level); + m_context->ClearRenderTargetView(m_downsample_weight_texture.GetD3DRTV(), clear_color); m_context->OMSetRenderTargets(1, m_downsample_weight_texture.GetD3DRTVArray(), nullptr); m_context->PSSetShaderResources(0, 1, m_downsample_mip_views.back().first.GetAddressOf()); m_context->PSSetShader(m_downsample_blur_pass_pixel_shader.Get(), nullptr, 0); @@ -1208,7 +1213,9 @@ void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(D3D11::Texture& source, u32 le const u32 ds_top = top / m_resolution_scale; const u32 ds_width = width / m_resolution_scale; const u32 ds_height = height / m_resolution_scale; + static constexpr float clear_color[4] = {}; + m_context->ClearRenderTargetView(m_downsample_texture.GetD3DRTV(), clear_color); m_context->OMSetDepthStencilState(m_depth_disabled_state.Get(), 0); m_context->OMSetRenderTargets(1, m_downsample_texture.GetD3DRTVArray(), nullptr); m_context->OMSetBlendState(m_blend_disabled_state.Get(), nullptr, 0xFFFFFFFFu); diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index 93a0edbe5..6df0d7229 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -372,7 +372,7 @@ void GPU_HW_Vulkan::DestroyResources() } void GPU_HW_Vulkan::BeginRenderPass(VkRenderPass render_pass, VkFramebuffer framebuffer, u32 x, u32 y, u32 width, - u32 height) + u32 height, const VkClearValue* clear_value /* = nullptr */) { DebugAssert(m_current_render_pass == VK_NULL_HANDLE); @@ -381,8 +381,8 @@ void GPU_HW_Vulkan::BeginRenderPass(VkRenderPass render_pass, VkFramebuffer fram render_pass, framebuffer, {{static_cast(x), static_cast(y)}, {width, height}}, - 0u, - nullptr}; + (clear_value ? 1u : 0u), + clear_value}; vkCmdBeginRenderPass(g_vulkan_context->GetCurrentCommandBuffer(), &bi, VK_SUBPASS_CONTENTS_INLINE); m_current_render_pass = render_pass; } @@ -620,10 +620,9 @@ bool GPU_HW_Vulkan::CreateFramebuffer() m_downsample_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); m_downsample_render_pass = g_vulkan_context->GetRenderPass(m_downsample_texture.GetFormat(), VK_FORMAT_UNDEFINED, - VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE); - m_downsample_weight_render_pass = - g_vulkan_context->GetRenderPass(m_downsample_weight_texture.GetFormat(), VK_FORMAT_UNDEFINED, - VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE); + VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR); + m_downsample_weight_render_pass = g_vulkan_context->GetRenderPass( + m_downsample_weight_texture.GetFormat(), VK_FORMAT_UNDEFINED, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR); if (m_downsample_render_pass == VK_NULL_HANDLE || m_downsample_weight_render_pass == VK_NULL_HANDLE) return false; @@ -693,7 +692,7 @@ bool GPU_HW_Vulkan::CreateFramebuffer() } m_downsample_render_pass = g_vulkan_context->GetRenderPass(m_downsample_texture.GetFormat(), VK_FORMAT_UNDEFINED, - VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_DONT_CARE); + VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR); m_downsample_mip_views.resize(1); m_downsample_mip_views[0].framebuffer = m_downsample_texture.CreateFramebuffer(m_downsample_render_pass); @@ -1789,8 +1788,9 @@ void GPU_HW_Vulkan::DownsampleFramebufferBoxFilter(Vulkan::Texture& source, u32 const u32 ds_width = width / m_resolution_scale; const u32 ds_height = height / m_resolution_scale; - BeginRenderPass(m_downsample_render_pass, m_downsample_mip_views[0].framebuffer, ds_left, ds_top, ds_width, - ds_height); + static constexpr VkClearValue clear_color = {}; + BeginRenderPass(m_downsample_render_pass, m_downsample_mip_views[0].framebuffer, ds_left, ds_top, ds_width, ds_height, + &clear_color); Vulkan::Util::SetViewportAndScissor(cmdbuf, ds_left, ds_top, ds_width, ds_height); vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_downsample_first_pass_pipeline); vkCmdBindDescriptorSets(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_single_sampler_pipeline_layout, 0, 1, &ds, 0, @@ -1832,8 +1832,9 @@ void GPU_HW_Vulkan::DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 l m_downsample_texture.TransitionSubresourcesToLayout( cmdbuf, level, 1, 0, 1, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - BeginRenderPass(m_downsample_render_pass, m_downsample_mip_views[level].framebuffer, left >> level, top >> level, - width >> level, height >> level); + static constexpr VkClearValue clear_color = {}; + BeginRenderPass(m_downsample_render_pass, m_downsample_mip_views[level].framebuffer, 0, 0, + m_downsample_texture.GetMipWidth(level), m_downsample_texture.GetMipHeight(level), &clear_color); Vulkan::Util::SetViewportAndScissor(cmdbuf, left >> level, top >> level, width >> level, height >> level); vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, (level == 1) ? m_downsample_first_pass_pipeline : m_downsample_mid_pass_pipeline); @@ -1859,8 +1860,10 @@ void GPU_HW_Vulkan::DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 l m_downsample_weight_texture.TransitionToLayout(cmdbuf, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - BeginRenderPass(m_downsample_weight_render_pass, m_downsample_weight_framebuffer, left >> last_level, - top >> last_level, width >> last_level, height >> last_level); + static constexpr VkClearValue clear_color = {}; + BeginRenderPass(m_downsample_weight_render_pass, m_downsample_weight_framebuffer, 0, 0, + m_downsample_texture.GetMipWidth(last_level), m_downsample_texture.GetMipHeight(last_level), + &clear_color); Vulkan::Util::SetViewportAndScissor(cmdbuf, left >> last_level, top >> last_level, width >> last_level, height >> last_level); vkCmdBindPipeline(cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, m_downsample_blur_pass_pipeline); diff --git a/src/core/gpu_hw_vulkan.h b/src/core/gpu_hw_vulkan.h index 5d7ccb846..a09bad3e6 100644 --- a/src/core/gpu_hw_vulkan.h +++ b/src/core/gpu_hw_vulkan.h @@ -49,7 +49,8 @@ private: void DestroyResources(); ALWAYS_INLINE bool InRenderPass() const { return (m_current_render_pass != VK_NULL_HANDLE); } - void BeginRenderPass(VkRenderPass render_pass, VkFramebuffer framebuffer, u32 x, u32 y, u32 width, u32 height); + void BeginRenderPass(VkRenderPass render_pass, VkFramebuffer framebuffer, u32 x, u32 y, u32 width, u32 height, + const VkClearValue* clear_value = nullptr); void BeginVRAMRenderPass(); void EndRenderPass();