From 0e50b2c9f23c71f25866a1d4d14ea1b1b8a36e7d Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 8 Dec 2017 17:55:33 +1000 Subject: Vulkan: Add missing layout transition when resolving MSAA depth buffers --- Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 94f773fb94..84127f37db 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -529,6 +529,8 @@ Texture2D* FramebufferManager::ResolveEFBDepthTexture(const VkRect2D& region) m_efb_depth_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + m_efb_resolve_depth_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // Draw using resolve shader to write the minimum depth of all samples to the resolve texture. UtilityShaderDraw draw(g_command_buffer_mgr->GetCurrentCommandBuffer(), @@ -546,8 +548,6 @@ Texture2D* FramebufferManager::ResolveEFBDepthTexture(const VkRect2D& region) m_efb_depth_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - // Render pass transitions to shader resource. - m_efb_resolve_depth_texture->OverrideImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); return m_efb_resolve_depth_texture.get(); } -- cgit v1.2.3 From 173a33886c72304aea923382ec114679dcad6ba4 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 9 Sep 2017 14:04:26 +1000 Subject: Vulkan: Move render pass management to ObjectCache --- .../VideoBackends/Vulkan/FramebufferManager.cpp | 194 ++------------------- 1 file changed, 18 insertions(+), 176 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 84127f37db..8befba821a 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -40,14 +40,12 @@ FramebufferManager::FramebufferManager() FramebufferManager::~FramebufferManager() { DestroyEFBFramebuffer(); - DestroyEFBRenderPass(); DestroyConversionShaders(); DestroyReadbackFramebuffer(); DestroyReadbackTextures(); DestroyReadbackShaders(); - DestroyReadbackRenderPasses(); DestroyPokeVertexBuffer(); DestroyPokeShaders(); @@ -88,7 +86,7 @@ MultisamplingState FramebufferManager::GetEFBMultisamplingState() const bool FramebufferManager::Initialize() { - if (!CreateEFBRenderPass()) + if (!CreateEFBRenderPasses()) { PanicAlert("Failed to create EFB render pass"); return false; @@ -142,108 +140,18 @@ bool FramebufferManager::Initialize() return true; } -bool FramebufferManager::CreateEFBRenderPass() +bool FramebufferManager::CreateEFBRenderPasses() { - VkSampleCountFlagBits samples = static_cast(g_ActiveConfig.iMultisamples); - - // render pass for rendering to the efb - VkAttachmentDescription attachments[] = { - {0, EFB_COLOR_TEXTURE_FORMAT, samples, VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}, - {0, EFB_DEPTH_TEXTURE_FORMAT, samples, VK_ATTACHMENT_LOAD_OP_LOAD, - VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}}; - - VkAttachmentReference color_attachment_references[] = { - {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}}; - - VkAttachmentReference depth_attachment_reference = { - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpass_description = { - 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, color_attachment_references, - nullptr, &depth_attachment_reference, 0, nullptr}; - - VkRenderPassCreateInfo pass_info = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - nullptr, - 0, - static_cast(ArraySize(attachments)), - attachments, - 1, - &subpass_description, - 0, - nullptr}; - - VkResult res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &pass_info, nullptr, - &m_efb_load_render_pass); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateRenderPass (EFB) failed: "); - return false; - } - - // render pass for clearing color/depth on load, as opposed to loading it - attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; - res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &pass_info, nullptr, - &m_efb_clear_render_pass); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateRenderPass (EFB) failed: "); - return false; - } - - // render pass for resolving depth, since we can't do it with vkCmdResolveImage - if (g_ActiveConfig.MultisamplingEnabled()) - { - VkAttachmentDescription resolve_attachment = {0, - EFB_DEPTH_AS_COLOR_TEXTURE_FORMAT, - VK_SAMPLE_COUNT_1_BIT, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_STORE, - VK_ATTACHMENT_LOAD_OP_DONT_CARE, - VK_ATTACHMENT_STORE_OP_DONT_CARE, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - subpass_description.pDepthStencilAttachment = nullptr; - pass_info.pAttachments = &resolve_attachment; - pass_info.attachmentCount = 1; - res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &pass_info, nullptr, - &m_depth_resolve_render_pass); - - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateRenderPass (EFB depth resolve) failed: "); - return false; - } - } - - return true; -} - -void FramebufferManager::DestroyEFBRenderPass() -{ - if (m_efb_load_render_pass != VK_NULL_HANDLE) - { - vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_efb_load_render_pass, nullptr); - m_efb_load_render_pass = VK_NULL_HANDLE; - } - - if (m_efb_clear_render_pass != VK_NULL_HANDLE) - { - vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_efb_clear_render_pass, nullptr); - m_efb_clear_render_pass = VK_NULL_HANDLE; - } - - if (m_depth_resolve_render_pass != VK_NULL_HANDLE) - { - vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_depth_resolve_render_pass, nullptr); - m_depth_resolve_render_pass = VK_NULL_HANDLE; - } + m_efb_load_render_pass = + g_object_cache->GetRenderPass(EFB_COLOR_TEXTURE_FORMAT, EFB_DEPTH_TEXTURE_FORMAT, + g_ActiveConfig.iMultisamples, VK_ATTACHMENT_LOAD_OP_LOAD); + m_efb_clear_render_pass = + g_object_cache->GetRenderPass(EFB_COLOR_TEXTURE_FORMAT, EFB_DEPTH_TEXTURE_FORMAT, + g_ActiveConfig.iMultisamples, VK_ATTACHMENT_LOAD_OP_CLEAR); + m_depth_resolve_render_pass = g_object_cache->GetRenderPass( + EFB_DEPTH_AS_COLOR_TEXTURE_FORMAT, VK_FORMAT_UNDEFINED, 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE); + return m_efb_load_render_pass != VK_NULL_HANDLE && m_efb_clear_render_pass != VK_NULL_HANDLE && + m_depth_resolve_render_pass != VK_NULL_HANDLE; } bool FramebufferManager::CreateEFBFramebuffer() @@ -419,9 +327,7 @@ void FramebufferManager::ResizeEFBTextures() void FramebufferManager::RecreateRenderPass() { - DestroyEFBRenderPass(); - - if (!CreateEFBRenderPass()) + if (!CreateEFBRenderPasses()) PanicAlert("Failed to create EFB render pass"); } @@ -849,62 +755,12 @@ void FramebufferManager::InvalidatePeekCache() bool FramebufferManager::CreateReadbackRenderPasses() { - VkAttachmentDescription copy_attachment = { - 0, // VkAttachmentDescriptionFlags flags - EFB_COLOR_TEXTURE_FORMAT, // VkFormat format - VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples - VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp - VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp - VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp - VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout - }; - VkAttachmentReference copy_attachment_ref = { - 0, // uint32_t attachment - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout - }; - VkSubpassDescription copy_subpass = { - 0, // VkSubpassDescriptionFlags flags - VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint - 0, // uint32_t inputAttachmentCount - nullptr, // const VkAttachmentReference* pInputAttachments - 1, // uint32_t colorAttachmentCount - ©_attachment_ref, // const VkAttachmentReference* pColorAttachments - nullptr, // const VkAttachmentReference* pResolveAttachments - nullptr, // const VkAttachmentReference* pDepthStencilAttachment - 0, // uint32_t preserveAttachmentCount - nullptr // const uint32_t* pPreserveAttachments - }; - VkRenderPassCreateInfo copy_pass = { - VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType - nullptr, // const void* pNext - 0, // VkRenderPassCreateFlags flags - 1, // uint32_t attachmentCount - ©_attachment, // const VkAttachmentDescription* pAttachments - 1, // uint32_t subpassCount - ©_subpass, // const VkSubpassDescription* pSubpasses - 0, // uint32_t dependencyCount - nullptr // const VkSubpassDependency* pDependencies - }; - - VkResult res = vkCreateRenderPass(g_vulkan_context->GetDevice(), ©_pass, nullptr, - &m_copy_color_render_pass); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: "); + m_copy_color_render_pass = g_object_cache->GetRenderPass( + EFB_COLOR_TEXTURE_FORMAT, VK_FORMAT_UNDEFINED, 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE); + m_copy_depth_render_pass = g_object_cache->GetRenderPass( + EFB_DEPTH_AS_COLOR_TEXTURE_FORMAT, VK_FORMAT_UNDEFINED, 1, VK_ATTACHMENT_LOAD_OP_DONT_CARE); + if (m_copy_color_render_pass == VK_NULL_HANDLE || m_copy_depth_render_pass == VK_NULL_HANDLE) return false; - } - - // Depth is similar to copy, just a different format. - copy_attachment.format = EFB_DEPTH_AS_COLOR_TEXTURE_FORMAT; - res = vkCreateRenderPass(g_vulkan_context->GetDevice(), ©_pass, nullptr, - &m_copy_depth_render_pass); - if (res != VK_SUCCESS) - { - LOG_VULKAN_ERROR(res, "vkCreateRenderPass failed: "); - return false; - } // Some devices don't support point sizes >1 (e.g. Adreno). // If we can't use a point size above our maximum IR, use triangles instead. @@ -925,20 +781,6 @@ bool FramebufferManager::CreateReadbackRenderPasses() return true; } -void FramebufferManager::DestroyReadbackRenderPasses() -{ - if (m_copy_color_render_pass != VK_NULL_HANDLE) - { - vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_color_render_pass, nullptr); - m_copy_color_render_pass = VK_NULL_HANDLE; - } - if (m_copy_depth_render_pass != VK_NULL_HANDLE) - { - vkDestroyRenderPass(g_vulkan_context->GetDevice(), m_copy_depth_render_pass, nullptr); - m_copy_depth_render_pass = VK_NULL_HANDLE; - } -} - bool FramebufferManager::CompileReadbackShaders() { std::string source; -- cgit v1.2.3 From 48a8063cd5e0b6bce6d152ea8b2bd213bb954244 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 11 Jan 2018 15:30:27 +1000 Subject: Vulkan: Fix FramebufferManagerBase::m_EFBLayers being set out-of-range --- Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 8befba821a..53302bb544 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -164,7 +164,7 @@ bool FramebufferManager::CreateEFBFramebuffer() INFO_LOG(VIDEO, "EFB size: %ux%ux%u", efb_width, efb_height, efb_layers); // Update the static variable in the base class. Why does this even exist? - FramebufferManagerBase::m_EFBLayers = g_ActiveConfig.iMultisamples; + FramebufferManagerBase::m_EFBLayers = efb_layers; // Allocate EFB render targets m_efb_color_texture = -- cgit v1.2.3 From 05257263381c0db9e42f8911cd4c9068fe593ab8 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 11 Jan 2018 15:36:01 +1000 Subject: Vulkan: Move pipeline barrier outside render pass for EFB peeks --- Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index 53302bb544..bf13701600 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -621,6 +621,9 @@ bool FramebufferManager::PopulateColorReadbackTexture() if (GetEFBWidth() != EFB_WIDTH || GetEFBHeight() != EFB_HEIGHT) { + // Transition EFB to shader read before drawing. + src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); m_color_copy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); @@ -631,10 +634,6 @@ bool FramebufferManager::PopulateColorReadbackTexture() VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}}; draw.BeginRenderPass(m_color_copy_framebuffer, rect); - - // Transition EFB to shader read before drawing. - src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetPointSampler()); draw.SetViewportAndScissor(0, 0, EFB_WIDTH, EFB_HEIGHT); draw.DrawWithoutVertexBuffer(4); @@ -697,6 +696,9 @@ bool FramebufferManager::PopulateDepthReadbackTexture() } if (GetEFBWidth() != EFB_WIDTH || GetEFBHeight() != EFB_HEIGHT) { + // Transition EFB to shader read before drawing. + src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); m_depth_copy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); @@ -707,10 +709,6 @@ bool FramebufferManager::PopulateDepthReadbackTexture() VkRect2D rect = {{0, 0}, {EFB_WIDTH, EFB_HEIGHT}}; draw.BeginRenderPass(m_depth_copy_framebuffer, rect); - - // Transition EFB to shader read before drawing. - src_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); draw.SetPSSampler(0, src_texture->GetView(), g_object_cache->GetPointSampler()); draw.SetViewportAndScissor(0, 0, EFB_WIDTH, EFB_HEIGHT); draw.DrawWithoutVertexBuffer(4); -- cgit v1.2.3 From 4997fbce44f9d092c503ce34f92faafb1af1dd44 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 11 Jan 2018 16:02:31 +1000 Subject: Vulkan: Fix possible mismatch between EFB framebuffer and render pass This could happen when changing MSAA settings or internal resolution at runtime. --- Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp') diff --git a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp index bf13701600..9c2c712837 100644 --- a/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp @@ -318,17 +318,15 @@ void FramebufferManager::DestroyEFBFramebuffer() m_efb_resolve_depth_texture.reset(); } -void FramebufferManager::ResizeEFBTextures() +void FramebufferManager::RecreateEFBFramebuffer() { DestroyEFBFramebuffer(); - if (!CreateEFBFramebuffer()) - PanicAlert("Failed to create EFB textures"); -} -void FramebufferManager::RecreateRenderPass() -{ if (!CreateEFBRenderPasses()) PanicAlert("Failed to create EFB render pass"); + + if (!CreateEFBFramebuffer()) + PanicAlert("Failed to create EFB textures"); } void FramebufferManager::RecompileShaders() -- cgit v1.2.3