- add depth/stencil attachment to the render pass

This commit is contained in:
Magnus Norddahl 2019-03-01 21:34:08 +01:00
parent d73b0b3146
commit 7871ec06ae
5 changed files with 106 additions and 18 deletions

View file

@ -154,18 +154,36 @@ void VkRenderPassManager::CreateDynamicSet()
VkRenderPassSetup::VkRenderPassSetup(const VkRenderPassKey &key)
{
CreateRenderPass();
CreateRenderPass(key);
CreatePipeline(key);
CreateFramebuffer();
CreateFramebuffer(key);
}
void VkRenderPassSetup::CreateRenderPass()
void VkRenderPassSetup::CreateRenderPass(const VkRenderPassKey &key)
{
RenderPassBuilder builder;
builder.addRgba16fAttachment(false, VK_IMAGE_LAYOUT_GENERAL);
if (key.DepthTest || key.DepthWrite)
builder.addDepthStencilAttachment(false, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.addSubpass();
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_GENERAL);
builder.addExternalSubpassDependency();
if (key.DepthTest || key.DepthWrite)
{
builder.addSubpassDepthStencilAttachmentRef(1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
builder.addExternalSubpassDependency(
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
}
else
{
builder.addExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT);
}
RenderPass = builder.create(GetVulkanFrameBuffer()->device);
}
@ -265,6 +283,8 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
blendequation = VK_BLEND_OP_ADD;
}
builder.setDepthEnable(key.DepthTest, key.DepthWrite);
builder.setBlendMode((VkBlendOp)blendequation, (VkBlendFactor)srcblend, (VkBlendFactor)dstblend);
builder.setLayout(fb->GetRenderPassManager()->PipelineLayout.get());
@ -272,12 +292,14 @@ void VkRenderPassSetup::CreatePipeline(const VkRenderPassKey &key)
Pipeline = builder.create(fb->device);
}
void VkRenderPassSetup::CreateFramebuffer()
void VkRenderPassSetup::CreateFramebuffer(const VkRenderPassKey &key)
{
auto fb = GetVulkanFrameBuffer();
FramebufferBuilder builder;
builder.setRenderPass(RenderPass.get());
builder.setSize(SCREENWIDTH, SCREENHEIGHT);
builder.addAttachment(fb->GetRenderPassManager()->SceneColorView.get());
if (key.DepthTest || key.DepthWrite)
builder.addAttachment(fb->GetRenderPassManager()->SceneDepthStencilView.get());
Framebuffer = builder.create(GetVulkanFrameBuffer()->device);
}

View file

@ -15,6 +15,8 @@ public:
int SpecialEffect;
int EffectState;
int AlphaTest;
int DepthWrite;
int DepthTest;
int VertexFormat;
int DrawType;
@ -35,8 +37,8 @@ public:
private:
void CreatePipeline(const VkRenderPassKey &key);
void CreateRenderPass();
void CreateFramebuffer();
void CreateRenderPass(const VkRenderPassKey &key);
void CreateFramebuffer(const VkRenderPassKey &key);
};
class VkVertexFormat

View file

@ -97,6 +97,63 @@ void VkRenderState::EnableClipDistance(int num, bool state)
void VkRenderState::Clear(int targets)
{
// We need an active render pass, and it must have a depth attachment..
bool lastDepthTest = mDepthTest;
bool lastDepthWrite = mDepthWrite;
if (targets & (CT_Depth | CT_Stencil))
{
mDepthTest = true;
mDepthWrite = true;
}
Apply(DT_TriangleFan);
mDepthTest = lastDepthTest;
mDepthWrite = lastDepthWrite;
VkClearAttachment attachments[2] = { };
VkClearRect rects[2] = { };
for (int i = 0; i < 2; i++)
{
rects[i].layerCount = 1;
if (mScissorWidth >= 0)
{
rects[0].rect.offset.x = mScissorX;
rects[0].rect.offset.y = mScissorY;
rects[0].rect.extent.width = mScissorWidth;
rects[0].rect.extent.height = mScissorHeight;
}
else
{
rects[0].rect.offset.x = 0;
rects[0].rect.offset.y = 0;
rects[0].rect.extent.width = SCREENWIDTH;
rects[0].rect.extent.height = SCREENHEIGHT;
}
}
if (targets & CT_Depth)
{
attachments[1].aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
attachments[1].clearValue.depthStencil.depth = 1.0f;
}
if (targets & CT_Stencil)
{
attachments[1].aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
attachments[1].clearValue.depthStencil.stencil = 0;
}
if (targets & CT_Color)
{
attachments[0].aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT;
for (int i = 0; i < 4; i++)
attachments[0].clearValue.color.float32[i] = screen->mSceneClearColor[i];
}
if ((targets & CT_Color) && (targets & CT_Stencil) && (targets & CT_Depth))
mCommandBuffer->clearAttachments(2, attachments, 2, rects);
else if (targets & (CT_Stencil | CT_Depth))
mCommandBuffer->clearAttachments(1, attachments + 1, 1, rects + 1);
else if (targets & CT_Color)
mCommandBuffer->clearAttachments(1, attachments, 1, rects);
}
void VkRenderState::EnableStencil(bool on)
@ -123,6 +180,8 @@ void VkRenderState::SetViewport(int x, int y, int w, int h)
void VkRenderState::EnableDepthTest(bool on)
{
mDepthTest = on;
mDepthWrite = on;
}
void VkRenderState::EnableMultisampling(bool on)
@ -153,6 +212,8 @@ void VkRenderState::Apply(int dt)
passKey.DrawType = dt;
passKey.VertexFormat = static_cast<VKVertexBuffer*>(mVertexBuffer)->VertexFormat;
passKey.RenderStyle = mRenderStyle;
passKey.DepthTest = mDepthTest;
passKey.DepthWrite = mDepthWrite;
if (mSpecialEffect > EFF_NONE)
{
passKey.SpecialEffect = mSpecialEffect;

View file

@ -58,6 +58,9 @@ private:
bool mScissorChanged = true;
bool mViewportChanged = true;
bool mDepthTest = false;
bool mDepthWrite = false;
MatricesUBO mMatrices = {};
ColorsUBO mColors = {};
GlowingWallsUBO mGlowingWalls = {};

View file

@ -247,13 +247,13 @@ public:
void addRgba16fAttachment(bool clear, VkImageLayout layout) { addColorAttachment(clear, VK_FORMAT_R16G16B16A16_SFLOAT, layout); }
void addColorAttachment(bool clear, VkFormat format, VkImageLayout layout);
void addDepthAttachment(bool clear, VkImageLayout layout);
void addDepthStencilAttachment(bool clear, VkImageLayout layout);
void addExternalSubpassDependency();
void addExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask);
void addSubpass();
void addSubpassColorAttachmentRef(uint32_t index, VkImageLayout layout);
void addSubpassDepthAttachmentRef(uint32_t index, VkImageLayout layout);
void addSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout);
std::unique_ptr<VulkanRenderPass> create(VulkanDevice *device);
@ -936,10 +936,10 @@ inline void RenderPassBuilder::addColorAttachment(bool clear, VkFormat format, V
renderPassInfo.attachmentCount = (uint32_t)attachments.size();
}
inline void RenderPassBuilder::addDepthAttachment(bool clear, VkImageLayout layout)
inline void RenderPassBuilder::addDepthStencilAttachment(bool clear, VkImageLayout layout)
{
VkAttachmentDescription depthAttachment = {};
depthAttachment.format = VK_FORMAT_D32_SFLOAT;
depthAttachment.format = VK_FORMAT_D32_SFLOAT_S8_UINT;
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.loadOp = clear ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE/*VK_ATTACHMENT_STORE_OP_DONT_CARE*/;
@ -953,15 +953,15 @@ inline void RenderPassBuilder::addDepthAttachment(bool clear, VkImageLayout layo
renderPassInfo.attachmentCount = (uint32_t)attachments.size();
}
inline void RenderPassBuilder::addExternalSubpassDependency()
inline void RenderPassBuilder::addExternalSubpassDependency(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask)
{
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.srcStageMask = srcStageMask;
dependency.srcAccessMask = srcAccessMask;
dependency.dstStageMask = dstStageMask;
dependency.dstAccessMask = dstAccessMask;
dependencies.push_back(dependency);
renderPassInfo.pDependencies = dependencies.data();
@ -991,7 +991,7 @@ inline void RenderPassBuilder::addSubpassColorAttachmentRef(uint32_t index, VkIm
subpasses.back().colorAttachmentCount = (uint32_t)subpassData.back()->colorRefs.size();
}
inline void RenderPassBuilder::addSubpassDepthAttachmentRef(uint32_t index, VkImageLayout layout)
inline void RenderPassBuilder::addSubpassDepthStencilAttachmentRef(uint32_t index, VkImageLayout layout)
{
VkAttachmentReference &depthAttachmentRef = subpassData.back()->depthRef;
depthAttachmentRef.attachment = index;