Commit dd4a00a0 by Jamie Madill Committed by Commit Bot

Vulkan: Track resource usage via counter.

This adds a small shared piece of memory that counts the number of times a resource is used in a command graph. This will enable more multi-threaded uses. The shared pointer is updated in the command graph during a submit and during graph construction. Bug: angleproject:2464 Change-Id: Id9d0319a6814825d02e865ba527c97b5f535ff31 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1785989 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent d7f28aae
...@@ -223,6 +223,8 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk, ...@@ -223,6 +223,8 @@ angle::Result BufferVk::mapRangeImpl(ContextVk *contextVk,
} }
// Make sure the GPU is done with the buffer. // Make sure the GPU is done with the buffer.
ANGLE_TRY(contextVk->finishToSerial(mBuffer.getStoredQueueSerial())); ANGLE_TRY(contextVk->finishToSerial(mBuffer.getStoredQueueSerial()));
ASSERT(!mBuffer.isResourceInUse(contextVk));
} }
ANGLE_VK_TRY(contextVk, mBuffer.getDeviceMemory().map(contextVk->getDevice(), offset, length, 0, ANGLE_VK_TRY(contextVk, mBuffer.getDeviceMemory().map(contextVk->getDevice(), offset, length, 0,
......
...@@ -240,21 +240,21 @@ float CalculateSecondaryCommandBufferPoolWaste(const std::vector<CommandGraphNod ...@@ -240,21 +240,21 @@ float CalculateSecondaryCommandBufferPoolWaste(const std::vector<CommandGraphNod
// CommandGraphResource implementation. // CommandGraphResource implementation.
CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType) CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType)
: mCurrentWritingNode(nullptr), mResourceType(resourceType) : mUse(new ResourceUse), mCurrentWritingNode(nullptr), mResourceType(resourceType)
{} {}
CommandGraphResource::~CommandGraphResource() = default; CommandGraphResource::~CommandGraphResource() = default;
bool CommandGraphResource::isResourceInUse(ContextVk *contextVk) const bool CommandGraphResource::isResourceInUse(ContextVk *contextVk) const
{ {
return contextVk->isSerialInUse(mStoredQueueSerial); return mUse->counter > 0 || contextVk->isSerialInUse(mUse->serial);
} }
void CommandGraphResource::resetQueueSerial() void CommandGraphResource::resetQueueSerial()
{ {
mCurrentWritingNode = nullptr; mCurrentWritingNode = nullptr;
mCurrentReadingNodes.clear(); mCurrentReadingNodes.clear();
mStoredQueueSerial = Serial(); mUse->serial = Serial();
} }
angle::Result CommandGraphResource::recordCommands(ContextVk *context, angle::Result CommandGraphResource::recordCommands(ContextVk *context,
...@@ -904,6 +904,8 @@ angle::Result CommandGraph::submitCommands(ContextVk *context, ...@@ -904,6 +904,8 @@ angle::Result CommandGraph::submitCommands(ContextVk *context,
dumpGraphDotFile(std::cout); dumpGraphDotFile(std::cout);
} }
releaseResourceUsesAndUpdateSerials(serial);
std::vector<CommandGraphNode *> nodeStack; std::vector<CommandGraphNode *> nodeStack;
VkCommandBufferBeginInfo beginInfo = {}; VkCommandBufferBeginInfo beginInfo = {};
...@@ -1228,5 +1230,17 @@ void CommandGraph::addDependenciesToNextBarrier(size_t begin, ...@@ -1228,5 +1230,17 @@ void CommandGraph::addDependenciesToNextBarrier(size_t begin,
} }
} }
void CommandGraph::releaseResourceUsesAndUpdateSerials(Serial serial)
{
for (SharedResourceUse &use : mResourceUses)
{
ASSERT(use->counter > 0);
use->counter--;
ASSERT(use->serial <= serial);
use->serial = serial;
}
mResourceUses.clear();
}
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
...@@ -271,6 +271,20 @@ class CommandGraphNode final : angle::NonCopyable ...@@ -271,6 +271,20 @@ class CommandGraphNode final : angle::NonCopyable
RenderPassOwner *mRenderPassOwner; RenderPassOwner *mRenderPassOwner;
}; };
// Tracks how a resource is used in a command graph and in a VkQueue. The reference count indicates
// the number of times a resource is used in the graph. The serial indicates the last current use
// of a resource in the VkQueue. The reference count and serial together can determine if a
// resource is in use.
struct ResourceUse
{
ResourceUse() = default;
uint32_t counter = 0;
Serial serial;
};
using SharedResourceUse = std::shared_ptr<ResourceUse>;
// This is a helper class for back-end objects used in Vk command buffers. It records a serial // This is a helper class for back-end objects used in Vk command buffers. It records a serial
// at command recording times indicating an order in the queue. We use Fences to detect when // at command recording times indicating an order in the queue. We use Fences to detect when
// commands finish, and then release any unreferenced and deleted resources based on the stored // commands finish, and then release any unreferenced and deleted resources based on the stored
...@@ -287,7 +301,7 @@ class CommandGraphResource : angle::NonCopyable ...@@ -287,7 +301,7 @@ class CommandGraphResource : angle::NonCopyable
// Get the current queue serial for this resource. Used to release resources, and for // 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. // queries, to know if the queue they are submitted on has finished execution.
Serial getStoredQueueSerial() const { return mStoredQueueSerial; } Serial getStoredQueueSerial() const { return mUse->serial; }
// Sets up dependency relations. 'this' resource is the resource being written to. // Sets up dependency relations. 'this' resource is the resource being written to.
void addWriteDependency(ContextVk *contextVk, CommandGraphResource *writingResource); void addWriteDependency(ContextVk *contextVk, CommandGraphResource *writingResource);
...@@ -362,7 +376,8 @@ class CommandGraphResource : angle::NonCopyable ...@@ -362,7 +376,8 @@ class CommandGraphResource : angle::NonCopyable
void onWriteImpl(ContextVk *contextVk, CommandGraphNode *writingNode); void onWriteImpl(ContextVk *contextVk, CommandGraphNode *writingNode);
Serial mStoredQueueSerial; // Current resource lifetime.
SharedResourceUse mUse;
std::vector<CommandGraphNode *> mCurrentReadingNodes; std::vector<CommandGraphNode *> mCurrentReadingNodes;
...@@ -432,6 +447,8 @@ class CommandGraph final : angle::NonCopyable ...@@ -432,6 +447,8 @@ class CommandGraph final : angle::NonCopyable
// Host-visible buffer write availability operation: // Host-visible buffer write availability operation:
void makeHostVisibleBufferWriteAvailable(); void makeHostVisibleBufferWriteAvailable();
void onResourceUse(const SharedResourceUse &resourceUse);
private: private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function, CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
CommandGraphResourceType resourceType, CommandGraphResourceType resourceType,
...@@ -442,6 +459,7 @@ class CommandGraph final : angle::NonCopyable ...@@ -442,6 +459,7 @@ class CommandGraph final : angle::NonCopyable
void dumpGraphDotFile(std::ostream &out) const; void dumpGraphDotFile(std::ostream &out) const;
void updateOverlay(ContextVk *contextVk) const; void updateOverlay(ContextVk *contextVk) const;
void releaseResourceUsesAndUpdateSerials(Serial serial);
std::vector<CommandGraphNode *> mNodes; std::vector<CommandGraphNode *> mNodes;
bool mEnableGraphDiagnostics; bool mEnableGraphDiagnostics;
...@@ -495,6 +513,8 @@ class CommandGraph final : angle::NonCopyable ...@@ -495,6 +513,8 @@ class CommandGraph final : angle::NonCopyable
// issued. // issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max(); static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex; size_t mLastBarrierIndex;
std::vector<SharedResourceUse> mResourceUses;
}; };
// CommandGraphResource inlines. // CommandGraphResource inlines.
...@@ -505,15 +525,16 @@ ANGLE_INLINE bool CommandGraphResource::hasStartedRenderPass() const ...@@ -505,15 +525,16 @@ ANGLE_INLINE bool CommandGraphResource::hasStartedRenderPass() const
ANGLE_INLINE void CommandGraphResource::onGraphAccess(Serial serial, CommandGraph *commandGraph) ANGLE_INLINE void CommandGraphResource::onGraphAccess(Serial serial, CommandGraph *commandGraph)
{ {
ASSERT(serial >= mStoredQueueSerial); ASSERT(serial >= mUse->serial);
// TODO(jmadill: Store reference to usage in graph. http://anglebug.com/2464 // Store reference to usage in graph.
commandGraph->onResourceUse(mUse);
if (serial > mStoredQueueSerial) if (serial > mUse->serial)
{ {
mCurrentWritingNode = nullptr; mCurrentWritingNode = nullptr;
mCurrentReadingNodes.clear(); mCurrentReadingNodes.clear();
mStoredQueueSerial = serial; mUse->serial = serial;
} }
} }
...@@ -608,6 +629,13 @@ ANGLE_INLINE bool CommandGraphResource::hasChildlessWritingNode() const ...@@ -608,6 +629,13 @@ ANGLE_INLINE bool CommandGraphResource::hasChildlessWritingNode() const
return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren()); return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren());
} }
// CommandGraph inlines.
ANGLE_INLINE void CommandGraph::onResourceUse(const SharedResourceUse &resourceUse)
{
ASSERT(resourceUse->counter < std::numeric_limits<uint32_t>::max());
resourceUse->counter++;
mResourceUses.push_back(resourceUse);
}
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment