Commit 4ff1651e by Jamie Madill Committed by Commit Bot

Vulkan: Add ResourceUseList helper.

This abstracts away the ResourceUse tracking from CommandGraph. Pulling it out will allow us to more easily swap resource use tracking into ContextVk. The command graph is eventually going away so we need to move functionality out of CommandGraph. Bug: angleproject:4029 Change-Id: Icc3bcc824510b03e91f8ff010a82751a81516bfa Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2002930 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent bdb0f8a5
......@@ -379,7 +379,8 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk,
VkBufferCopy copyRegion = {stagingBufferOffset, offset, size};
ANGLE_TRY(mBuffer.copyFromBuffer(contextVk, mStagingBuffer.getCurrentBuffer()->getBuffer(),
VK_ACCESS_HOST_WRITE_BIT, copyRegion));
mStagingBuffer.getCurrentBuffer()->onGraphAccess(contextVk->getCommandGraph());
mStagingBuffer.getCurrentBuffer()->onGraphAccess(
&contextVk->getCommandGraph()->getResourceUseList());
}
else
{
......
......@@ -326,7 +326,7 @@ angle::Result CommandGraphResource::recordCommands(ContextVk *contextVk,
}
// Store reference to usage in graph.
contextVk->getCommandGraph()->onResourceUse(mUse);
contextVk->getCommandGraph()->getResourceUseList().add(mUse);
return angle::Result::Continue;
}
......@@ -366,7 +366,7 @@ void CommandGraphResource::addWriteDependency(ContextVk *contextVk,
void CommandGraphResource::addReadDependency(ContextVk *contextVk,
CommandGraphResource *readingResource)
{
onGraphAccess(contextVk->getCommandGraph());
onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
CommandGraphNode *readingNode = readingResource->mCurrentWritingNode;
ASSERT(readingNode);
......@@ -396,7 +396,7 @@ void CommandGraphResource::startNewCommands(ContextVk *contextVk)
void CommandGraphResource::onWriteImpl(ContextVk *contextVk, CommandGraphNode *writingNode)
{
onGraphAccess(contextVk->getCommandGraph());
onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
// Make sure any open reads and writes finish before we execute 'writingNode'.
if (!mCurrentReadingNodes.empty())
......@@ -940,7 +940,6 @@ CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *po
CommandGraph::~CommandGraph()
{
ASSERT(empty());
ASSERT(mResourceUses.empty());
}
CommandGraphNode *CommandGraph::allocateNode(CommandGraphNodeFunction function)
......@@ -1008,7 +1007,7 @@ angle::Result CommandGraph::submitCommands(ContextVk *context,
dumpGraphDotFile(std::cout);
}
releaseResourceUsesAndUpdateSerials(serial);
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial);
std::vector<CommandGraphNode *> nodeStack;
......@@ -1342,7 +1341,15 @@ void CommandGraph::addDependenciesToNextBarrier(size_t begin,
}
}
void CommandGraph::releaseResourceUses()
// ResourceUseList implementation.
ResourceUseList::ResourceUseList() = default;
ResourceUseList::~ResourceUseList()
{
ASSERT(mResourceUses.empty());
}
void ResourceUseList::releaseResourceUses()
{
for (SharedResourceUse &use : mResourceUses)
{
......@@ -1352,7 +1359,7 @@ void CommandGraph::releaseResourceUses()
mResourceUses.clear();
}
void CommandGraph::releaseResourceUsesAndUpdateSerials(Serial serial)
void ResourceUseList::releaseResourceUsesAndUpdateSerials(Serial serial)
{
for (SharedResourceUse &use : mResourceUses)
{
......
......@@ -387,6 +387,33 @@ class SharedGarbage
using SharedGarbageList = std::vector<SharedGarbage>;
// Mixin to abstract away the resource use tracking.
class ResourceUseList final : angle::NonCopyable
{
public:
ResourceUseList();
virtual ~ResourceUseList();
void add(const SharedResourceUse &resourceUse);
void releaseResourceUses();
void releaseResourceUsesAndUpdateSerials(Serial serial);
private:
std::vector<SharedResourceUse> mResourceUses;
};
// ResourceUser inlines.
ANGLE_INLINE void ResourceUseList::add(const SharedResourceUse &resourceUse)
{
// Disabled the assert because of difficulties with ImageView references.
// TODO(jmadill): Clean up with graph redesign. http://anglebug.com/4029
// ASSERT(!empty());
SharedResourceUse newUse;
newUse.set(resourceUse);
mResourceUses.emplace_back(std::move(newUse));
}
// 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
// commands finish, and then release any unreferenced and deleted resources based on the stored
......@@ -415,7 +442,7 @@ class CommandGraphResource : angle::NonCopyable
// 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 onGraphAccess(CommandGraph *commandGraph);
void onGraphAccess(ResourceUseList *resourceUseList);
void updateCurrentAccessNodes();
// If a resource is recreated, as in released and reinitialized, the next access to the
......@@ -424,7 +451,7 @@ class CommandGraphResource : angle::NonCopyable
// particular cases, such as recreating an image with full mipchain or adding STORAGE_IMAGE flag
// to its uses, this function is used to preserve the link between the previous and new
// nodes allocated for this resource.
void onResourceRecreated(CommandGraph *commandGraph);
void onResourceRecreated(ResourceUseList *resourceUseList);
// Allocates a write node via getNewWriteNode and returns a started command buffer.
// The started command buffer will render outside of a RenderPass.
......@@ -446,7 +473,7 @@ class CommandGraphResource : angle::NonCopyable
// Checks if we're in a RenderPass that encompasses renderArea, returning true if so. Updates
// serial internally. Returns the started command buffer in commandBufferOut.
bool appendToStartedRenderPass(CommandGraph *graph,
bool appendToStartedRenderPass(ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
CommandBuffer **commandBufferOut);
......@@ -561,8 +588,7 @@ class CommandGraph final : angle::NonCopyable
// External memory synchronization:
void syncExternalMemory();
void onResourceUse(const SharedResourceUse &resourceUse);
void releaseResourceUses();
ResourceUseList &getResourceUseList() { return mResourceUseList; }
private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
......@@ -574,12 +600,13 @@ class CommandGraph final : angle::NonCopyable
void dumpGraphDotFile(std::ostream &out) const;
void updateOverlay(ContextVk *contextVk) const;
void releaseResourceUsesAndUpdateSerials(Serial serial);
std::vector<CommandGraphNode *> mNodes;
bool mEnableGraphDiagnostics;
angle::PoolAllocator *mPoolAllocator;
ResourceUseList mResourceUseList;
// A set of nodes (eventually) exist that act as barriers to guarantee submission order. For
// example, a glMemoryBarrier() calls would lead to such a barrier or beginning and ending a
// query. This is because the graph can reorder operations if it sees fit. Let's call a barrier
......@@ -628,8 +655,6 @@ class CommandGraph final : angle::NonCopyable
// issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex;
std::vector<SharedResourceUse> mResourceUses;
};
// CommandGraphResource inlines.
......@@ -648,21 +673,21 @@ ANGLE_INLINE void CommandGraphResource::updateCurrentAccessNodes()
}
}
ANGLE_INLINE void CommandGraphResource::onResourceRecreated(CommandGraph *commandGraph)
ANGLE_INLINE void CommandGraphResource::onResourceRecreated(ResourceUseList *resourceUseList)
{
// Store reference to usage in graph.
commandGraph->onResourceUse(mUse);
// Store reference in resource list.
resourceUseList->add(mUse);
}
ANGLE_INLINE void CommandGraphResource::onGraphAccess(CommandGraph *commandGraph)
ANGLE_INLINE void CommandGraphResource::onGraphAccess(ResourceUseList *resourceUseList)
{
updateCurrentAccessNodes();
// Store reference to usage in graph.
commandGraph->onResourceUse(mUse);
// Store reference in resource list.
resourceUseList->add(mUse);
}
ANGLE_INLINE bool CommandGraphResource::appendToStartedRenderPass(CommandGraph *graph,
ANGLE_INLINE bool CommandGraphResource::appendToStartedRenderPass(ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
CommandBuffer **commandBufferOut)
{
......@@ -670,8 +695,8 @@ ANGLE_INLINE bool CommandGraphResource::appendToStartedRenderPass(CommandGraph *
if (hasStartedRenderPass())
{
// Store reference to usage in graph.
graph->onResourceUse(mUse);
// Store reference in resource list.
resourceUseList->add(mUse);
if (mCurrentWritingNode->getRenderPassRenderArea().encloses(renderArea))
{
......@@ -765,17 +790,6 @@ ANGLE_INLINE bool CommandGraphResource::hasChildlessWritingNode() const
mCurrentWritingNode->getFunction() == CommandGraphNodeFunction::Generic);
return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren());
}
// CommandGraph inlines.
ANGLE_INLINE void CommandGraph::onResourceUse(const SharedResourceUse &resourceUse)
{
// Disabled the assert because of difficulties with ImageView references.
// TODO(jmadill): Clean up with graph redesign. http://anglebug.com/4029
// ASSERT(!empty());
SharedResourceUse newUse;
newUse.set(resourceUse);
mResourceUses.emplace_back(std::move(newUse));
}
} // namespace vk
} // namespace rx
......
......@@ -642,7 +642,7 @@ void ContextVk::onDestroy(const gl::Context *context)
mCommandQueue.destroy(device);
mCommandGraph.releaseResourceUses();
mCommandGraph.getResourceUseList().releaseResourceUses();
mUtils.destroy(device);
......@@ -803,7 +803,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
mGraphicsDirtyBits |= mNewGraphicsCommandBufferDirtyBits;
gl::Rectangle scissoredRenderArea = mDrawFramebuffer->getScissoredRenderArea(this);
if (!mDrawFramebuffer->appendToStartedRenderPass(&mCommandGraph, scissoredRenderArea,
if (!mDrawFramebuffer->appendToStartedRenderPass(&mCommandGraph.getResourceUseList(),
scissoredRenderArea,
&mRenderPassCommandBuffer))
{
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, scissoredRenderArea,
......@@ -3127,13 +3128,13 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context,
{
samplerVk = nullptr;
samplerSerial = kZeroSerial;
textureVk->onSamplerGraphAccess(&mCommandGraph);
textureVk->onSamplerGraphAccess(&mCommandGraph.getResourceUseList());
}
else
{
samplerVk = vk::GetImpl(sampler);
samplerSerial = samplerVk->getSerial();
samplerVk->onSamplerGraphAccess(&mCommandGraph);
samplerVk->onSamplerGraphAccess(&mCommandGraph.getResourceUseList());
}
vk::ImageHelper &image = textureVk->getImage();
......@@ -3159,7 +3160,7 @@ angle::Result ContextVk::updateActiveTextures(const gl::Context *context,
image.changeLayout(aspectFlags, textureLayout, srcLayoutChange);
}
textureVk->onImageViewGraphAccess(&mCommandGraph);
textureVk->onImageViewGraphAccess(&mCommandGraph.getResourceUseList());
image.addReadDependency(this, recorder);
mActiveTextures[textureUnit].texture = textureVk;
......
......@@ -162,7 +162,7 @@ angle::Result FramebufferVk::invalidate(const gl::Context *context,
const GLenum *attachments)
{
ContextVk *contextVk = vk::GetImpl(context);
mFramebuffer.onGraphAccess(contextVk->getCommandGraph());
mFramebuffer.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
if (mFramebuffer.valid() && mFramebuffer.hasStartedRenderPass())
{
......@@ -178,7 +178,7 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
const gl::Rectangle &area)
{
ContextVk *contextVk = vk::GetImpl(context);
mFramebuffer.onGraphAccess(contextVk->getCommandGraph());
mFramebuffer.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
// RenderPass' storeOp cannot be made conditional to a specific region, so we only apply this
// hint if the requested area encompasses the render area.
......
......@@ -112,11 +112,12 @@ class FramebufferVk : public FramebufferImpl
RenderTargetVk *getColorReadRenderTarget() const;
// This will clear the current write operation if it is complete.
bool appendToStartedRenderPass(vk::CommandGraph *graph,
bool appendToStartedRenderPass(vk::ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
vk::CommandBuffer **commandBufferOut)
{
return mFramebuffer.appendToStartedRenderPass(graph, renderArea, commandBufferOut);
return mFramebuffer.appendToStartedRenderPass(resourceUseList, renderArea,
commandBufferOut);
}
vk::FramebufferHelper *getFramebuffer() { return &mFramebuffer; }
......
......@@ -1248,7 +1248,7 @@ void ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk)
}
else
{
mEmptyBuffer.onGraphAccess(contextVk->getCommandGraph());
mEmptyBuffer.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
bufferInfo.buffer = mEmptyBuffer.getBuffer().getHandle();
mDescriptorBuffersCache.emplace_back(&mEmptyBuffer);
}
......@@ -1416,7 +1416,7 @@ void ProgramVk::updateAtomicCounterBuffersDescriptorSet(ContextVk *contextVk,
}
// Bind the empty buffer to every array slot that's unused.
mEmptyBuffer.onGraphAccess(contextVk->getCommandGraph());
mEmptyBuffer.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
for (size_t binding : ~writtenBindings)
{
VkDescriptorBufferInfo &bufferInfo = descriptorBufferInfo[binding];
......@@ -1779,7 +1779,7 @@ angle::Result ProgramVk::updateDescriptorSets(ContextVk *contextVk,
for (vk::BufferHelper *buffer : mDescriptorBuffersCache)
{
buffer->onGraphAccess(contextVk->getCommandGraph());
buffer->onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
}
return angle::Result::Continue;
......
......@@ -184,6 +184,6 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
void RenderTargetVk::onImageViewGraphAccess(ContextVk *contextVk) const
{
mImageViews->onGraphAccess(contextVk->getCommandGraph());
mImageViews->onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
}
} // namespace rx
......@@ -34,9 +34,9 @@ class SamplerVk : public SamplerImpl
Serial getSerial() const { return mSerial; }
void onSamplerGraphAccess(vk::CommandGraph *commandGraph)
void onSamplerGraphAccess(vk::ResourceUseList *resourceUseList)
{
mSampler.onGraphAccess(commandGraph);
mSampler.onGraphAccess(resourceUseList);
}
private:
......
......@@ -54,7 +54,7 @@ angle::Result SyncHelper::initialize(ContextVk *contextVk)
CommandGraph *commandGraph = contextVk->getCommandGraph();
commandGraph->setFenceSync(mEvent);
commandGraph->onResourceUse(mUse);
commandGraph->getResourceUseList().add(mUse);
return angle::Result::Continue;
}
......@@ -107,7 +107,7 @@ void SyncHelper::serverWait(ContextVk *contextVk)
{
CommandGraph *commandGraph = contextVk->getCommandGraph();
commandGraph->waitFenceSync(mEvent);
commandGraph->onResourceUse(mUse);
commandGraph->getResourceUseList().add(mUse);
}
angle::Result SyncHelper::getStatus(Context *context, bool *signaled)
......
......@@ -1176,7 +1176,7 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
// Release the origin image and recreate it with new mipmap counts.
releaseImage(contextVk);
mImage->onResourceRecreated(contextVk->getCommandGraph());
mImage->onResourceRecreated(&contextVk->getCommandGraph()->getResourceUseList());
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::FullMipChain));
}
......@@ -1345,7 +1345,7 @@ angle::Result TextureVk::changeLevels(ContextVk *contextVk,
// recreated with the correct number of mip levels, base level, and max level.
releaseImage(contextVk);
mImage->onResourceRecreated(contextVk->getCommandGraph());
mImage->onResourceRecreated(&contextVk->getCommandGraph()->getResourceUseList());
return angle::Result::Continue;
}
......@@ -1597,7 +1597,7 @@ const vk::ImageView &TextureVk::getReadImageViewAndRecordUse(ContextVk *contextV
{
ASSERT(mImage->valid());
mImageViews.onGraphAccess(contextVk->getCommandGraph());
mImageViews.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
if (mState.isStencilMode() && mImageViews.hasStencilReadImageView())
{
......@@ -1611,7 +1611,7 @@ const vk::ImageView &TextureVk::getFetchImageViewAndRecordUse(ContextVk *context
{
ASSERT(mImage->valid());
mImageViews.onGraphAccess(contextVk->getCommandGraph());
mImageViews.onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
// We don't currently support fetch for depth/stencil cube map textures.
ASSERT(!mImageViews.hasStencilReadImageView() || !mImageViews.hasFetchImageView());
......
......@@ -179,14 +179,14 @@ class TextureVk : public TextureImpl
return *mImage;
}
void onImageViewGraphAccess(vk::CommandGraph *commandGraph)
void onImageViewGraphAccess(vk::ResourceUseList *resourceUseList)
{
mImageViews.onGraphAccess(commandGraph);
mImageViews.onGraphAccess(resourceUseList);
}
void onSamplerGraphAccess(vk::CommandGraph *commandGraph)
void onSamplerGraphAccess(vk::ResourceUseList *resourceUseList)
{
mSampler.onGraphAccess(commandGraph);
mSampler.onGraphAccess(resourceUseList);
}
void releaseOwnershipOfImage(const gl::Context *context);
......
......@@ -1206,8 +1206,8 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea = params.clearArea;
vk::CommandBuffer *commandBuffer;
if (!framebuffer->appendToStartedRenderPass(contextVk->getCommandGraph(), scissoredRenderArea,
&commandBuffer))
if (!framebuffer->appendToStartedRenderPass(&contextVk->getCommandGraph()->getResourceUseList(),
scissoredRenderArea, &commandBuffer))
{
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, scissoredRenderArea, &commandBuffer));
}
......@@ -1435,8 +1435,8 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
}
vk::CommandBuffer *commandBuffer;
if (!framebuffer->appendToStartedRenderPass(contextVk->getCommandGraph(), params.blitArea,
&commandBuffer))
if (!framebuffer->appendToStartedRenderPass(&contextVk->getCommandGraph()->getResourceUseList(),
params.blitArea, &commandBuffer))
{
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer));
}
......@@ -1546,7 +1546,7 @@ angle::Result UtilsVk::stencilBlitResolveNoShaderExport(ContextVk *contextVk,
ANGLE_TRY(
blitBuffer.get().init(contextVk, blitBufferInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
blitBuffer.get().onGraphAccess(contextVk->getCommandGraph());
blitBuffer.get().onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
BlitResolveStencilNoExportShaderParams shaderParams;
if (isResolve)
......
......@@ -2904,7 +2904,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
BufferHelper *currentBuffer = bufferUpdate.bufferHelper;
ASSERT(currentBuffer && currentBuffer->valid());
currentBuffer->onGraphAccess(contextVk->getCommandGraph());
currentBuffer->onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
commandBuffer->copyBufferToImage(currentBuffer->getBuffer().getHandle(), mImage,
getCurrentLayout(), 1, &update.buffer.copyRegion);
......@@ -3204,7 +3204,7 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
ANGLE_TRY(resolvedImage.get().init2DStaging(
contextVk, renderer->getMemoryProperties(), gl::Extents(area.width, area.height, 1),
*mFormat, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, 1));
resolvedImage.get().onGraphAccess(contextVk->getCommandGraph());
resolvedImage.get().onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
// Note: resolve only works on color images (not depth/stencil).
//
......@@ -3483,7 +3483,7 @@ angle::Result ImageViewHelper::getLevelDrawImageView(ContextVk *contextVk,
uint32_t layer,
const ImageView **imageViewOut)
{
onGraphAccess(contextVk->getCommandGraph());
onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
// TODO(http://anglebug.com/4008): Possibly incorrect level count.
ImageView *imageView = GetLevelImageView(&mLevelDrawImageViews, level, 1);
......@@ -3508,7 +3508,7 @@ angle::Result ImageViewHelper::getLevelLayerDrawImageView(ContextVk *contextVk,
ASSERT(image.valid());
ASSERT(!image.getFormat().actualImageFormat().isBlock);
onGraphAccess(contextVk->getCommandGraph());
onGraphAccess(&contextVk->getCommandGraph()->getResourceUseList());
uint32_t layerCount = GetImageLayerCountForView(image);
......
......@@ -1077,7 +1077,7 @@ class ImageViewHelper : angle::NonCopyable
bool hasFetchImageView() const { return mFetchImageView.valid(); }
// Store reference to usage in graph.
void onGraphAccess(CommandGraph *commandGraph) const { commandGraph->onResourceUse(mUse); }
void onGraphAccess(ResourceUseList *resourceUseList) const { resourceUseList->add(mUse); }
// Creates views with multiple layers and levels.
angle::Result initReadViews(ContextVk *contextVk,
......@@ -1132,7 +1132,7 @@ class SamplerHelper final : angle::NonCopyable
Sampler &get() { return mSampler; }
const Sampler &get() const { return mSampler; }
void onGraphAccess(CommandGraph *commandGraph) { commandGraph->onResourceUse(mUse); }
void onGraphAccess(ResourceUseList *resourceUseList) { resourceUseList->add(mUse); }
private:
SharedResourceUse mUse;
......
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