mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-27 08:56:44 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user