230 lines
6.9 KiB
C++
230 lines
6.9 KiB
C++
#include "renderpassmgr.h"
|
|
|
|
void CRenderPassMgr::CreateRenderPass(BeginInfo *pBeginInfo, VkRenderPass *prp, VkFramebuffer *pfb)
|
|
{
|
|
RenderPassHandle *pRP = FindRenderPass(pBeginInfo);
|
|
|
|
*prp = pRP->renderpass;
|
|
if (pRP->framebuffer)
|
|
{
|
|
if (pRP->uWidth != pBeginInfo->uWidth)
|
|
goto recreate;
|
|
if (pRP->uHeight != pBeginInfo->uHeight)
|
|
goto recreate;
|
|
for (uint32_t i = 0; i < pRP->usages.GetSize(); i++)
|
|
{
|
|
RenderPassUsage *u = &pRP->usages[i];
|
|
RenderImage *im = &pBeginInfo->pRenderImages[i];
|
|
CVkImage *vku = (CVkImage*)u->pImage;
|
|
CVkImage *imu = (CVkImage*)im->pImage;
|
|
if (vku != imu)
|
|
goto recreate;
|
|
if (vku->m_imageView != imu->m_imageView)
|
|
goto recreate;
|
|
}
|
|
if (pRP->bIsDepth)
|
|
{
|
|
|
|
CVkImage *vku = (CVkImage*)pRP->depth.pImage;
|
|
CVkImage *imu = (CVkImage*)pBeginInfo->pDepth->pImage;
|
|
if (vku != imu)
|
|
goto recreate;
|
|
if (vku->m_imageView != imu->m_imageView)
|
|
goto recreate;
|
|
}
|
|
*pfb = pRP->framebuffer;
|
|
return;
|
|
recreate:
|
|
m_scheduledReleasesFB.AppendTail(pRP->framebuffer);
|
|
}
|
|
|
|
CUtlVector<VkImageView> image_views = {};
|
|
for (uint32_t i = 0; i < pRP->usages.GetSize(); i++)
|
|
{
|
|
RenderPassUsage *u = &pRP->usages[i];
|
|
RenderImage *im = &pBeginInfo->pRenderImages[i];
|
|
CVkImage *imu = (CVkImage*)im->pImage;
|
|
u->pImage = imu;
|
|
image_views.AppendTail(imu->m_imageView);
|
|
}
|
|
if (pRP->bIsDepth)
|
|
{
|
|
CVkImage *imu = (CVkImage*)pBeginInfo->pDepth->pImage;
|
|
pRP->depth.pImage = imu;
|
|
image_views.AppendTail(imu->m_imageView);
|
|
}
|
|
image_views.Reserve(pBeginInfo->uRenderImageCount);
|
|
VkFramebufferCreateInfo fbci = {};
|
|
fbci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
|
fbci.renderPass = pRP->renderpass;
|
|
fbci.attachmentCount = image_views.GetSize();
|
|
fbci.pAttachments = image_views.GetData();
|
|
fbci.width = pBeginInfo->uWidth;
|
|
fbci.height = pBeginInfo->uHeight;
|
|
fbci.layers = 1;
|
|
vkCreateFramebuffer(m_hDevice, &fbci, NULL, &pRP->framebuffer);
|
|
pRP->uWidth = pBeginInfo->uWidth;
|
|
pRP->uHeight = pBeginInfo->uHeight;
|
|
*pfb = pRP->framebuffer;
|
|
}
|
|
|
|
void CRenderPassMgr::Frame()
|
|
{
|
|
CUtlVector<RenderPassHandle> renderPassHandles = {};
|
|
for (auto &r: m_renderPassHandles)
|
|
{
|
|
if (r.bIsUsed)
|
|
{
|
|
renderPassHandles.AppendTail(r);
|
|
r.bIsUsed = false;
|
|
}
|
|
else
|
|
{
|
|
m_scheduledReleasesRP.AppendTail(r.renderpass);
|
|
m_scheduledReleasesFB.AppendTail(r.framebuffer);
|
|
}
|
|
|
|
}
|
|
m_renderPassHandles = renderPassHandles;
|
|
|
|
for (auto fb: m_scheduledReleasesFB)
|
|
{
|
|
vkDestroyFramebuffer(m_hDevice, fb, NULL);
|
|
}
|
|
for (auto rp: m_scheduledReleasesRP)
|
|
{
|
|
vkDestroyRenderPass(m_hDevice, rp, NULL);
|
|
}
|
|
m_scheduledReleasesFB = {};
|
|
m_scheduledReleasesRP = {};
|
|
|
|
}
|
|
RenderPassHandle *CRenderPassMgr::FindRenderPass(BeginInfo *pBeginInfo)
|
|
{
|
|
for (auto &r: m_renderPassHandles)
|
|
{
|
|
if (!(pBeginInfo->pDepth && r.bIsDepth))
|
|
continue;
|
|
if (pBeginInfo->uRenderImageCount != r.usages.GetSize())
|
|
continue;
|
|
for (uint32_t i = 0; i < r.usages.GetSize(); i++)
|
|
{
|
|
RenderPassUsage *u = &r.usages[i];
|
|
RenderImage *im = &pBeginInfo->pRenderImages[i];
|
|
if (u->eLoadMode != im->eLoadMode)
|
|
goto next_usage;
|
|
if (u->eStoreMode != im->eStoreMode)
|
|
goto next_usage;
|
|
if (u->eFormat != im->pImage->GetImageFormat())
|
|
goto next_usage;
|
|
if (u->eMultisampleType != im->pImage->GetMultisampleType())
|
|
goto next_usage;
|
|
}
|
|
r.bIsUsed = true;
|
|
return &r;
|
|
next_usage:
|
|
continue;
|
|
}
|
|
|
|
VkRenderPass hRenderPass = NULL;
|
|
CUtlVector<VkAttachmentDescription> attachments = {};
|
|
CUtlVector<VkAttachmentReference> input_refs = {};
|
|
attachments.Resize(pBeginInfo->uRenderImageCount);
|
|
input_refs.Resize(pBeginInfo->uRenderImageCount);
|
|
uint32_t i = 0;
|
|
|
|
for (uint32_t i = 0; i < pBeginInfo->uRenderImageCount; i++)
|
|
{
|
|
RenderImage *ri = pBeginInfo->pRenderImages+i;
|
|
|
|
VkAttachmentDescription a = {};
|
|
a.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
a.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
a.format = CVkImage::GetImageFormat(ri->pImage->GetImageFormat());
|
|
a.samples = CVkImage::GetMultisampling(ri->pImage->GetMultisampleType());
|
|
|
|
V_printf("INTERNAL IMAGE %p\n",ri->pImage);
|
|
V_printf(" %u\n",ri->pImage->GetImageFormat());
|
|
V_printf(" %u\n",ri->pImage->GetMultisampleType());
|
|
switch( ri->eLoadMode )
|
|
{
|
|
case LOAD_MODE_DONT_CARE:
|
|
a.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
break;
|
|
case LOAD_MODE_LOAD:
|
|
a.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
|
break;
|
|
case LOAD_MODE_CLEAR:
|
|
a.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
break;
|
|
}
|
|
a.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
attachments[i] = a;
|
|
|
|
VkAttachmentReference ref = {};
|
|
ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
ref.attachment = i;
|
|
input_refs[i] = ref;
|
|
|
|
}
|
|
if (pBeginInfo->pDepth)
|
|
{
|
|
CVkImage *depth = (CVkImage*)pBeginInfo->pDepth->pImage;
|
|
VkAttachmentDescription desc = {};
|
|
desc.format = CVkImage::GetImageFormat(depth->GetImageFormat());
|
|
desc.samples = CVkImage::GetMultisampling(depth->GetMultisampleType());
|
|
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
|
|
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
|
|
desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
attachments.AppendTail(desc);
|
|
}
|
|
VkAttachmentReference depthRef;
|
|
depthRef.attachment = attachments.GetSize() - 1;
|
|
depthRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
VkSubpassDescription subpass = {};
|
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
subpass.colorAttachmentCount = input_refs.GetSize();
|
|
subpass.pColorAttachments = input_refs.GetData();
|
|
if (pBeginInfo->pDepth)
|
|
{
|
|
subpass.pDepthStencilAttachment = &depthRef;
|
|
}
|
|
VkRenderPassCreateInfo rpci = {};
|
|
rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
|
rpci.attachmentCount = attachments.GetSize();
|
|
rpci.pAttachments = attachments.GetData();
|
|
rpci.subpassCount = 1;
|
|
rpci.pSubpasses = &subpass;
|
|
vkCreateRenderPass(m_hDevice, &rpci, NULL, &hRenderPass);
|
|
|
|
RenderPassHandle hHandle = {};
|
|
if (pBeginInfo->pDepth)
|
|
{
|
|
V_printf("DEPTH %p\n", pBeginInfo->pDepth->pImage);
|
|
hHandle.depth.pImage = pBeginInfo->pDepth->pImage;
|
|
hHandle.depth.eMultisampleType = pBeginInfo->pDepth->pImage->GetMultisampleType();
|
|
hHandle.depth.eFormat = pBeginInfo->pDepth->pImage->GetImageFormat();
|
|
hHandle.depth.eLoadMode = pBeginInfo->pDepth->eLoadMode;
|
|
hHandle.depth.eStoreMode = pBeginInfo->pDepth->eStoreMode;
|
|
hHandle.bIsDepth = true;
|
|
}
|
|
for (uint32_t i = 0; i < pBeginInfo->uRenderImageCount; i++)
|
|
{
|
|
RenderPassUsage hUsage = {};
|
|
RenderImage *ri = pBeginInfo->pRenderImages+i;
|
|
hUsage.pImage = ri->pImage;
|
|
hUsage.eMultisampleType = ri->pImage->GetMultisampleType();
|
|
hUsage.eFormat = ri->pImage->GetImageFormat();
|
|
hUsage.eLoadMode = ri->eLoadMode;
|
|
hUsage.eStoreMode = ri->eStoreMode;
|
|
hHandle.usages.AppendTail(hUsage);
|
|
}
|
|
hHandle.bIsUsed = true;
|
|
hHandle.renderpass = hRenderPass;
|
|
m_renderPassHandles.AppendTail(hHandle);
|
|
return &m_renderPassHandles[m_renderPassHandles.GetSize()-1];
|
|
}
|