summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/FramebufferManager.cpp194
1 files changed, 18 insertions, 176 deletions
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<VkSampleCountFlagBits>(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<u32>(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
- &copy_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
- &copy_attachment, // const VkAttachmentDescription* pAttachments
- 1, // uint32_t subpassCount
- &copy_subpass, // const VkSubpassDescription* pSubpasses
- 0, // uint32_t dependencyCount
- nullptr // const VkSubpassDependency* pDependencies
- };
-
- VkResult res = vkCreateRenderPass(g_vulkan_context->GetDevice(), &copy_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(), &copy_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;