Vulkan: More Vertex Array optimizations.
Inlines a number of Vulkan vertex array methods.
Also changes the way vertex buffers are bound. Note that Vulkan doesn't
support NULL buffer bindings. Thus we create an emulated NULL buffer
to work around the problem of having gaps in the bound vertex buffers.
This allows us to use a single bind call for ranges of vertex buffers
even when there are gaps.
Also changes how vertex array dirty bits are reset. Instead of calling
memset to clear the affected buffers we pass a mutable pointer to the
Vertex Array sync state. This allows us to only reset the dirty bits
that we sync. This saves on the memory clearing time.
Improves perf by about 10% in the Vulkan VBO state change test.
Bug: angleproject:3014
Change-Id: Ib7b742dff7897fc891606a652ea0b64255a24c86
Reviewed-on: https://chromium-review.googlesource.com/c/1390360
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h
index 17d79bf..40d0a7e 100644
--- a/src/libANGLE/renderer/vulkan/CommandGraph.h
+++ b/src/libANGLE/renderer/vulkan/CommandGraph.h
@@ -76,7 +76,13 @@
// Once a node has commands that must happen after it, recording is stopped and the node is
// frozen forever.
static void SetHappensBeforeDependency(CommandGraphNode *beforeNode,
- CommandGraphNode *afterNode);
+ CommandGraphNode *afterNode)
+ {
+ ASSERT(beforeNode != afterNode && !beforeNode->isChildOf(afterNode));
+ afterNode->mParents.emplace_back(beforeNode);
+ beforeNode->setHasChildren();
+ }
+
static void SetHappensBeforeDependencies(CommandGraphNode **beforeNodes,
size_t beforeNodesCount,
CommandGraphNode *afterNode);
@@ -107,10 +113,14 @@
void setQueryPool(const QueryPool *queryPool, uint32_t queryIndex);
- void addGlobalMemoryBarrier(VkFlags srcAccess, VkFlags dstAccess);
+ ANGLE_INLINE void addGlobalMemoryBarrier(VkFlags srcAccess, VkFlags dstAccess)
+ {
+ mGlobalMemoryBarrierSrcAccess |= srcAccess;
+ mGlobalMemoryBarrierDstAccess |= dstAccess;
+ }
private:
- void setHasChildren();
+ void setHasChildren() { mHasChildren = true; }
// Used for testing only.
bool isChildOf(CommandGraphNode *parent);
@@ -169,7 +179,7 @@
// Get the current queue serial for this resource. Used to release resources, and for
// queries, to know if the queue they are submitted on has finished execution.
- Serial getStoredQueueSerial() const;
+ Serial getStoredQueueSerial() const { return mStoredQueueSerial; }
protected:
explicit CommandGraphResource(CommandGraphResourceType resourceType);
@@ -198,7 +208,17 @@
// Updates the in-use serial tracked for this resource. Will clear dependencies if the resource
// was not used in this set of command nodes.
- void updateQueueSerial(Serial queueSerial);
+ ANGLE_INLINE void updateQueueSerial(Serial queueSerial)
+ {
+ ASSERT(queueSerial >= mStoredQueueSerial);
+
+ if (queueSerial > mStoredQueueSerial)
+ {
+ mCurrentWritingNode = nullptr;
+ mCurrentReadingNodes.clear();
+ mStoredQueueSerial = queueSerial;
+ }
+ }
// Allocates a write node via getNewWriteNode and returns a started command buffer.
// The started command buffer will render outside of a RenderPass.
@@ -216,7 +236,20 @@
// Checks if we're in a RenderPass, returning true if so. Updates serial internally.
// Returns the started command buffer in commandBufferOut.
- bool appendToStartedRenderPass(RendererVk *renderer, CommandBuffer **commandBufferOut);
+ ANGLE_INLINE bool appendToStartedRenderPass(Serial currentQueueSerial,
+ CommandBuffer **commandBufferOut)
+ {
+ updateQueueSerial(currentQueueSerial);
+ if (hasStartedRenderPass())
+ {
+ *commandBufferOut = mCurrentWritingNode->getInsideRenderPassCommands();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
// Accessor for RenderPass RenderArea.
const gl::Rectangle &getRenderPassRenderArea() const;
@@ -236,7 +269,7 @@
private:
// Returns true if this node has a current writing node with no children.
- bool hasChildlessWritingNode() const
+ ANGLE_INLINE bool hasChildlessWritingNode() const
{
// Note: currently, we don't have a resource that can issue both generic and special
// commands. We don't create read/write dependencies between mixed generic/special