Skip to content
Permalink
Browse files

Vulkan: Reduce the amount of redundant stencil parameter sets

  • Loading branch information...
hrydgard committed Aug 12, 2019
1 parent cf06b4a commit ddb5208130921c83b53552b7c3cd09ab8d61aec6
Showing with 22 additions and 6 deletions.
  1. +22 −6 ext/native/thin3d/VulkanQueueRunner.cpp
@@ -869,9 +869,11 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c

auto &commands = step.commands;

// TODO: Dynamic state commands (SetViewport, SetScissor, SetBlendConstants, SetStencil*) are only
// valid when a pipeline is bound with those as dynamic state. So we need to add some state tracking here
// for this to be correct. This is a bit of a pain but also will let us eliminate redundant calls.
// We can do a little bit of state tracking here to eliminate some calls into the driver.
// The stencil ones are very commonly mostly redundant so let's eliminate them where possible.
int lastStencilWriteMask = -1;
int lastStencilCompareMask = -1;
int lastStencilReference = -1;

for (const auto &c : commands) {
switch (c.cmd) {
@@ -882,6 +884,10 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
if (c.pipeline.pipeline != lastPipeline) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, c.pipeline.pipeline);
lastPipeline = c.pipeline.pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1;
lastStencilCompareMask = -1;
lastStencilReference = -1;
}
break;

@@ -902,9 +908,18 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
break;

case VKRRenderCommand::STENCIL:
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilWriteMask);
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilCompareMask);
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilRef);
if (lastStencilReference != c.stencil.stencilWriteMask) {
lastStencilReference = (int)c.stencil.stencilWriteMask;
vkCmdSetStencilWriteMask(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilWriteMask);
}
if (lastStencilCompareMask != c.stencil.stencilCompareMask) {
lastStencilCompareMask = c.stencil.stencilCompareMask;
vkCmdSetStencilCompareMask(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilCompareMask);
}
if (lastStencilReference != c.stencil.stencilRef) {
lastStencilReference = c.stencil.stencilRef;
vkCmdSetStencilReference(cmd, VK_STENCIL_FRONT_AND_BACK, c.stencil.stencilRef);
}
break;

case VKRRenderCommand::DRAW_INDEXED:
@@ -924,6 +939,7 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c

case VKRRenderCommand::CLEAR:
{
// If we get here, we failed to merge a clear into a render pass load op. This is bad for perf.
int numAttachments = 0;
VkClearRect rc{};
rc.baseArrayLayer = 0;

0 comments on commit ddb5208

Please sign in to comment.
You can’t perform that action at this time.