Vulkan: De-couple Program from VertexArrayVk dirtyiness.
The VertexArrayVk is responsible for filling out the packed shader
input info in ANGLE's packed PipelineDesc info structure. This
packed info structure is used for Pipeline init and caching lookup.
The prior design had this info depend on the active inputs in the
current Program. This was undesirable because then, on a Program
change, the ContextVk would have to call into the VertexArrayVk
to invalidate this info.
Instead, keep a working copy of the VertexArrayVk bits and only
update the bits corresponding to dirty vertex attributes. This
simplifies the cached state management a little bit for ContextVk.
This also means we don't have to update the cached copy in the
VertexArray on a change in VertexArray binding.
Bug: angleproject:2163
Change-Id: I5ba74535367aed74957d17bdc61f882508562d0e
Reviewed-on: https://chromium-review.googlesource.com/881703
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 59f0a6d..5dfe53a 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -24,11 +24,13 @@
: VertexArrayImpl(state),
mCurrentArrayBufferHandles{},
mCurrentArrayBufferResources{},
- mCurrentElementArrayBufferResource(nullptr),
- mCurrentVertexDescsValid(false)
+ mCurrentElementArrayBufferResource(nullptr)
{
mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
mCurrentArrayBufferResources.fill(nullptr);
+
+ mPackedInputBindings.fill({0, 0});
+ mPackedInputAttributes.fill({0, 0, 0});
}
VertexArrayVk::~VertexArrayVk()
@@ -49,9 +51,6 @@
ContextVk *contextVk = vk::GetImpl(context);
contextVk->onVertexArrayChange();
- // Invalidate the vertex descriptions.
- invalidateVertexDescriptions();
-
// Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
// TODO(jmadill): Handle buffer storage changes.
const auto &attribs = mState.getVertexAttributes();
@@ -75,6 +74,9 @@
size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
+ // Invalidate the input description for pipelines.
+ mDirtyPackedInputs.set(attribIndex);
+
const auto &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex];
@@ -126,15 +128,15 @@
}
}
-void VertexArrayVk::invalidateVertexDescriptions()
+void VertexArrayVk::getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc)
{
- mCurrentVertexDescsValid = false;
+ updatePackedInputDescriptions();
+ pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
}
-void VertexArrayVk::updateVertexDescriptions(const gl::Context *context,
- vk::PipelineDesc *pipelineDesc)
+void VertexArrayVk::updatePackedInputDescriptions()
{
- if (mCurrentVertexDescsValid)
+ if (!mDirtyPackedInputs.any())
{
return;
}
@@ -142,18 +144,13 @@
const auto &attribs = mState.getVertexAttributes();
const auto &bindings = mState.getVertexBindings();
- const gl::Program *programGL = context->getGLState().getProgram();
-
- pipelineDesc->resetVertexInputState();
-
- for (auto attribIndex : programGL->getActiveAttribLocationsMask())
+ for (auto attribIndex : mDirtyPackedInputs)
{
const auto &attrib = attribs[attribIndex];
const auto &binding = bindings[attrib.bindingIndex];
if (attrib.enabled)
{
- pipelineDesc->updateVertexInputInfo(static_cast<uint32_t>(attribIndex), binding,
- attrib);
+ updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
}
else
{
@@ -161,7 +158,30 @@
}
}
- mCurrentVertexDescsValid = true;
+ mDirtyPackedInputs.reset();
+}
+
+void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
+ const gl::VertexBinding &binding,
+ const gl::VertexAttribute &attrib)
+{
+ vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
+
+ size_t attribSize = gl::ComputeVertexAttributeTypeSize(attrib);
+ ASSERT(attribSize <= std::numeric_limits<uint16_t>::max());
+
+ bindingDesc.stride = static_cast<uint16_t>(attribSize);
+ bindingDesc.inputRate = static_cast<uint16_t>(
+ binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
+
+ gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
+ VkFormat vkFormat = vk::GetNativeVertexFormat(vertexFormatType);
+ ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
+
+ vk::PackedVertexInputAttributeDesc &attribDesc = mPackedInputAttributes[attribIndex];
+ attribDesc.format = static_cast<uint16_t>(vkFormat);
+ attribDesc.location = static_cast<uint16_t>(attribIndex);
+ attribDesc.offset = static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
}
} // namespace rx