- fix stencil test not being active when applying SSAO to portals

This commit is contained in:
Magnus Norddahl 2019-05-13 22:06:17 +02:00
parent bab5862383
commit 3a112c2a47
2 changed files with 52 additions and 11 deletions

View file

@ -465,9 +465,15 @@ void VkPPRenderState::Draw()
key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT; key.OutputFormat = VK_FORMAT_R16G16B16A16_SFLOAT;
if (Output.Type == PPTextureType::SceneColor) if (Output.Type == PPTextureType::SceneColor)
{
key.StencilTest = 1;
key.Samples = fb->GetBuffers()->GetSceneSamples(); key.Samples = fb->GetBuffers()->GetSceneSamples();
}
else else
{
key.StencilTest = 0;
key.Samples = VK_SAMPLE_COUNT_1_BIT; key.Samples = VK_SAMPLE_COUNT_1_BIT;
}
auto &passSetup = pp->mRenderPassSetup[key]; auto &passSetup = pp->mRenderPassSetup[key];
if (!passSetup) if (!passSetup)
@ -475,9 +481,9 @@ void VkPPRenderState::Draw()
int framebufferWidth = 0, framebufferHeight = 0; int framebufferWidth = 0, framebufferHeight = 0;
VulkanDescriptorSet *input = GetInput(passSetup.get(), Textures, ShadowMapBuffers); VulkanDescriptorSet *input = GetInput(passSetup.get(), Textures, ShadowMapBuffers);
VulkanFramebuffer *output = GetOutput(passSetup.get(), Output, framebufferWidth, framebufferHeight); VulkanFramebuffer *output = GetOutput(passSetup.get(), Output, key.StencilTest, framebufferWidth, framebufferHeight);
RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size()); RenderScreenQuad(passSetup.get(), input, output, framebufferWidth, framebufferHeight, Viewport.left, Viewport.top, Viewport.width, Viewport.height, Uniforms.Data.Data(), Uniforms.Data.Size(), key.StencilTest);
// Advance to next PP texture if our output was sent there // Advance to next PP texture if our output was sent there
if (Output.Type == PPTextureType::NextPipelineTexture) if (Output.Type == PPTextureType::NextPipelineTexture)
@ -486,7 +492,7 @@ void VkPPRenderState::Draw()
} }
} }
void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize) void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize, bool stencilTest)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
auto cmdbuffer = fb->GetDrawCommands(); auto cmdbuffer = fb->GetDrawCommands();
@ -520,6 +526,8 @@ void VkPPRenderState::RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDes
cmdbuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets); cmdbuffer->bindVertexBuffers(0, 1, vertexBuffers, offsets);
cmdbuffer->setViewport(0, 1, &viewport); cmdbuffer->setViewport(0, 1, &viewport);
cmdbuffer->setScissor(0, 1, &scissor); cmdbuffer->setScissor(0, 1, &scissor);
if (stencilTest)
cmdbuffer->setStencilReference(VK_STENCIL_FRONT_AND_BACK, screen->stencilValue);
if (pushConstantsSize > 0) if (pushConstantsSize > 0)
cmdbuffer->pushConstants(passSetup->PipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, pushConstantsSize, pushConstants); cmdbuffer->pushConstants(passSetup->PipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0, pushConstantsSize, pushConstants);
cmdbuffer->draw(4, 1, FFlatVertexBuffer::PRESENT_INDEX, 0); cmdbuffer->draw(4, 1, FFlatVertexBuffer::PRESENT_INDEX, 0);
@ -561,7 +569,7 @@ VulkanDescriptorSet *VkPPRenderState::GetInput(VkPPRenderPassSetup *passSetup, c
return set; return set;
} }
VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight) VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight)
{ {
auto fb = GetVulkanFrameBuffer(); auto fb = GetVulkanFrameBuffer();
@ -573,6 +581,8 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
{ {
VkPPImageTransition imageTransition; VkPPImageTransition imageTransition;
imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture); imageTransition.addImage(tex.image, tex.layout, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, output.Type == PPTextureType::NextPipelineTexture);
if (stencilTest)
imageTransition.addImage(fb->GetBuffers()->SceneDepthStencil.get(), &fb->GetBuffers()->SceneDepthStencilLayout, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, false);
imageTransition.execute(fb->GetDrawCommands()); imageTransition.execute(fb->GetDrawCommands());
view = tex.view->view; view = tex.view->view;
@ -593,6 +603,8 @@ VulkanFramebuffer *VkPPRenderState::GetOutput(VkPPRenderPassSetup *passSetup, co
builder.setRenderPass(passSetup->RenderPass.get()); builder.setRenderPass(passSetup->RenderPass.get());
builder.setSize(w, h); builder.setSize(w, h);
builder.addAttachment(view); builder.addAttachment(view);
if (stencilTest)
builder.addAttachment(fb->GetBuffers()->SceneDepthStencilView.get());
framebuffer = builder.create(GetVulkanFrameBuffer()->device); framebuffer = builder.create(GetVulkanFrameBuffer()->device);
framebuffer->SetDebugName(tex.debugname); framebuffer->SetDebugName(tex.debugname);
} }
@ -739,6 +751,12 @@ void VkPPRenderPassSetup::CreatePipeline(const VkPPRenderPassKey &key)
// Note: the actual values are ignored since we use dynamic viewport+scissor states // Note: the actual values are ignored since we use dynamic viewport+scissor states
builder.setViewport(0.0f, 0.0f, 320.0f, 200.0f); builder.setViewport(0.0f, 0.0f, 320.0f, 200.0f);
builder.setScissor(0.0f, 0.0f, 320.0f, 200.0f); builder.setScissor(0.0f, 0.0f, 320.0f, 200.0f);
if (key.StencilTest)
{
builder.addDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
builder.setDepthStencilEnable(false, false, true);
builder.setStencil(VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_STENCIL_OP_KEEP, VK_COMPARE_OP_EQUAL, 0xffffffff, 0xffffffff, 0);
}
builder.setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); builder.setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
builder.setBlendMode(key.BlendMode); builder.setBlendMode(key.BlendMode);
builder.setRasterizationSamples(key.Samples); builder.setRasterizationSamples(key.Samples);
@ -755,13 +773,35 @@ void VkPPRenderPassSetup::CreateRenderPass(const VkPPRenderPassKey &key)
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
else else
builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); builder.addAttachment(key.OutputFormat, key.Samples, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest)
{
builder.addDepthStencilAttachment(
GetVulkanFrameBuffer()->GetBuffers()->SceneDepthStencilFormat, key.Samples,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
builder.addSubpass(); builder.addSubpass();
builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); builder.addSubpassColorAttachmentRef(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (key.StencilTest)
{
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_PIPELINE_STAGE_FRAGMENT_SHADER_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 | VK_ACCESS_SHADER_READ_BIT);
}
else
{
builder.addExternalSubpassDependency( builder.addExternalSubpassDependency(
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT); VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT);
}
RenderPass = builder.create(GetVulkanFrameBuffer()->device); RenderPass = builder.create(GetVulkanFrameBuffer()->device);
RenderPass->SetDebugName("VkPPRenderPassSetup.RenderPass"); RenderPass->SetDebugName("VkPPRenderPassSetup.RenderPass");
} }

View file

@ -26,6 +26,7 @@ public:
VkFormat OutputFormat; VkFormat OutputFormat;
int SwapChain; int SwapChain;
int ShadowMapBuffers; int ShadowMapBuffers;
int StencilTest;
VkSampleCountFlagBits Samples; VkSampleCountFlagBits Samples;
bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; } bool operator<(const VkPPRenderPassKey &other) const { return memcmp(this, &other, sizeof(VkPPRenderPassKey)) < 0; }
@ -134,10 +135,10 @@ public:
void Draw() override; void Draw() override;
private: private:
void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize); void RenderScreenQuad(VkPPRenderPassSetup *passSetup, VulkanDescriptorSet *descriptorSet, VulkanFramebuffer *framebuffer, int framebufferWidth, int framebufferHeight, int x, int y, int width, int height, const void *pushConstants, uint32_t pushConstantsSize, bool stencilTest);
VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers); VulkanDescriptorSet *GetInput(VkPPRenderPassSetup *passSetup, const TArray<PPTextureInput> &textures, bool bindShadowMapBuffers);
VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, int &framebufferWidth, int &framebufferHeight); VulkanFramebuffer *GetOutput(VkPPRenderPassSetup *passSetup, const PPOutput &output, bool stencilTest, int &framebufferWidth, int &framebufferHeight);
VkPPShader *GetVkShader(PPShader *shader); VkPPShader *GetVkShader(PPShader *shader);
VkPPTexture *GetVkTexture(PPTexture *texture); VkPPTexture *GetVkTexture(PPTexture *texture);