Vulkan: Move render pass management to ObjectCache

This commit is contained in:
Stenzek
2017-09-09 14:04:26 +10:00
parent 0e50b2c9f2
commit 173a33886c
12 changed files with 178 additions and 376 deletions

View File

@ -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;