Vulkan: Faster state transitions.
Implements a transition table from Pipeline Cache entry to
state change neighbouring Pipeline Cache entries. We use
a 64-bit mask to do a quick scan over the pipeline desc.
This ends up being a lot faster than doing a full hash
and memcmp over the pipeline description.
Note that there could be future optimizations to this design.
We might keep a hash map of the pipeline transitions instead
of a list. Or use a sorted list. This could speed up the search
when there are many transitions for cache entries. Also we could
skip the transition table and opt to do a full hash when there
are more than a configurable number of dirty states. This might
be a bit faster in some cases. Likely this will be something we
can add performance tests for in the future.
Documentation is also added in a README file for the Vulkan back
end. This will be extended over time.
Improves performance about 30-35% on the VBO state change test.
Bug: angleproject:3013
Change-Id: I793f9e3efd8887acf00ad60e4ac2502a54c95dee
Reviewed-on: https://chromium-review.googlesource.com/c/1369287
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/UtilsVk.cpp b/src/libANGLE/renderer/vulkan/UtilsVk.cpp
index a59c2cf..7c2ba26 100644
--- a/src/libANGLE/renderer/vulkan/UtilsVk.cpp
+++ b/src/libANGLE/renderer/vulkan/UtilsVk.cpp
@@ -325,25 +325,30 @@
Serial serial = renderer->getCurrentQueueSerial();
- vk::PipelineAndSerial *pipelineAndSerial;
if (isCompute)
{
+ vk::PipelineAndSerial *pipelineAndSerial;
program->setShader(gl::ShaderType::Compute, fsCsShader);
ANGLE_TRY(program->getComputePipeline(context, pipelineLayout.get(), &pipelineAndSerial));
+ pipelineAndSerial->updateSerial(serial);
+ commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
}
else
{
program->setShader(gl::ShaderType::Vertex, vsShader);
program->setShader(gl::ShaderType::Fragment, fsCsShader);
+ // This value is not used but is passed to getGraphicsPipeline to avoid a nullptr check.
+ const vk::GraphicsPipelineDesc *descPtr;
+ vk::PipelineHelper *helper;
+
ANGLE_TRY(program->getGraphicsPipeline(
context, &renderer->getRenderPassCache(), renderer->getPipelineCache(), serial,
- pipelineLayout.get(), *pipelineDesc, gl::AttributesMask(), &pipelineAndSerial));
+ pipelineLayout.get(), *pipelineDesc, gl::AttributesMask(), &descPtr, &helper));
+ helper->updateSerial(serial);
+ commandBuffer->bindPipeline(bindPoint, helper->getPipeline());
}
- commandBuffer->bindPipeline(bindPoint, pipelineAndSerial->get());
- pipelineAndSerial->updateSerial(serial);
-
if (descriptorSet != VK_NULL_HANDLE)
{
commandBuffer->bindDescriptorSets(bindPoint, pipelineLayout.get(), 0, 1, &descriptorSet, 0,
@@ -619,8 +624,8 @@
vk::GraphicsPipelineDesc pipelineDesc;
pipelineDesc.initDefaults();
- pipelineDesc.updateColorWriteMask(params.colorMaskFlags, *params.alphaMask);
- pipelineDesc.updateRenderPassDesc(*params.renderPassDesc);
+ pipelineDesc.setColorWriteMask(params.colorMaskFlags, *params.alphaMask);
+ pipelineDesc.setRenderPassDesc(*params.renderPassDesc);
vk::ShaderLibrary &shaderLibrary = renderer->getShaderLibrary();
vk::RefCounted<vk::ShaderAndSerial> *vertexShader = nullptr;
@@ -707,7 +712,7 @@
vk::GraphicsPipelineDesc pipelineDesc;
pipelineDesc.initDefaults();
- pipelineDesc.updateRenderPassDesc(renderPassDesc);
+ pipelineDesc.setRenderPassDesc(renderPassDesc);
gl::Rectangle renderArea;
renderArea.x = params.destOffset[0];