Force on dynamic states we want in pixel history, to simplify handling

* This also fixes a case where pipelines with dynamic stencil masks wouldn't
  have the masks properly set for stencil counting and we wouldn't get shader
  output properly.
This commit is contained in:
baldurk
2020-05-08 20:43:25 +01:00
parent 1ad2cf0905
commit 7ddc24e13d
3 changed files with 166 additions and 87 deletions
+72 -87
View File
@@ -448,17 +448,15 @@ protected:
const VulkanCreationInfo::Pipeline &p = m_pDriver->GetDebugManager()->GetPipelineInfo(pipe);
m_pDriver->GetShaderCache()->MakeGraphicsPipelineInfo(pipeCreateInfo, pipe);
// make state we want to control dynamic
AddDynamicStates(pipeCreateInfo);
VkPipelineRasterizationStateCreateInfo *rs =
(VkPipelineRasterizationStateCreateInfo *)pipeCreateInfo.pRasterizationState;
VkPipelineDepthStencilStateCreateInfo *ds =
(VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState;
VkPipelineMultisampleStateCreateInfo *ms =
(VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState;
VkPipelineViewportStateCreateInfo *vs =
(VkPipelineViewportStateCreateInfo *)pipeCreateInfo.pViewportState;
VkRect2D newScissors[16];
memset(newScissors, 0, sizeof(newScissors));
// TODO: should leave in the original state.
ds->depthTestEnable = VK_FALSE;
@@ -489,22 +487,6 @@ protected:
// Narrow on the specific pixel and sample.
{
ms->pSampleMask = &m_CallbackInfo.sampleMask;
// Change scissors unless they are set dynamically.
if(p.dynamicStates[VkDynamicScissor])
{
VulkanRenderState &pipestate = m_pDriver->GetCmdRenderState();
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
}
else
{
for(uint32_t i = 0; i < vs->viewportCount; i++)
{
ScissorToPixel(vs->pViewports[i], newScissors[i]);
}
vs->pScissors = newScissors;
}
}
// Turn off all color modifications.
@@ -543,6 +525,34 @@ protected:
pipeCreateInfo.pStages = stages.data();
}
// ensures the state we want to control is dynamic, whether or not it was dynamic in the original
// pipeline
void AddDynamicStates(VkGraphicsPipelineCreateInfo &pipeCreateInfo)
{
// we need to add it. Check if the dynamic state is already pointing to our internal array (in
// the case of adding multiple dynamic states in a row), and otherwise initialise our array from
// it and repoint. Then we can add the new state
VkPipelineDynamicStateCreateInfo *dynState =
(VkPipelineDynamicStateCreateInfo *)pipeCreateInfo.pDynamicState;
// copy over the original dynamic states
m_DynamicStates.assign(dynState->pDynamicStates, dynState->dynamicStateCount);
// add the ones we want
if(!m_DynamicStates.contains(VK_DYNAMIC_STATE_SCISSOR))
m_DynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
if(!m_DynamicStates.contains(VK_DYNAMIC_STATE_STENCIL_REFERENCE))
m_DynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
if(!m_DynamicStates.contains(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))
m_DynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
if(!m_DynamicStates.contains(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))
m_DynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
// now point at our storage for the array
dynState->pDynamicStates = m_DynamicStates.data();
dynState->dynamicStateCount = (uint32_t)m_DynamicStates.size();
}
// CreateRenderPass creates a new VkRenderPass based on the original that has a separate
// depth-stencil attachment, and covers a single subpass. This will be used to replay
// a single draw. The new renderpass also replaces the depth stencil attachment, so
@@ -873,6 +883,7 @@ protected:
VkQueryPool m_OcclusionPool;
rdcarray<VkRenderPass> m_RpsToDestroy;
rdcarray<VkFramebuffer> m_FbsToDestroy;
rdcarray<VkDynamicState> m_DynamicStates;
};
// VulkanOcclusionCallback callback is used to determine which draw events might have
@@ -900,8 +911,6 @@ struct VulkanOcclusionCallback : public VulkanPixelHistoryCallback
return;
VulkanRenderState prevState = m_pDriver->GetCmdRenderState();
VulkanRenderState &pipestate = m_pDriver->GetCmdRenderState();
const VulkanCreationInfo::Pipeline &p =
m_pDriver->GetDebugManager()->GetPipelineInfo(pipestate.graphics.pipeline);
uint32_t framebufferIndex = 0;
const rdcarray<ResourceId> &atts = pipestate.GetFramebufferAttachments();
@@ -915,9 +924,13 @@ struct VulkanOcclusionCallback : public VulkanPixelHistoryCallback
}
}
VkPipeline pipe = GetPixelOcclusionPipeline(eid, prevState.graphics.pipeline, framebufferIndex);
if(p.dynamicStates[VkDynamicScissor])
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
// set the scissor
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
// set stencil state (though it's unused here)
pipestate.front.compare = pipestate.front.write = 0xff;
pipestate.front.ref = 0;
pipestate.back = pipestate.front;
pipestate.graphics.pipeline = GetResID(pipe);
ReplayDrawWithQuery(cmd, eid);
@@ -1099,11 +1112,8 @@ struct VulkanColorAndStencilCallback : public VulkanPixelHistoryCallback
PipelineReplacements replacements =
GetPipelineReplacements(eid, pipestate.graphics.pipeline, newRp, framebufferIndex);
const VulkanCreationInfo::Pipeline &p =
m_pDriver->GetDebugManager()->GetPipelineInfo(pipestate.graphics.pipeline);
if(p.dynamicStates[VkDynamicScissor])
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
// TODO: should fill depth value from the original DS attachment.
@@ -1114,6 +1124,9 @@ struct VulkanColorAndStencilCallback : public VulkanPixelHistoryCallback
pipestate.renderPass = GetResID(newRp);
pipestate.subpass = 0;
pipestate.graphics.pipeline = GetResID(replacements.fixedShaderStencil);
pipestate.front.compare = pipestate.front.write = 0xff;
pipestate.front.ref = 0;
pipestate.back = pipestate.front;
ReplayDraw(cmd, eid, true);
CopyPixelParams params = {};
@@ -1685,20 +1698,17 @@ private:
m_ShaderCache->GetShaderWithoutSideEffects(p.shaders[i].module, p.shaders[i].entryPoint);
}
bool dynamicScissor = p.dynamicStates[VkDynamicScissor];
VulkanRenderState &pipestate = m_pDriver->GetCmdRenderState();
rdcarray<VkRect2D> prevScissors = pipestate.scissors;
if(dynamicScissor)
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
if(eventFlags & TestEnabled_Culling)
{
uint32_t pipeFlags =
PipelineCreationFlags_DisableDepthTest | PipelineCreationFlags_DisableDepthBoundsTest |
PipelineCreationFlags_DisableStencilTest | PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_Culling);
}
@@ -1712,13 +1722,11 @@ private:
PipelineCreationFlags_IntersectOriginalScissor | PipelineCreationFlags_DisableDepthTest |
PipelineCreationFlags_DisableDepthBoundsTest | PipelineCreationFlags_DisableStencilTest |
PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
// This will change the dynamic scissor state for the later tests, but since those
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
// This will change the scissor for the later tests, but since those
// tests happen later in the pipeline, it does not matter.
if(dynamicScissor)
for(uint32_t i = 0; i < pipestate.views.size(); i++)
IntersectScissors(prevScissors[i], pipestate.scissors[i]);
for(uint32_t i = 0; i < pipestate.views.size(); i++)
IntersectScissors(prevScissors[i], pipestate.scissors[i]);
ReplayDraw(cmd, pipe, eid, TestEnabled_Scissor);
}
@@ -1731,8 +1739,7 @@ private:
uint32_t pipeFlags =
PipelineCreationFlags_DisableDepthBoundsTest | PipelineCreationFlags_DisableStencilTest |
PipelineCreationFlags_DisableDepthTest | PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_SampleMask);
}
@@ -1742,8 +1749,7 @@ private:
uint32_t pipeFlags = PipelineCreationFlags_DisableStencilTest |
PipelineCreationFlags_DisableDepthTest |
PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_DepthBounds);
}
@@ -1755,8 +1761,7 @@ private:
{
uint32_t pipeFlags =
PipelineCreationFlags_DisableDepthTest | PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_StencilTesting);
}
@@ -1771,8 +1776,7 @@ private:
uint32_t pipeFlags =
PipelineCreationFlags_DisableStencilTest | PipelineCreationFlags_FixedColorShader;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_DepthTesting);
}
@@ -1785,8 +1789,7 @@ private:
uint32_t pipeFlags = PipelineCreationFlags_DisableDepthBoundsTest |
PipelineCreationFlags_DisableStencilTest |
PipelineCreationFlags_DisableDepthTest;
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, dynamicScissor, replacementShaders,
framebufferIndex);
VkPipeline pipe = CreatePipeline(basePipeline, pipeFlags, replacementShaders, framebufferIndex);
ReplayDraw(cmd, pipe, eid, TestEnabled_FragmentDiscard);
}
}
@@ -1794,7 +1797,7 @@ private:
// Creates a pipeline that is based on the given pipeline and the given
// pipeline flags. Modifies the base pipeline according to the flags, and
// leaves the original pipeline behavior if a flag is not set.
VkPipeline CreatePipeline(ResourceId basePipeline, uint32_t pipeCreateFlags, bool dynamicScissor,
VkPipeline CreatePipeline(ResourceId basePipeline, uint32_t pipeCreateFlags,
const rdcarray<VkShaderModule> &replacementShaders,
uint32_t framebufferIndex)
{
@@ -1810,10 +1813,11 @@ private:
(VkPipelineRasterizationStateCreateInfo *)ci.pRasterizationState;
VkPipelineDepthStencilStateCreateInfo *ds =
(VkPipelineDepthStencilStateCreateInfo *)ci.pDepthStencilState;
VkPipelineViewportStateCreateInfo *vs = (VkPipelineViewportStateCreateInfo *)ci.pViewportState;
VkPipelineMultisampleStateCreateInfo *ms =
(VkPipelineMultisampleStateCreateInfo *)ci.pMultisampleState;
AddDynamicStates(ci);
// Only interested in a single sample.
ms->pSampleMask = &m_CallbackInfo.sampleMask;
// We are going to replay a draw multiple times, don't want to modify the
@@ -1848,17 +1852,6 @@ private:
}
ci.pStages = stages.data();
if(!dynamicScissor)
{
VkRect2D *pScissors = (VkRect2D *)vs->pScissors;
for(uint32_t i = 0; i < vs->viewportCount; i++)
{
ScissorToPixel(vs->pViewports[i], pScissors[i]);
if(pipeCreateFlags & PipelineCreationFlags_IntersectOriginalScissor)
IntersectScissors(vs->pScissors[i], pScissors[i]);
}
}
VkPipeline pipe;
VkResult vkr = m_pDriver->vkCreateGraphicsPipelines(m_pDriver->GetDev(), VK_NULL_HANDLE, 1, &ci,
NULL, &pipe);
@@ -1965,7 +1958,10 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
}
}
Pipelines pipes = CreatePerFragmentPipelines(curPipeline, newRp, eid, false, 0, framebufferIndex);
Pipelines pipes = CreatePerFragmentPipelines(curPipeline, newRp, eid, 0, framebufferIndex);
for(uint32_t i = 0; i < state.views.size(); i++)
ScissorToPixel(state.views[i], state.scissors[i]);
state.renderPass = GetResID(newRp);
state.SetFramebuffer(m_pDriver, GetResID(newFb));
@@ -2035,6 +2031,8 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
// Update stencil reference to the current fragment index, so that we get values
// for a single fragment only.
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, f);
const DrawcallDescription *drawcall = m_pDriver->GetDrawcall(eid);
if(drawcall->flags & DrawFlags::Indexed)
@@ -2112,6 +2110,8 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
ObjDisp(cmd)->CmdClearAttachments(Unwrap(cmd), 2, clearAtts, 1, &rect);
}
ObjDisp(cmd)->CmdSetStencilCompareMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
ObjDisp(cmd)->CmdSetStencilWriteMask(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, 0xff);
ObjDisp(cmd)->CmdSetStencilReference(Unwrap(cmd), VK_STENCIL_FACE_FRONT_AND_BACK, f);
const DrawcallDescription *drawcall = m_pDriver->GetDrawcall(eid);
if(drawcall->flags & DrawFlags::Indexed)
@@ -2150,20 +2150,19 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
void PostRedraw(uint32_t eid, VkCommandBuffer cmd) {}
// CreatePerFragmentPipelines for getting per fragment information.
Pipelines CreatePerFragmentPipelines(ResourceId pipe, VkRenderPass rp, uint32_t eid,
bool dynamicScissor, uint32_t fragmentIndex,
uint32_t framebufferIndex)
uint32_t fragmentIndex, uint32_t framebufferIndex)
{
const VulkanCreationInfo::Pipeline &p = m_pDriver->GetDebugManager()->GetPipelineInfo(pipe);
VkGraphicsPipelineCreateInfo pipeCreateInfo = {};
rdcarray<VkPipelineShaderStageCreateInfo> stages;
m_pDriver->GetShaderCache()->MakeGraphicsPipelineInfo(pipeCreateInfo, pipe);
AddDynamicStates(pipeCreateInfo);
VkPipelineDepthStencilStateCreateInfo *ds =
(VkPipelineDepthStencilStateCreateInfo *)pipeCreateInfo.pDepthStencilState;
VkPipelineMultisampleStateCreateInfo *ms =
(VkPipelineMultisampleStateCreateInfo *)pipeCreateInfo.pMultisampleState;
VkPipelineViewportStateCreateInfo *vs =
(VkPipelineViewportStateCreateInfo *)pipeCreateInfo.pViewportState;
VkRect2D newScissors[16];
memset(newScissors, 0, sizeof(newScissors));
@@ -2180,22 +2179,6 @@ struct VulkanPixelHistoryPerFragmentCallback : VulkanPixelHistoryCallback
ds->back = ds->front;
ms->pSampleMask = &m_CallbackInfo.sampleMask;
// Change scissors unless they are set dynamically.
if(p.dynamicStates[VkDynamicScissor])
{
VulkanRenderState &pipestate = m_pDriver->GetCmdRenderState();
for(uint32_t i = 0; i < pipestate.views.size(); i++)
ScissorToPixel(pipestate.views[i], pipestate.scissors[i]);
}
else
{
for(uint32_t i = 0; i < vs->viewportCount; i++)
{
ScissorToPixel(vs->pViewports[i], newScissors[i]);
}
vs->pScissors = newScissors;
}
}
// TODO: this is wrong, should take into account subpass.
@@ -2377,6 +2360,8 @@ struct VulkanPixelHistoryDiscardedFragmentsCallback : VulkanPixelHistoryCallback
VulkanRenderState &state = m_pDriver->GetCmdRenderState();
// Create a pipeline with a scissor and colorWriteMask = 0, and disable all tests.
VkPipeline newPipe = CreatePipeline(state.graphics.pipeline, eid);
for(uint32_t i = 0; i < state.views.size(); i++)
ScissorToPixel(state.views[i], state.scissors[i]);
state.graphics.pipeline = GetResID(newPipe);
state.BindPipeline(m_pDriver, cmd, VulkanRenderState::BindGraphics, false);
for(uint32_t i = 0; i < primIds.size(); i++)
@@ -178,6 +178,23 @@ void main()
{Vec3f(0.0f, -0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(0.0f, -0.725f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
{Vec3f(0.025f, -0.7f, 0.5f), Vec4f(1.0f, 0.5f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
// dynamic triangles
{Vec3f(-0.6f, 0.75f, 0.5f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.5f, 0.65f, 0.5f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
{Vec3f(-0.4f, 0.75f, 0.5f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)},
{Vec3f(-0.6f, 0.75f, 0.5f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.5f, 0.65f, 0.5f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
{Vec3f(-0.4f, 0.75f, 0.5f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(1.0f, 0.0f)},
{Vec3f(-0.6f, 0.75f, 0.5f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.5f, 0.65f, 0.5f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
{Vec3f(-0.4f, 0.75f, 0.5f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
{Vec3f(-0.6f, 0.75f, 0.5f), Vec4f(0.0f, 1.0f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
{Vec3f(-0.5f, 0.65f, 0.5f), Vec4f(0.0f, 1.0f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
{Vec3f(-0.4f, 0.75f, 0.5f), Vec4f(0.0f, 1.0f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
};
// negate y if we're using negative viewport height
@@ -264,6 +281,40 @@ void main()
pipeCreateInfo.depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
VkPipeline depthWritePipe = createGraphicsPipeline(pipeCreateInfo);
VkPipeline dynamicScissorPipe, fixedScissorPassPipe, fixedScissorFailPipe,
dynamicStencilRefPipe, dynamicStencilMaskPipe;
{
vkh::GraphicsPipelineCreateInfo dynamicPipe = pipeCreateInfo;
dynamicPipe.depthStencilState.depthWriteEnable = VK_FALSE;
dynamicPipe.depthStencilState.depthTestEnable = VK_FALSE;
dynamicScissorPipe = createGraphicsPipeline(dynamicPipe);
setName(dynamicScissorPipe, "dynamicScissorPipe");
dynamicPipe.dynamicState.dynamicStates = {VK_DYNAMIC_STATE_VIEWPORT};
dynamicPipe.viewportState.scissors = {{{95, 245}, {10, 10}}};
fixedScissorPassPipe = createGraphicsPipeline(dynamicPipe);
setName(fixedScissorPassPipe, "fixedScissorPassPipe");
dynamicPipe.viewportState.scissors = {{{95, 245}, {4, 4}}};
fixedScissorFailPipe = createGraphicsPipeline(dynamicPipe);
setName(fixedScissorFailPipe, "fixedScissorFailPipe");
dynamicPipe.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
dynamicPipe.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
dynamicStencilRefPipe = createGraphicsPipeline(dynamicPipe);
setName(dynamicStencilRefPipe, "dynamicStencilRefPipe");
dynamicPipe.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
dynamicPipe.dynamicState.dynamicStates.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
dynamicStencilMaskPipe = createGraphicsPipeline(dynamicPipe);
setName(dynamicStencilMaskPipe, "dynamicStencilMaskPipe");
}
pipeCreateInfo.depthStencilState.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
pipeCreateInfo.depthStencilState.stencilTestEnable = VK_TRUE;
VkPipeline stencilWritePipe = createGraphicsPipeline(pipeCreateInfo);
@@ -391,6 +442,26 @@ void main()
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
vkCmdDraw(cmd, 24, 1, 9, 0);
setMarker(cmd, "Fixed Scissor Fail");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, fixedScissorFailPipe);
vkCmdDraw(cmd, 3, 1, 33, 0);
setMarker(cmd, "Fixed Scissor Pass");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, fixedScissorPassPipe);
vkCmdDraw(cmd, 3, 1, 36, 0);
setMarker(cmd, "Dynamic Stencil Ref");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dynamicStencilRefPipe);
vkCmdSetScissor(cmd, 0, 1, &mainWindow->scissor);
vkCmdSetStencilReference(cmd, VK_STENCIL_FACE_FRONT_AND_BACK, 0x67);
vkCmdDraw(cmd, 3, 1, 39, 0);
setMarker(cmd, "Dynamic Stencil Mask");
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, dynamicStencilMaskPipe);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FACE_FRONT_AND_BACK, 0);
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FACE_FRONT_AND_BACK, 0);
vkCmdDraw(cmd, 3, 1, 42, 0);
vkCmdEndRenderPass(cmd);
{
@@ -1,11 +1,13 @@
import renderdoc as rd
import rdtest
from typing import List
def value_selector(x): return x.floatValue
def passed(x): return x.Passed()
def event_id(x): return x.eventId
def culled(x): return x.backfaceCulled
def depth_test_failed(x): return x.depthTestFailed
def scissor_clipped(x): return x.scissorClipped
def stencil_test_failed(x): return x.stencilTestFailed
def shader_discarded(x): return x.shaderDiscarded
def shader_out_col(x): return value_selector(x.shaderOut.col)
@@ -53,6 +55,10 @@ class VK_Pixel_History(rdtest.TestCase):
background_eid = self.find_draw("Background").next.eventId
cull_eid = self.find_draw("Cull Front").next.eventId
test_eid = self.find_draw("Test").next.eventId
fixed_scissor_fail_eid = self.find_draw("Fixed Scissor Fail").next.eventId
fixed_scissor_pass_eid = self.find_draw("Fixed Scissor Pass").next.eventId
dynamic_stencil_ref_eid = self.find_draw("Dynamic Stencil Ref").next.eventId
dynamic_stencil_mask_eid = self.find_draw("Dynamic Stencil Mask").next.eventId
# For pixel 190, 149 inside the red triangle
x, y = 190, 149
@@ -102,6 +108,23 @@ class VK_Pixel_History(rdtest.TestCase):
self.check_events(events, modifs, False)
self.check_pixel_value(tex, x, y, value_selector(modifs[-1].postMod.col), sub=sub, cast=rt.typeCast)
rdtest.log.print("Testing dynamic state pipelines")
self.controller.SetFrameEvent(dynamic_stencil_mask_eid, True)
x, y = 100, 250
rdtest.log.print("Testing pixel {}, {}".format(x, y))
modifs: List[rd.PixelModification] = self.controller.PixelHistory(tex, x, y, sub, rt.typeCast)
events = [
[[event_id, begin_renderpass_eid], [passed, True]],
[[event_id, background_eid], [passed, True]],
[[event_id, fixed_scissor_fail_eid], [scissor_clipped, True]],
[[event_id, fixed_scissor_pass_eid], [passed, True], [shader_out_col, (0.0, 1.0, 0.0, 1.0)]],
[[event_id, dynamic_stencil_ref_eid], [passed, True], [shader_out_col, (0.0, 0.0, 1.0, 1.0)]],
[[event_id, dynamic_stencil_mask_eid], [passed, True], [shader_out_col, (0.0, 1.0, 1.0, 1.0)]],
]
self.check_events(events, modifs, False)
self.check_pixel_value(tex, x, y, value_selector(modifs[-1].postMod.col), sub=sub, cast=rt.typeCast)
def multisampled_image_test(self):
test_marker: rd.DrawcallDescription = self.find_draw("Multisampled: test")
draw_eid = test_marker.next.eventId