Vulkan: Remove CommandGraph code.

Also updates relevant comments to no longer refer to a graph.

Bug: angleproject:4029
Change-Id: Ic29716e9ae4926870f902947d49d8fee7af98662
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2057804
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Tim Van Patten <timvp@google.com>
This commit is contained in:
Jamie Madill 2020-02-19 14:51:41 -05:00 коммит произвёл Commit Bot
Родитель 519163eeb4
Коммит c58458e633
24 изменённых файлов: 327 добавлений и 3464 удалений

Просмотреть файл

@ -222,14 +222,6 @@ struct FeaturesVk : FeatureSetBase
"VkDevice supports the VK_EXT_swapchain_colorspace extension", &members,
"http://anglebug.com/2514"};
// Whether to use ANGLE's deferred command graph. http://anglebug.com/4029
Feature commandGraph = {
"command_graph",
FeatureCategory::VulkanFeatures,
"Use ANGLE's Vulkan deferred command graph.",
&members,
};
// Whether the VkDevice supports the VK_EXT_external_memory_host extension, on which the
// ANGLE_iosurface_client_buffer extension can be layered.
Feature supportsExternalMemoryHost = {

Просмотреть файл

@ -208,31 +208,9 @@ angle::Result BufferVk::copySubData(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
// Handle self-dependency especially.
if (sourceBuffer->mBuffer.getBuffer().getHandle() == mBuffer.getBuffer().getHandle())
{
// We set the TRANSFER_READ_BIT to be conservative.
mBuffer.onSelfReadWrite(contextVk,
VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT);
ANGLE_TRY(mBuffer.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(mBuffer.recordCommands(contextVk, &commandBuffer));
sourceBuffer->mBuffer.onReadByBuffer(contextVk, &mBuffer, VK_ACCESS_TRANSFER_READ_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
}
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &sourceBuffer->getBuffer()));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &sourceBuffer->getBuffer()));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Enqueue a copy command on the GPU.
const VkBufferCopy copyRegion = {static_cast<VkDeviceSize>(sourceOffset),
@ -415,24 +393,12 @@ angle::Result BufferVk::copyToBuffer(ContextVk *contextVk,
const VkBufferCopy *copies)
{
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(destBuffer->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &mBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
commandBuffer->copyBuffer(mBuffer.getBuffer(), destBuffer->getBuffer(), copyCount, copies);
if (contextVk->commandGraphEnabled())
{
mBuffer.onReadByBuffer(contextVk, destBuffer, VK_ACCESS_TRANSFER_READ_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
}
return angle::Result::Continue;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -20,48 +20,6 @@ namespace vk
{
class CommandGraph;
enum class VisitedState
{
Unvisited,
Ready,
Visited,
};
enum class CommandGraphResourceType
{
Buffer,
Framebuffer,
Image,
Query,
Dispatcher,
// Transform feedback queries could be handled entirely on the CPU (if not using
// VK_EXT_transform_feedback), but still need to generate a command graph barrier node.
EmulatedQuery,
FenceSync,
GraphBarrier,
DebugMarker,
HostAvailabilityOperation,
};
// Certain functionality cannot be put in secondary command buffers, so they are special-cased in
// the node.
enum class CommandGraphNodeFunction
{
Generic,
BeginQuery,
EndQuery,
WriteTimestamp,
BeginTransformFeedbackQuery,
EndTransformFeedbackQuery,
SetFenceSync,
WaitFenceSync,
GraphBarrier,
InsertDebugMarker,
PushDebugMarker,
PopDebugMarker,
HostAvailabilityOperation,
};
// Receives notifications when a render pass command buffer is no longer able to record. Can be
// used with inheritance. Faster than using an interface class since it has inlined methods. Could
// be used with composition by adding a getCommandBuffer method.
@ -77,218 +35,6 @@ class RenderPassOwner
CommandBuffer *mRenderPassCommandBuffer = nullptr;
};
// Only used internally in the command graph. Kept in the header for better inlining performance.
class CommandGraphNode final : angle::NonCopyable
{
public:
CommandGraphNode(CommandGraphNodeFunction function, angle::PoolAllocator *poolAllocator);
~CommandGraphNode();
// Immutable queries for when we're walking the commands tree.
CommandBuffer *getOutsideRenderPassCommands()
{
ASSERT(!mHasChildren);
return &mOutsideRenderPassCommands;
}
CommandBuffer *getInsideRenderPassCommands()
{
ASSERT(!mHasChildren);
return &mInsideRenderPassCommands;
}
// For outside the render pass (copies, transitions, etc).
angle::Result beginOutsideRenderPassRecording(ContextVk *context,
const CommandPool &commandPool,
CommandBuffer **commandsOut);
// For rendering commands (draws).
angle::Result beginInsideRenderPassRecording(ContextVk *context, CommandBuffer **commandsOut);
// storeRenderPassInfo and append*RenderTarget store info relevant to the RenderPass.
void storeRenderPassInfo(const Framebuffer &framebuffer,
const gl::Rectangle renderArea,
const vk::RenderPassDesc &renderPassDesc,
const AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues);
void clearRenderPassColorAttachment(size_t attachmentIndex, const VkClearColorValue &clearValue)
{
mRenderPassAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].color = clearValue;
}
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth)
{
mRenderPassAttachmentOps[attachmentIndex].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].depthStencil.depth = depth;
}
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil)
{
mRenderPassAttachmentOps[attachmentIndex].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
mRenderPassClearValues[attachmentIndex].depthStencil.stencil = stencil;
}
void invalidateRenderPassColorAttachment(size_t attachmentIndex)
{
mRenderPassAttachmentOps[attachmentIndex].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
void invalidateRenderPassDepthAttachment(size_t attachmentIndex)
{
mRenderPassAttachmentOps[attachmentIndex].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
void invalidateRenderPassStencilAttachment(size_t attachmentIndex)
{
mRenderPassAttachmentOps[attachmentIndex].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
// Dependency commands order node execution in the command graph.
// 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)
{
ASSERT(beforeNode != afterNode && !beforeNode->isChildOf(afterNode));
afterNode->mParents.emplace_back(beforeNode);
beforeNode->setHasChildren();
}
static void SetHappensBeforeDependencies(CommandGraphNode **beforeNodes,
size_t beforeNodesCount,
CommandGraphNode *afterNode);
static void SetHappensBeforeDependencies(CommandGraphNode *beforeNode,
CommandGraphNode **afterNodes,
size_t afterNodesCount);
bool hasParents() const;
bool hasChildren() const { return mHasChildren; }
// Commands for traversing the node on a flush operation.
VisitedState visitedState() const;
void visitParents(std::vector<CommandGraphNode *> *stack);
angle::Result visitAndExecute(Context *context,
Serial serial,
RenderPassCache *renderPassCache,
PrimaryCommandBuffer *primaryCommandBuffer);
// Only used in the command graph diagnostics.
const std::vector<CommandGraphNode *> &getParentsForDiagnostics() const;
void setDiagnosticInfo(CommandGraphResourceType resourceType, uintptr_t resourceID);
CommandGraphResourceType getResourceTypeForDiagnostics() const { return mResourceType; }
uintptr_t getResourceIDForDiagnostics() const { return mResourceID; }
bool hasDiagnosticID() const;
std::string dumpCommandsForDiagnostics(const char *separator) const;
void getMemoryUsageStatsForDiagnostics(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;
const gl::Rectangle &getRenderPassRenderArea() const { return mRenderPassRenderArea; }
CommandGraphNodeFunction getFunction() const { return mFunction; }
void setQueryPool(const QueryPool *queryPool, uint32_t queryIndex);
VkQueryPool getQueryPool() const { return mQueryPool; }
uint32_t getQueryIndex() const { return mQueryIndex; }
void setFenceSync(const vk::Event &event);
void setDebugMarker(GLenum source, std::string &&marker);
const std::string &getDebugMarker() const { return mDebugMarker; }
ANGLE_INLINE void addGlobalMemoryBarrier(VkFlags srcAccess,
VkFlags dstAccess,
VkPipelineStageFlags stages)
{
mGlobalMemoryBarrierSrcAccess |= srcAccess;
mGlobalMemoryBarrierDstAccess |= dstAccess;
mGlobalMemoryBarrierStages |= stages;
}
ANGLE_INLINE void setActiveTransformFeedbackInfo(size_t validBufferCount,
const VkBuffer *counterBuffers,
bool rebindBuffer)
{
mValidTransformFeedbackBufferCount = static_cast<uint32_t>(validBufferCount);
mRebindTransformFeedbackBuffers = rebindBuffer;
for (size_t index = 0; index < validBufferCount; index++)
{
mTransformFeedbackCounterBuffers[index] = counterBuffers[index];
}
}
// This can only be set for RenderPass nodes. Each RenderPass node can have at most one owner.
void setRenderPassOwner(RenderPassOwner *owner)
{
ASSERT(mRenderPassOwner == nullptr);
mRenderPassOwner = owner;
}
private:
ANGLE_INLINE void setHasChildren()
{
mHasChildren = true;
if (mRenderPassOwner)
{
mRenderPassOwner->onRenderPassFinished();
}
}
// Used for testing only.
bool isChildOf(CommandGraphNode *parent);
// Only used if we need a RenderPass for these commands.
RenderPassDesc mRenderPassDesc;
AttachmentOpsArray mRenderPassAttachmentOps;
Framebuffer mRenderPassFramebuffer;
gl::Rectangle mRenderPassRenderArea;
gl::AttachmentArray<VkClearValue> mRenderPassClearValues;
CommandGraphNodeFunction mFunction;
angle::PoolAllocator *mPoolAllocator;
// Keep separate buffers for commands inside and outside a RenderPass.
// TODO(jmadill): We might not need inside and outside RenderPass commands separate.
CommandBuffer mOutsideRenderPassCommands;
CommandBuffer mInsideRenderPassCommands;
// Special-function additional data:
// Queries:
VkQueryPool mQueryPool;
uint32_t mQueryIndex;
// GLsync and EGLSync:
VkEvent mFenceSyncEvent;
// Debug markers:
GLenum mDebugMarkerSource;
std::string mDebugMarker;
// Parents are commands that must be submitted before 'this' CommandNode can be submitted.
std::vector<CommandGraphNode *> mParents;
// If this is true, other commands exist that must be submitted after 'this' command.
bool mHasChildren;
// Used when traversing the dependency graph.
VisitedState mVisitedState;
// Additional diagnostic information.
CommandGraphResourceType mResourceType;
uintptr_t mResourceID;
// For global memory barriers.
VkFlags mGlobalMemoryBarrierSrcAccess;
VkFlags mGlobalMemoryBarrierDstAccess;
VkPipelineStageFlags mGlobalMemoryBarrierStages;
// Render pass command buffer notifications.
RenderPassOwner *mRenderPassOwner;
// Active transform feedback state
gl::TransformFeedbackBuffersArray<VkBuffer> mTransformFeedbackCounterBuffers;
uint32_t mValidTransformFeedbackBufferCount;
bool mRebindTransformFeedbackBuffers;
};
// 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
@ -458,16 +204,10 @@ class CommandGraphResource : angle::NonCopyable
// Ensures the driver is caught up to this resource and it is only in use by ANGLE.
angle::Result finishRunningCommands(ContextVk *contextVk);
// Sets up dependency relations. 'this' resource is the resource being written to.
void addWriteDependency(ContextVk *contextVk, CommandGraphResource *writingResource);
// Sets up dependency relations. 'this' resource is the resource being read.
void addReadDependency(ContextVk *contextVk, CommandGraphResource *readingResource);
// Updates the in-use serial tracked for this resource. Will clear dependencies if the resource
// was not used in this set of command nodes.
// TODO(jmadill): Merge and rename. http://anglebug.com/4029
void onResourceAccess(ResourceUseList *resourceUseList);
void updateCurrentAccessNodes();
// If a resource is recreated, as in released and reinitialized, the next access to the
// resource will not create an edge from its last node and will create a new independent node.
@ -475,226 +215,16 @@ 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.
// TODO(jmadill): Merge and rename. http://anglebug.com/4029
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.
// Will append to an existing command buffer/graph node if possible.
angle::Result recordCommands(ContextVk *context, CommandBuffer **commandBufferOut);
// Begins a command buffer on the current graph node for in-RenderPass rendering.
// Called from FramebufferVk::startNewRenderPass and UtilsVk functions.
angle::Result beginRenderPass(ContextVk *contextVk,
const Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const RenderPassDesc &renderPassDesc,
const AttachmentOpsArray &renderPassAttachmentOps,
const std::vector<VkClearValue> &clearValues,
CommandBuffer **commandBufferOut);
// Checks if we're in a RenderPass without children.
bool hasStartedRenderPass() const;
// 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(ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
CommandBuffer **commandBufferOut);
// Returns true if the render pass is started, but there are no commands yet recorded in it.
// This is useful to know if the render pass ops can be modified.
bool renderPassStartedButEmpty() const;
void clearRenderPassColorAttachment(size_t attachmentIndex,
const VkClearColorValue &clearValue);
void clearRenderPassDepthAttachment(size_t attachmentIndex, float depth);
void clearRenderPassStencilAttachment(size_t attachmentIndex, uint32_t stencil);
void invalidateRenderPassColorAttachment(size_t attachmentIndex);
void invalidateRenderPassDepthAttachment(size_t attachmentIndex);
void invalidateRenderPassStencilAttachment(size_t attachmentIndex);
// Accessor for RenderPass RenderArea.
const gl::Rectangle &getRenderPassRenderArea() const;
// Called when 'this' object changes, but we'd like to start a new command buffer later.
void finishCurrentCommands(ContextVk *contextVk);
// Store a deferred memory barrier. Will be recorded into a primary command buffer at submit.
void addGlobalMemoryBarrier(VkFlags srcAccess, VkFlags dstAccess, VkPipelineStageFlags stages);
// Sets active transform feedback information to current writing node.
void setActiveTransformFeedbackInfo(size_t validBufferCount,
const VkBuffer *counterBuffers,
bool rebindBuffer);
protected:
explicit CommandGraphResource(CommandGraphResourceType resourceType);
CommandGraphResource();
// Current resource lifetime.
SharedResourceUse mUse;
private:
// Returns true if this node has a current writing node with no children.
ANGLE_INLINE bool hasChildlessWritingNode() const;
void startNewCommands(ContextVk *contextVk);
void onWriteImpl(ContextVk *contextVk, CommandGraphNode *writingNode);
std::vector<CommandGraphNode *> mCurrentReadingNodes;
// Current command graph writing node.
CommandGraphNode *mCurrentWritingNode;
// Additional diagnostic information.
CommandGraphResourceType mResourceType;
};
// Translating OpenGL commands into Vulkan and submitting them immediately loses out on some
// of the powerful flexiblity Vulkan offers in RenderPasses. Load/Store ops can automatically
// clear RenderPass attachments, or preserve the contents. RenderPass automatic layout transitions
// can improve certain performance cases. Also, we can remove redundant RenderPass Begin and Ends
// when processing interleaved draw operations on independent Framebuffers.
//
// ANGLE's CommandGraph (and CommandGraphNode) attempt to solve these problems using deferred
// command submission. We also sometimes call this command re-ordering. A brief summary:
//
// During GL command processing, we record Vulkan commands into SecondaryCommandBuffers, which
// are stored in CommandGraphNodes, and these nodes are chained together via dependencies to
// form a directed acyclic CommandGraph. When we need to submit the CommandGraph, say during a
// SwapBuffers or ReadPixels call, we begin a primary Vulkan CommandBuffer, and walk the
// CommandGraph, starting at the most senior nodes, recording SecondaryCommandBuffers inside
// and outside RenderPasses as necessary, filled with the right load/store operations. Once
// the primary CommandBuffer has recorded all of the SecondaryCommandBuffers from all the open
// CommandGraphNodes, we submit the primary CommandBuffer to the VkQueue on the device.
//
// The Command Graph consists of an array of open Command Graph Nodes. It supports allocating new
// nodes for the graph, which are linked via dependency relation calls in CommandGraphNode, and
// also submitting the whole command graph via submitCommands.
class CommandGraph final : angle::NonCopyable
{
public:
explicit CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *poolAllocator);
~CommandGraph();
// Allocates a new CommandGraphNode and adds it to the list of current open nodes. No ordering
// relations exist in the node by default. Call CommandGraphNode::SetHappensBeforeDependency
// to set up dependency relations. If the node is a barrier, it will automatically add
// dependencies between the previous barrier, the new barrier and all nodes in between.
CommandGraphNode *allocateNode(CommandGraphNodeFunction function);
angle::Result submitCommands(ContextVk *context,
Serial serial,
RenderPassCache *renderPassCache,
PrimaryCommandBuffer *primaryCommandBuffer);
bool empty() const;
void clear();
// The following create special-function nodes that don't require a graph resource.
// Queries:
void beginQuery(const QueryPool *queryPool, uint32_t queryIndex);
void endQuery(const QueryPool *queryPool, uint32_t queryIndex);
void writeTimestamp(const QueryPool *queryPool, uint32_t queryIndex);
void beginTransformFeedbackEmulatedQuery();
void endTransformFeedbackEmulatedQuery();
// GLsync and EGLSync:
void setFenceSync(const vk::Event &event);
void waitFenceSync(const vk::Event &event);
// Memory barriers:
void memoryBarrier(VkFlags srcAccess, VkFlags dstAccess, VkPipelineStageFlags stages);
// Debug markers:
void insertDebugMarker(GLenum source, std::string &&marker);
void pushDebugMarker(GLenum source, std::string &&marker);
void popDebugMarker();
// Host-visible buffer write availability operation:
void makeHostVisibleBufferWriteAvailable();
// External memory synchronization:
void syncExternalMemory();
void tickRenderPassCount() { mRenderPassCount++; }
private:
CommandGraphNode *allocateBarrierNode(CommandGraphNodeFunction function,
CommandGraphResourceType resourceType,
uintptr_t resourceID);
void setNewBarrier(CommandGraphNode *newBarrier);
CommandGraphNode *getLastBarrierNode(size_t *indexOut);
void addDependenciesToNextBarrier(size_t begin, size_t end, CommandGraphNode *nextBarrier);
void dumpGraphDotFile(std::ostream &out) const;
void updateOverlay(ContextVk *contextVk) const;
std::vector<CommandGraphNode *> mNodes;
bool mEnableGraphDiagnostics;
angle::PoolAllocator *mPoolAllocator;
// 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
// node Bi, and the other nodes Ni. The edges between Ni don't interest us. Before a barrier is
// inserted, we have:
//
// N0 N1 ... Na
// \___\__/_/ (dependency egdes, which we don't care about so I'll stop drawing them.
// \/
//
// When the first barrier is inserted, we will have:
//
// ______
// / ____\
// / / \
// / / /\
// N0 N1 ... Na B0
//
// This makes sure all N0..Na are called before B0. From then on, B0 will be the current
// "barrier point" which extends an edge to every next node:
//
// ______
// / ____\
// / / \
// / / /\
// N0 N1 ... Na B0 Na+1 ... Nb
// \/ /
// \______/
//
//
// When the next barrier B1 is met, all nodes between B0 and B1 will add a depenency on B1 as
// well, and the "barrier point" is updated.
//
// ______
// / ____\ ______ ______
// / / \ / \ / \
// / / /\ / /\ / /\
// N0 N1 ... Na B0 Na+1 ... Nb B1 Nb+1 ... Nc B2 ...
// \/ / / \/ / /
// \______/ / \______/ /
// \_______/ \_______/
//
//
// When barrier Bi is introduced, all nodes added since Bi-1 need to add a dependency to Bi
// (including Bi-1). We therefore keep track of the node index of the last barrier that was
// issued.
static constexpr size_t kInvalidNodeIndex = std::numeric_limits<std::size_t>::max();
size_t mLastBarrierIndex;
uint32_t mRenderPassCount;
};
// CommandGraphResource inlines.
ANGLE_INLINE bool CommandGraphResource::hasStartedRenderPass() const
{
return hasChildlessWritingNode() && mCurrentWritingNode->getInsideRenderPassCommands()->valid();
}
ANGLE_INLINE void CommandGraphResource::updateCurrentAccessNodes()
{
// Clear dependencies if this is a new access.
if (!mUse.hasRecordedCommands())
{
mCurrentWritingNode = nullptr;
mCurrentReadingNodes.clear();
}
}
ANGLE_INLINE void CommandGraphResource::onResourceRecreated(ResourceUseList *resourceUseList)
{
// Store reference in resource list.
@ -703,115 +233,9 @@ ANGLE_INLINE void CommandGraphResource::onResourceRecreated(ResourceUseList *res
ANGLE_INLINE void CommandGraphResource::onResourceAccess(ResourceUseList *resourceUseList)
{
updateCurrentAccessNodes();
// Store reference in resource list.
resourceUseList->add(mUse);
}
ANGLE_INLINE bool CommandGraphResource::appendToStartedRenderPass(ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
CommandBuffer **commandBufferOut)
{
updateCurrentAccessNodes();
if (hasStartedRenderPass())
{
// Store reference in resource list.
resourceUseList->add(mUse);
if (mCurrentWritingNode->getRenderPassRenderArea().encloses(renderArea))
{
*commandBufferOut = mCurrentWritingNode->getInsideRenderPassCommands();
return true;
}
}
return false;
}
ANGLE_INLINE bool CommandGraphResource::renderPassStartedButEmpty() const
{
return hasStartedRenderPass() && (!vk::CommandBuffer::CanKnowIfEmpty() ||
mCurrentWritingNode->getInsideRenderPassCommands()->empty());
}
ANGLE_INLINE void CommandGraphResource::clearRenderPassColorAttachment(
size_t attachmentIndex,
const VkClearColorValue &clearValue)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassColorAttachment(attachmentIndex, clearValue);
}
ANGLE_INLINE void CommandGraphResource::clearRenderPassDepthAttachment(size_t attachmentIndex,
float depth)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassDepthAttachment(attachmentIndex, depth);
}
ANGLE_INLINE void CommandGraphResource::clearRenderPassStencilAttachment(size_t attachmentIndex,
uint32_t stencil)
{
ASSERT(renderPassStartedButEmpty());
mCurrentWritingNode->clearRenderPassStencilAttachment(attachmentIndex, stencil);
}
ANGLE_INLINE void CommandGraphResource::invalidateRenderPassColorAttachment(size_t attachmentIndex)
{
ASSERT(hasStartedRenderPass());
mCurrentWritingNode->invalidateRenderPassColorAttachment(attachmentIndex);
}
ANGLE_INLINE void CommandGraphResource::invalidateRenderPassDepthAttachment(size_t attachmentIndex)
{
ASSERT(hasStartedRenderPass());
mCurrentWritingNode->invalidateRenderPassDepthAttachment(attachmentIndex);
}
ANGLE_INLINE void CommandGraphResource::invalidateRenderPassStencilAttachment(
size_t attachmentIndex)
{
ASSERT(hasStartedRenderPass());
mCurrentWritingNode->invalidateRenderPassStencilAttachment(attachmentIndex);
}
ANGLE_INLINE const gl::Rectangle &CommandGraphResource::getRenderPassRenderArea() const
{
ASSERT(hasStartedRenderPass());
return mCurrentWritingNode->getRenderPassRenderArea();
}
ANGLE_INLINE void CommandGraphResource::addGlobalMemoryBarrier(VkFlags srcAccess,
VkFlags dstAccess,
VkPipelineStageFlags stages)
{
ASSERT(mCurrentWritingNode);
mCurrentWritingNode->addGlobalMemoryBarrier(srcAccess, dstAccess, stages);
}
ANGLE_INLINE void CommandGraphResource::setActiveTransformFeedbackInfo(
size_t validBufferCount,
const VkBuffer *counterBuffers,
bool rebindBuffer)
{
ASSERT(mCurrentWritingNode);
mCurrentWritingNode->setActiveTransformFeedbackInfo(validBufferCount, counterBuffers,
rebindBuffer);
}
ANGLE_INLINE bool CommandGraphResource::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
// resources either. As such, we expect the function to always be generic here. If such a
// resource is added in the future, this can add a check for function == generic and fail if
// false.
ASSERT(mCurrentWritingNode == nullptr ||
mCurrentWritingNode->getFunction() == CommandGraphNodeFunction::Generic);
return (mCurrentWritingNode != nullptr && !mCurrentWritingNode->hasChildren());
}
} // namespace vk
} // namespace rx

Просмотреть файл

@ -19,7 +19,6 @@
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/BufferVk.h"
#include "libANGLE/renderer/vulkan/CommandGraph.h"
#include "libANGLE/renderer/vulkan/CompilerVk.h"
#include "libANGLE/renderer/vulkan/FenceNVVk.h"
#include "libANGLE/renderer/vulkan/FramebufferVk.h"
@ -531,7 +530,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mEmulateSeamfulCubeMapSampling(false),
mUseOldRewriteStructSamplers(false),
mPoolAllocator(kDefaultPoolAllocatorPageSize, 1),
mCommandGraph(kEnableCommandStreamDiagnostics, &mPoolAllocator),
mGpuEventsEnabled(false),
mGpuClockSync{std::numeric_limits<double>::max(), std::numeric_limits<double>::max()},
mGpuEventTimestampOrigin(0),
@ -743,21 +741,17 @@ angle::Result ContextVk::initialize()
mUseOldRewriteStructSamplers = shouldUseOldRewriteStructSamplers();
if (!commandGraphEnabled())
{
// Push a scope in the pool allocator so we can easily reinitialize on flush.
mPoolAllocator.push();
mOutsideRenderPassCommands.getCommandBuffer().initialize(&mPoolAllocator);
mRenderPassCommands.initialize(&mPoolAllocator);
ANGLE_TRY(startPrimaryCommandBuffer());
}
// Push a scope in the pool allocator so we can easily reinitialize on flush.
mPoolAllocator.push();
mOutsideRenderPassCommands.getCommandBuffer().initialize(&mPoolAllocator);
mRenderPassCommands.initialize(&mPoolAllocator);
ANGLE_TRY(startPrimaryCommandBuffer());
return angle::Result::Continue;
}
angle::Result ContextVk::startPrimaryCommandBuffer()
{
ASSERT(!commandGraphEnabled());
ANGLE_TRY(mCommandQueue.allocatePrimaryCommandBuffer(this, mCommandPool, &mPrimaryCommands));
VkCommandBufferBeginInfo beginInfo = {};
@ -816,13 +810,8 @@ angle::Result ContextVk::setupDraw(const gl::Context *context,
mGraphicsDirtyBits |= mNewGraphicsCommandBufferDirtyBits;
gl::Rectangle scissoredRenderArea = mDrawFramebuffer->getScissoredRenderArea(this);
if (!commandGraphEnabled() ||
!mDrawFramebuffer->appendToStartedRenderPass(&mResourceUseList, scissoredRenderArea,
&mRenderPassCommandBuffer))
{
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, scissoredRenderArea,
&mRenderPassCommandBuffer));
}
ANGLE_TRY(mDrawFramebuffer->startNewRenderPass(this, scissoredRenderArea,
&mRenderPassCommandBuffer));
}
// We keep a local copy of the command buffer. It's possible that some state changes could
@ -918,16 +907,8 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
GLsizei vertexCount = 0;
GLsizei instanceCount = 1;
if (commandGraphEnabled())
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
indirectBuffer->onRead(this, framebuffer, VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
}
else
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
indirectBuffer);
}
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
indirectBuffer);
ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount,
gl::DrawElementsType::InvalidEnum, nullptr, dirtyBitMask,
@ -1036,19 +1017,12 @@ angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
angle::Result ContextVk::setupDispatch(const gl::Context *context,
vk::CommandBuffer **commandBufferOut)
{
if (commandGraphEnabled())
{
ANGLE_TRY(mDispatcher.recordCommands(this, commandBufferOut));
}
else
{
// |setupDispatch| and |setupDraw| are special in that they flush dirty bits. Therefore they
// don't use the same APIs to record commands as the functions outside ContextVk.
// The following ensures prior commands are flushed before we start processing dirty bits.
mOutsideRenderPassCommands.flushToPrimary(this, &mPrimaryCommands);
ANGLE_TRY(endRenderPass());
*commandBufferOut = &mOutsideRenderPassCommands.getCommandBuffer();
}
// |setupDispatch| and |setupDraw| are special in that they flush dirty bits. Therefore they
// don't use the same APIs to record commands as the functions outside ContextVk.
// The following ensures prior commands are flushed before we start processing dirty bits.
mOutsideRenderPassCommands.flushToPrimary(this, &mPrimaryCommands);
ANGLE_TRY(endRenderPass());
*commandBufferOut = &mOutsideRenderPassCommands.getCommandBuffer();
if (mProgram->dirtyUniforms())
{
@ -1164,24 +1138,8 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(
}
// Ensure the image is in read-only layout
if (commandGraphEnabled())
{
if (image.isLayoutChangeNecessary(textureLayout))
{
vk::CommandBuffer *srcLayoutChange;
VkImageAspectFlags aspectFlags = image.getAspectFlags();
ASSERT(aspectFlags != 0);
ANGLE_TRY(image.recordCommands(this, &srcLayoutChange));
image.changeLayout(aspectFlags, textureLayout, srcLayoutChange);
}
image.addReadDependency(this, recorder);
}
else
{
commandBufferHelper->imageRead(&mResourceUseList, image.getAspectFlags(), textureLayout,
&image);
}
commandBufferHelper->imageRead(&mResourceUseList, image.getAspectFlags(), textureLayout,
&image);
textureVk->onImageViewUse(&mResourceUseList);
@ -1229,32 +1187,16 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(const gl::Context *con
const gl::AttribArray<vk::BufferHelper *> &arrayBufferResources =
mVertexArray->getCurrentArrayBuffers();
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
// Mark all active vertex buffers as accessed by the graph.
if (commandGraphEnabled())
// Mark all active vertex buffers as accessed.
gl::AttributesMask attribsMask = mProgram->getState().getActiveAttribLocationsMask();
for (size_t attribIndex : attribsMask)
{
gl::AttributesMask attribsMask = mProgram->getState().getActiveAttribLocationsMask();
for (size_t attribIndex : attribsMask)
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
if (arrayBuffer)
{
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
if (arrayBuffer)
{
arrayBuffer->onRead(this, framebuffer, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
}
}
}
else
{
gl::AttributesMask attribsMask = mProgram->getState().getActiveAttribLocationsMask();
for (size_t attribIndex : attribsMask)
{
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
if (arrayBuffer)
{
mRenderPassCommands.bufferRead(&mResourceUseList,
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, arrayBuffer);
}
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
arrayBuffer);
}
}
@ -1271,16 +1213,7 @@ angle::Result ContextVk::handleDirtyGraphicsIndexBuffer(const gl::Context *conte
mVertexArray->getCurrentElementArrayBufferOffset(),
gl_vk::kIndexTypeMap[mCurrentDrawElementsType]);
if (commandGraphEnabled())
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
elementArrayBuffer->onRead(this, framebuffer, VK_ACCESS_INDEX_READ_BIT);
}
else
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT,
elementArrayBuffer);
}
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT, elementArrayBuffer);
return angle::Result::Continue;
}
@ -1325,23 +1258,20 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation(
{
if (mProgram->hasTransformFeedbackOutput() && mState.isTransformFeedbackActive())
{
if (!commandGraphEnabled())
size_t bufferCount = mProgram->getState().getTransformFeedbackBufferCount();
const std::vector<gl::OffsetBindingPointer<gl::Buffer>> &xfbBuffers =
mState.getCurrentTransformFeedback()->getIndexedBuffers();
for (size_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex)
{
size_t bufferCount = mProgram->getState().getTransformFeedbackBufferCount();
const std::vector<gl::OffsetBindingPointer<gl::Buffer>> &xfbBuffers =
mState.getCurrentTransformFeedback()->getIndexedBuffers();
const gl::OffsetBindingPointer<gl::Buffer> &xfbBuffer = xfbBuffers[bufferIndex];
gl::Buffer *buffer = xfbBuffer.get();
ASSERT(buffer != nullptr);
BufferVk *bufferVk = vk::GetImpl(buffer);
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
for (size_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex)
{
const gl::OffsetBindingPointer<gl::Buffer> &xfbBuffer = xfbBuffers[bufferIndex];
gl::Buffer *buffer = xfbBuffer.get();
ASSERT(buffer != nullptr);
BufferVk *bufferVk = vk::GetImpl(buffer);
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
mRenderPassCommands.bufferWrite(
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
}
mRenderPassCommands.bufferWrite(
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
}
ANGLE_TRY(mProgram->updateTransformFeedbackDescriptorSet(
@ -1376,11 +1306,8 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension(
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
bufferHandles[bufferIndex] = bufferHelper.getBuffer().getHandle();
if (!commandGraphEnabled())
{
mRenderPassCommands.bufferWrite(
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
}
mRenderPassCommands.bufferWrite(&mResourceUseList,
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
}
const TransformFeedbackBufferRange &xfbBufferRangeExtension =
@ -1390,12 +1317,6 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension(
static_cast<uint32_t>(bufferCount), bufferHandles.data(),
xfbBufferRangeExtension.offsets.data(), xfbBufferRangeExtension.sizes.data());
if (commandGraphEnabled())
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
transformFeedbackVk->addFramebufferDependency(this, mProgram->getState(), framebuffer);
}
return angle::Result::Continue;
}
@ -1412,19 +1333,10 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackState(const gl::Con
const gl::TransformFeedbackBuffersArray<VkBuffer> &counterBufferHandles =
transformFeedbackVk->getCounterBufferHandles();
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
bool rebindBuffer = transformFeedbackVk->getTransformFeedbackBufferRebindState();
if (commandGraphEnabled())
{
framebuffer->setActiveTransformFeedbackInfo(bufferCount, counterBufferHandles.data(),
rebindBuffer);
}
else
{
mRenderPassCommands.beginTransformFeedback(bufferCount, counterBufferHandles.data(),
rebindBuffer);
}
mRenderPassCommands.beginTransformFeedback(bufferCount, counterBufferHandles.data(),
rebindBuffer);
transformFeedbackVk->unsetTransformFeedbackBufferRebindState();
@ -1442,17 +1354,14 @@ angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
vk::PrimaryCommandBuffer &&commandBuffer)
{
// Update overlay if active.
if (!commandGraphEnabled())
{
gl::RunningGraphWidget *renderPassCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
renderPassCount->add(mRenderPassCommands.getAndResetCounter());
renderPassCount->next();
gl::RunningGraphWidget *renderPassCount =
mState.getOverlay()->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount);
renderPassCount->add(mRenderPassCommands.getAndResetCounter());
renderPassCount->next();
if (kEnableCommandStreamDiagnostics)
{
dumpCommandStreamDiagnostics();
}
if (kEnableCommandStreamDiagnostics)
{
dumpCommandStreamDiagnostics();
}
ANGLE_TRY(ensureSubmitFenceInitialized());
@ -1475,22 +1384,6 @@ angle::Result ContextVk::submitFrame(const VkSubmitInfo &submitInfo,
return angle::Result::Continue;
}
angle::Result ContextVk::flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch)
{
ASSERT(commandGraphEnabled());
if (mIsAnyHostVisibleBufferWritten)
{
mCommandGraph.makeHostVisibleBufferWriteAvailable();
}
mIsAnyHostVisibleBufferWritten = false;
Serial serial = getCurrentQueueSerial();
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial);
return mCommandGraph.submitCommands(this, serial, &mRenderPassCache, commandBatch);
}
angle::Result ContextVk::synchronizeCpuGpuTime()
{
ASSERT(mGpuEventsEnabled);
@ -1564,7 +1457,7 @@ angle::Result ContextVk::synchronizeCpuGpuTime()
// Note: Once VK_EXT_calibrated_timestamps is ubiquitous, this should be redone.
// Make sure nothing is running
ASSERT(mCommandGraph.empty());
ASSERT(!hasRecordedCommands());
ANGLE_TRACE_EVENT0("gpu.angle", "RendererVk::synchronizeCpuGpuTime");
@ -1839,15 +1732,8 @@ void ContextVk::clearAllGarbage()
void ContextVk::handleDeviceLost()
{
if (commandGraphEnabled())
{
mCommandGraph.clear();
}
else
{
mOutsideRenderPassCommands.reset();
mRenderPassCommands.reset();
}
mOutsideRenderPassCommands.reset();
mRenderPassCommands.reset();
mCommandQueue.handleDeviceLost(mRenderer);
clearAllGarbage();
@ -2096,16 +1982,8 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any())
{
if (commandGraphEnabled())
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
currentIndirectBuf->onRead(this, framebuffer, VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
}
else
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
}
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
// We have instanced vertex attributes that need to be emulated for Vulkan.
// invalidate any cache and map the buffer so that we can read the indirect data.
@ -2158,16 +2036,8 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any())
{
if (commandGraphEnabled())
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
currentIndirectBuf->onRead(this, framebuffer, VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
}
else
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
}
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
// We have instanced vertex attributes that need to be emulated for Vulkan.
// invalidate any cache and map the buffer so that we can read the indirect data.
@ -2234,7 +2104,6 @@ angle::Result ContextVk::clearWithRenderPassOp(
// Validate cache variable is in sync.
ASSERT(mDrawFramebuffer == vk::GetImpl(mState.getDrawFramebuffer()));
ASSERT(!commandGraphEnabled());
// Start a new render pass if:
//
// - no render pass has started,
@ -2341,20 +2210,12 @@ angle::Result ContextVk::insertEventMarker(GLsizei length, const char *marker)
if (!mRenderer->enableDebugUtils())
return angle::Result::Continue;
if (commandGraphEnabled())
{
std::string markerStr(marker, length <= 0 ? strlen(marker) : length);
mCommandGraph.insertDebugMarker(GL_DEBUG_SOURCE_APPLICATION, std::move(marker));
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(GL_DEBUG_SOURCE_APPLICATION, marker, &label);
primary->insertDebugUtilsLabelEXT(label);
}
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(GL_DEBUG_SOURCE_APPLICATION, marker, &label);
primary->insertDebugUtilsLabelEXT(label);
return angle::Result::Continue;
}
@ -2364,20 +2225,12 @@ angle::Result ContextVk::pushGroupMarker(GLsizei length, const char *marker)
if (!mRenderer->enableDebugUtils())
return angle::Result::Continue;
if (commandGraphEnabled())
{
std::string markerStr(marker, length <= 0 ? strlen(marker) : length);
mCommandGraph.pushDebugMarker(GL_DEBUG_SOURCE_APPLICATION, std::move(marker));
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(GL_DEBUG_SOURCE_APPLICATION, marker, &label);
primary->beginDebugUtilsLabelEXT(label);
}
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(GL_DEBUG_SOURCE_APPLICATION, marker, &label);
primary->beginDebugUtilsLabelEXT(label);
return angle::Result::Continue;
}
@ -2387,16 +2240,9 @@ angle::Result ContextVk::popGroupMarker()
if (!mRenderer->enableDebugUtils())
return angle::Result::Continue;
if (commandGraphEnabled())
{
mCommandGraph.popDebugMarker();
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
primary->endDebugUtilsLabelEXT();
}
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
primary->endDebugUtilsLabelEXT();
return angle::Result::Continue;
}
@ -2409,19 +2255,12 @@ angle::Result ContextVk::pushDebugGroup(const gl::Context *context,
if (!mRenderer->enableDebugUtils())
return angle::Result::Continue;
if (commandGraphEnabled())
{
mCommandGraph.insertDebugMarker(source, std::string(message));
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(source, message.c_str(), &label);
primary->insertDebugUtilsLabelEXT(label);
}
VkDebugUtilsLabelEXT label;
vk::MakeDebugUtilsLabel(source, message.c_str(), &label);
primary->insertDebugUtilsLabelEXT(label);
return angle::Result::Continue;
}
@ -2431,16 +2270,9 @@ angle::Result ContextVk::popDebugGroup(const gl::Context *context)
if (!mRenderer->enableDebugUtils())
return angle::Result::Continue;
if (commandGraphEnabled())
{
mCommandGraph.popDebugMarker();
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
primary->endDebugUtilsLabelEXT();
}
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
primary->endDebugUtilsLabelEXT();
return angle::Result::Continue;
}
@ -2566,24 +2398,11 @@ angle::Result ContextVk::updateScissor(const gl::State &glState)
// a render pass, the scissor is disabled and a draw call is issued to affect the whole
// framebuffer.
gl::Rectangle scissoredRenderArea = framebufferVk->getScissoredRenderArea(this);
if (commandGraphEnabled())
if (!mRenderPassCommands.empty())
{
vk::FramebufferHelper *framebuffer = framebufferVk->getFramebuffer();
framebuffer->updateCurrentAccessNodes();
if (framebuffer->hasStartedRenderPass() &&
!framebuffer->getRenderPassRenderArea().encloses(scissoredRenderArea))
if (!mRenderPassCommands.getRenderArea().encloses(scissoredRenderArea))
{
framebuffer->finishCurrentCommands(this);
}
}
else
{
if (!mRenderPassCommands.empty())
{
if (!mRenderPassCommands.getRenderArea().encloses(scissoredRenderArea))
{
ANGLE_TRY(endRenderPass());
}
ANGLE_TRY(endRenderPass());
}
}
@ -2775,9 +2594,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
// FramebufferVk::syncState signals that we should start a new command buffer.
// But changing the binding can skip FramebufferVk::syncState if the Framebuffer
// has no dirty bits. Thus we need to explicitly clear the current command
// buffer to ensure we start a new one. Note that we need a new command buffer
// because a command graph node can only support one RenderPass configuration at
// a time.
// buffer to ensure we start a new one. Note that we always start a new command
// buffer because we currently can only support one open RenderPass at a time.
onRenderPassFinished();
gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
@ -2932,7 +2750,6 @@ GLint64 ContextVk::getTimestamp()
angle::Result ContextVk::onMakeCurrent(const gl::Context *context)
{
mRenderer->reloadVolkIfNeeded();
ASSERT(mCommandGraph.empty());
// Flip viewports if FeaturesVk::flipViewportY is enabled and the user did not request that
// the surface is flipped.
@ -3226,15 +3043,8 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi
gl::Buffer *glBuffer = getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
vk::BufferHelper &buffer = vk::GetImpl(glBuffer)->getBuffer();
if (commandGraphEnabled())
{
buffer.onRead(this, &mDispatcher, VK_ACCESS_INDIRECT_COMMAND_READ_BIT);
}
else
{
mOutsideRenderPassCommands.bufferRead(&mResourceUseList,
VK_ACCESS_INDIRECT_COMMAND_READ_BIT, &buffer);
}
mOutsideRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
&buffer);
commandBuffer->dispatchIndirect(buffer.getBuffer(), indirect);
@ -3256,12 +3066,7 @@ angle::Result ContextVk::memoryBarrierByRegion(const gl::Context *context, GLbit
angle::Result ContextVk::memoryBarrierImpl(GLbitfield barriers, VkPipelineStageFlags stageMask)
{
// TOOD(jmadill): Clean up the comments with the refactor. http://anglebug.com/4029
// Note: most of the barriers specified here don't require us to issue a memory barrier, as
// the relevant resources already insert the appropriate barriers. They do however require
// the resource writing nodes to finish so future buffer barriers are placed correctly, as
// well as resource dependencies not creating a graph loop. This is done by inserting a
// command graph barrier that does nothing!
// Note: many of the barriers specified here are already covered automatically.
//
// The barriers that are necessary all have SHADER_WRITE as src access and the dst access is
// determined by the given bitfield. Currently, all image-related barriers that require the
@ -3283,22 +3088,15 @@ angle::Result ContextVk::memoryBarrierImpl(GLbitfield barriers, VkPipelineStageF
dstAccess |= VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT;
}
if (commandGraphEnabled())
{
mCommandGraph.memoryBarrier(srcAccess, dstAccess, stageMask);
}
else
{
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(getOutsideRenderPassCommandBuffer(&commandBuffer));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(getOutsideRenderPassCommandBuffer(&commandBuffer));
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = srcAccess;
memoryBarrier.dstAccessMask = dstAccess;
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = srcAccess;
memoryBarrier.dstAccessMask = dstAccess;
commandBuffer->memoryBarrier(stageMask, stageMask, &memoryBarrier);
}
commandBuffer->memoryBarrier(stageMask, stageMask, &memoryBarrier);
return angle::Result::Continue;
}
@ -3652,23 +3450,7 @@ angle::Result ContextVk::updateActiveImages(const gl::Context *context,
VkImageAspectFlags aspectFlags = image->getAspectFlags();
if (commandGraphEnabled())
{
// Ensure the image is in the correct layout
if (image->isLayoutChangeNecessary(imageLayout))
{
vk::CommandBuffer *layoutChange;
ANGLE_TRY(image->recordCommands(this, &layoutChange));
image->changeLayout(aspectFlags, imageLayout, layoutChange);
}
image->addWriteDependency(this, recorder);
}
else
{
commandBufferHelper->imageWrite(&mResourceUseList, aspectFlags, imageLayout, image);
}
commandBufferHelper->imageWrite(&mResourceUseList, aspectFlags, imageLayout, image);
}
return angle::Result::Continue;
@ -3687,15 +3469,8 @@ bool ContextVk::shouldFlush()
bool ContextVk::hasRecordedCommands()
{
if (commandGraphEnabled())
{
return !mCommandGraph.empty();
}
else
{
return !mOutsideRenderPassCommands.empty() || !mRenderPassCommands.empty() ||
!mPrimaryCommands.empty();
}
return !mOutsideRenderPassCommands.empty() || !mRenderPassCommands.empty() ||
!mPrimaryCommands.empty();
}
angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
@ -3708,66 +3483,44 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
ANGLE_TRACE_EVENT0("gpu.angle", "ContextVk::flush");
if (commandGraphEnabled())
mOutsideRenderPassCommands.flushToPrimary(this, &mPrimaryCommands);
ANGLE_TRY(endRenderPass());
if (mIsAnyHostVisibleBufferWritten)
{
vk::DeviceScoped<vk::PrimaryCommandBuffer> primaryCommands(getDevice());
ANGLE_TRY(
mCommandQueue.allocatePrimaryCommandBuffer(this, mCommandPool, &primaryCommands.get()));
// Make sure all writes to host-visible buffers are flushed. We have no way of knowing
// whether any buffer will be mapped for readback in the future, and we can't afford to
// flush and wait on a one-pipeline-barrier command buffer on every map().
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
if (!mCommandGraph.empty())
{
ANGLE_TRY(flushCommandGraph(&primaryCommands.get()));
}
waitForSwapchainImageIfNecessary();
VkSubmitInfo submitInfo = {};
InitializeSubmitInfo(&submitInfo, primaryCommands.get(), mWaitSemaphores,
&mWaitSemaphoreStageMasks, signalSemaphore);
ANGLE_TRY(submitFrame(submitInfo, primaryCommands.release()));
mPrimaryCommands.memoryBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_HOST_BIT, &memoryBarrier);
mIsAnyHostVisibleBufferWritten = false;
}
else
{
mOutsideRenderPassCommands.flushToPrimary(this, &mPrimaryCommands);
ANGLE_TRY(endRenderPass());
if (mIsAnyHostVisibleBufferWritten)
{
// Make sure all writes to host-visible buffers are flushed. We have no way of knowing
// whether any buffer will be mapped for readback in the future, and we can't afford to
// flush and wait on a one-pipeline-barrier command buffer on every map().
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
memoryBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
ANGLE_VK_TRY(this, mPrimaryCommands.end());
mPrimaryCommands.memoryBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_HOST_BIT, &memoryBarrier);
mIsAnyHostVisibleBufferWritten = false;
}
// Free secondary command pool allocations and restart command buffers with the new page.
mPoolAllocator.pop();
mPoolAllocator.push();
mOutsideRenderPassCommands.reset();
mRenderPassCommands.reset();
ANGLE_VK_TRY(this, mPrimaryCommands.end());
Serial serial = getCurrentQueueSerial();
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial);
// Free secondary command pool allocations and restart command buffers with the new page.
mPoolAllocator.pop();
mPoolAllocator.push();
mOutsideRenderPassCommands.reset();
mRenderPassCommands.reset();
waitForSwapchainImageIfNecessary();
Serial serial = getCurrentQueueSerial();
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial);
VkSubmitInfo submitInfo = {};
InitializeSubmitInfo(&submitInfo, mPrimaryCommands, mWaitSemaphores, &mWaitSemaphoreStageMasks,
signalSemaphore);
waitForSwapchainImageIfNecessary();
ANGLE_TRY(submitFrame(submitInfo, std::move(mPrimaryCommands)));
VkSubmitInfo submitInfo = {};
InitializeSubmitInfo(&submitInfo, mPrimaryCommands, mWaitSemaphores,
&mWaitSemaphoreStageMasks, signalSemaphore);
ANGLE_TRY(submitFrame(submitInfo, std::move(mPrimaryCommands)));
ANGLE_TRY(startPrimaryCommandBuffer());
}
ANGLE_TRY(startPrimaryCommandBuffer());
mWaitSemaphores.clear();
@ -3877,9 +3630,8 @@ angle::Result ContextVk::getTimestamp(uint64_t *timestampOut)
// > This will return the GL time after all previous commands have reached the GL server but
// have not yet necessarily executed.
//
// The previous commands are stored in the command graph at the moment and are not yet
// flushed. The wording allows us to make a submission to get the timestamp without
// performing a flush.
// The previous commands may be deferred at the moment and not yet flushed. The wording allows
// us to make a submission to get the timestamp without flushing.
//
// Second:
//
@ -4048,8 +3800,6 @@ bool ContextVk::shouldUseOldRewriteStructSamplers() const
angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer)
{
ASSERT(!commandGraphEnabled());
ANGLE_TRY(endRenderPass());
if (!buffer->canAccumulateRead(this, readAccessType))
@ -4064,8 +3814,6 @@ angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, vk::BufferHe
angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer)
{
ASSERT(!commandGraphEnabled());
ANGLE_TRY(endRenderPass());
if (!buffer->canAccumulateWrite(this, writeAccessType))
@ -4082,8 +3830,6 @@ angle::Result ContextVk::onImageRead(VkImageAspectFlags aspectFlags,
vk::ImageLayout imageLayout,
vk::ImageHelper *image)
{
ASSERT(!commandGraphEnabled());
ANGLE_TRY(endRenderPass());
if (image->isLayoutChangeNecessary(imageLayout))
@ -4100,8 +3846,6 @@ angle::Result ContextVk::onImageWrite(VkImageAspectFlags aspectFlags,
vk::ImageLayout imageLayout,
vk::ImageHelper *image)
{
ASSERT(!commandGraphEnabled());
ANGLE_TRY(endRenderPass());
// Barriers are always required for image writes.
@ -4123,8 +3867,6 @@ angle::Result ContextVk::beginRenderPass(const vk::Framebuffer &framebuffer,
const std::vector<VkClearValue> &clearValues,
vk::CommandBuffer **commandBufferOut)
{
ASSERT(!commandGraphEnabled());
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(getPrimaryCommandBuffer(&primary));
mRenderPassCommands.beginRenderPass(framebuffer, renderArea, renderPassDesc,
@ -4134,8 +3876,6 @@ angle::Result ContextVk::beginRenderPass(const vk::Framebuffer &framebuffer,
angle::Result ContextVk::endRenderPass()
{
ASSERT(!commandGraphEnabled());
onRenderPassFinished();
return mRenderPassCommands.flushToPrimary(this, &mPrimaryCommands);
}

Просмотреть файл

@ -425,7 +425,6 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
egl::ContextPriority getPriority() const { return mContextPriority; }
ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
ANGLE_INLINE bool commandGraphEnabled() const { return getFeatures().commandGraph.enabled; }
ANGLE_INLINE void invalidateVertexAndIndexBuffers()
{
@ -537,13 +536,6 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
angle::Result getNextSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut);
vk::Shared<vk::Fence> getLastSubmittedFence() const;
// This should only be called from ResourceVk.
vk::CommandGraph *getCommandGraph()
{
ASSERT(commandGraphEnabled());
return &mCommandGraph;
}
vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
UtilsVk &getUtils() { return mUtils; }
@ -996,9 +988,6 @@ class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassO
// Pool allocator used for command graph but may be expanded to other allocations
angle::PoolAllocator mPoolAllocator;
// See CommandGraph.h for a desription of the Command Graph.
vk::CommandGraph mCommandGraph;
// When the command graph is disabled we record commands completely linearly. We have plans to
// reorder independent draws so that we can create fewer RenderPasses in some scenarios.
OutsideRenderPassCommandBuffer mOutsideRenderPassCommands;

Просмотреть файл

@ -31,10 +31,6 @@ namespace rx
namespace
{
// The value to assign an alpha channel that's emulated. The type is unsigned int, though it will
// automatically convert to the actual data type.
constexpr unsigned int kEmulatedAlphaValue = 1;
constexpr size_t kMinReadPixelsBufferSize = 128000;
// Alignment value to accommodate the largest known, for now, uncompressed Vulkan format
@ -69,7 +65,7 @@ bool HasDstBlitFeature(RendererVk *renderer, RenderTargetVk *dstRenderTarget)
// Returns false if destination has any channel the source doesn't. This means that channel was
// emulated and using the Vulkan blit command would overwrite that emulated channel.
bool areSrcAndDstColorChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
bool AreSrcAndDstColorChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
RenderTargetVk *dstRenderTarget)
{
const angle::Format &srcFormat = srcRenderTarget->getImageFormat().intendedFormat();
@ -87,7 +83,7 @@ bool areSrcAndDstColorChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
(dstFormat.alphaBits > 0 || srcFormat.alphaBits == 0);
}
bool areSrcAndDstDepthStencilChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
bool AreSrcAndDstDepthStencilChannelsBlitCompatible(RenderTargetVk *srcRenderTarget,
RenderTargetVk *dstRenderTarget)
{
const angle::Format &srcFormat = srcRenderTarget->getImageFormat().intendedFormat();
@ -96,25 +92,6 @@ bool areSrcAndDstDepthStencilChannelsBlitCompatible(RenderTargetVk *srcRenderTar
return (dstFormat.depthBits > 0 || srcFormat.depthBits == 0) &&
(dstFormat.stencilBits > 0 || srcFormat.stencilBits == 0);
}
void SetEmulatedAlphaValue(const vk::Format &format, VkClearColorValue *value)
{
if (format.vkFormatIsInt)
{
if (format.vkFormatIsUnsigned)
{
value->uint32[3] = kEmulatedAlphaValue;
}
else
{
value->int32[3] = kEmulatedAlphaValue;
}
}
else
{
value->float32[3] = kEmulatedAlphaValue;
}
}
} // anonymous namespace
// static
@ -181,19 +158,9 @@ angle::Result FramebufferVk::invalidate(const gl::Context *context,
ASSERT(mFramebuffer->valid());
mFramebuffer->onResourceAccess(&contextVk->getResourceUseList());
if (contextVk->commandGraphEnabled())
if (contextVk->hasStartedRenderPass())
{
if (mFramebuffer->hasStartedRenderPass())
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
else
{
if (contextVk->hasStartedRenderPass())
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
@ -212,21 +179,10 @@ angle::Result FramebufferVk::invalidateSub(const gl::Context *context,
if (mFramebuffer != nullptr)
{
ASSERT(mFramebuffer->valid());
if (contextVk->commandGraphEnabled())
if (contextVk->hasStartedRenderPass() &&
area.encloses(contextVk->getStartedRenderPassCommands().getRenderArea()))
{
if (mFramebuffer->hasStartedRenderPass() &&
area.encloses(mFramebuffer->getRenderPassRenderArea()))
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
else
{
if (contextVk->hasStartedRenderPass() &&
area.encloses(contextVk->getStartedRenderPassCommands().getRenderArea()))
{
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
ANGLE_TRY(invalidateImpl(contextVk, count, attachments));
}
}
@ -333,18 +289,9 @@ angle::Result FramebufferVk::clearImpl(const gl::Context *context,
clearBuffersWithRenderPassLoadOp = clearColorBuffers;
}
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(clearWithRenderPassOp(
contextVk, scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
}
else
{
ANGLE_TRY(contextVk->clearWithRenderPassOp(
scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
}
ANGLE_TRY(contextVk->clearWithRenderPassOp(
scissoredRenderArea, clearBuffersWithRenderPassLoadOp, clearDepth,
clearStencilWithRenderPassLoadOp, clearColorValue, modifiedDepthStencilValue));
// Fallback to other methods for whatever isn't cleared here.
clearDepth = false;
@ -560,7 +507,7 @@ angle::Result FramebufferVk::blitWithCommand(ContextVk *contextVk,
ASSERT(colorBlit != (depthBlit || stencilBlit));
vk::ImageHelper *srcImage = &readRenderTarget->getImage();
vk::ImageHelper *dstImage = drawRenderTarget->getImageForWrite(contextVk, mFramebuffer);
vk::ImageHelper *dstImage = drawRenderTarget->getImageForWrite(contextVk);
VkImageAspectFlags imageAspectMask = srcImage->getAspectFlags();
VkImageAspectFlags blitAspectMask = imageAspectMask;
@ -576,28 +523,9 @@ angle::Result FramebufferVk::blitWithCommand(ContextVk *contextVk,
}
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(imageAspectMask, vk::ImageLayout::TransferSrc, srcLayoutChange);
}
ANGLE_TRY(mFramebuffer->recordCommands(contextVk, &commandBuffer));
srcImage->addReadDependency(contextVk, mFramebuffer);
// Requirement of the copyImageToBuffer, the dst image must be in
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL layout.
dstImage->changeLayout(imageAspectMask, vk::ImageLayout::TransferDst, commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageRead(imageAspectMask, vk::ImageLayout::TransferSrc, srcImage));
ANGLE_TRY(contextVk->onImageWrite(imageAspectMask, vk::ImageLayout::TransferDst, dstImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageRead(imageAspectMask, vk::ImageLayout::TransferSrc, srcImage));
ANGLE_TRY(contextVk->onImageWrite(imageAspectMask, vk::ImageLayout::TransferDst, dstImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkImageBlit blit = {};
blit.srcSubresource.aspectMask = blitAspectMask;
@ -802,7 +730,7 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
canBlitWithCommand && HasDstBlitFeature(renderer, drawRenderTarget);
areChannelsBlitCompatible =
areChannelsBlitCompatible &&
areSrcAndDstColorChannelsBlitCompatible(readRenderTarget, drawRenderTarget);
AreSrcAndDstColorChannelsBlitCompatible(readRenderTarget, drawRenderTarget);
}
if (canBlitWithCommand && areChannelsBlitCompatible)
@ -846,7 +774,7 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
HasSrcBlitFeature(renderer, readRenderTarget) &&
HasDstBlitFeature(renderer, drawRenderTarget);
bool areChannelsBlitCompatible =
areSrcAndDstDepthStencilChannelsBlitCompatible(readRenderTarget, drawRenderTarget);
AreSrcAndDstDepthStencilChannelsBlitCompatible(readRenderTarget, drawRenderTarget);
if (canBlitWithCommand && areChannelsBlitCompatible)
{
@ -918,26 +846,8 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
vk::ImageHelper *srcImage)
{
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
}
ANGLE_TRY(mFramebuffer->recordCommands(contextVk, &commandBuffer));
// Source's layout change should happen before rendering
srcImage->addReadDependency(contextVk, mFramebuffer);
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcImage));
}
ANGLE_TRY(
contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc, srcImage));
VkImageResolve resolveRegion = {};
resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -959,20 +869,9 @@ angle::Result FramebufferVk::resolveColorWithCommand(ContextVk *contextVk,
for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{
RenderTargetVk *drawRenderTarget = mRenderTargetCache.getColors()[colorIndexGL];
if (contextVk->commandGraphEnabled())
{
vk::ImageHelper *drawImage =
drawRenderTarget->getImageForWrite(contextVk, mFramebuffer);
drawImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst,
&drawRenderTarget->getImage()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
&drawRenderTarget->getImage()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
resolveRegion.dstSubresource.mipLevel = drawRenderTarget->getLevelIndex();
resolveRegion.dstSubresource.baseArrayLayer = drawRenderTarget->getLayerIndex();
@ -1067,15 +966,8 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
{
if (invalidateColorBuffers.test(colorIndexGL))
{
if (contextVk->commandGraphEnabled())
{
mFramebuffer->invalidateRenderPassColorAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassColorAttachment(
attachmentIndexVk);
}
contextVk->getStartedRenderPassCommands().invalidateRenderPassColorAttachment(
attachmentIndexVk);
}
++attachmentIndexVk;
}
@ -1085,28 +977,14 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
{
if (invalidateDepthBuffer)
{
if (contextVk->commandGraphEnabled())
{
mFramebuffer->invalidateRenderPassDepthAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassDepthAttachment(
attachmentIndexVk);
}
contextVk->getStartedRenderPassCommands().invalidateRenderPassDepthAttachment(
attachmentIndexVk);
}
if (invalidateStencilBuffer)
{
if (contextVk->commandGraphEnabled())
{
mFramebuffer->invalidateRenderPassStencilAttachment(attachmentIndexVk);
}
else
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassStencilAttachment(
attachmentIndexVk);
}
contextVk->getStartedRenderPassCommands().invalidateRenderPassStencilAttachment(
attachmentIndexVk);
}
}
@ -1123,14 +1001,7 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
// this pattern, this optimization may not be necessary if no application does this. It is
// expected that an application would invalidate() when it's done with the framebuffer, so the
// render pass would have closed either way.
if (contextVk->commandGraphEnabled())
{
mFramebuffer->finishCurrentCommands(contextVk);
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
ANGLE_TRY(contextVk->endRenderPass());
return angle::Result::Continue;
}
@ -1246,16 +1117,7 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
mActiveColorComponentMasksForClear[0].any(), mActiveColorComponentMasksForClear[1].any(),
mActiveColorComponentMasksForClear[2].any(), mActiveColorComponentMasksForClear[3].any());
if (contextVk->commandGraphEnabled())
{
// Will freeze the current set of dependencies on this FBO. The next time we render we will
// create a new entry in the command graph.
mFramebuffer->finishCurrentCommands(contextVk);
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
ANGLE_TRY(contextVk->endRenderPass());
// Notify the ContextVk to update the pipeline desc.
updateRenderPassDesc();
@ -1384,74 +1246,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, vk::Framebuffe
return angle::Result::Continue;
}
angle::Result FramebufferVk::clearWithRenderPassOp(
ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue)
{
ASSERT(contextVk->commandGraphEnabled());
// Start a new render pass if:
//
// - no render pass has started,
// - there is a render pass started but it contains commands; we cannot modify its ops, so new
// render pass is needed,
// - the current render area doesn't match the clear area. We need the render area to be
// exactly as specified by the scissor for the loadOp to clear only that area. See
// ContextVk::updateScissor for more information.
if (mFramebuffer == nullptr || !mFramebuffer->valid() ||
!mFramebuffer->renderPassStartedButEmpty() ||
mFramebuffer->getRenderPassRenderArea() != clearArea)
{
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(startNewRenderPass(contextVk, clearArea, &commandBuffer));
}
size_t attachmentIndexVk = 0;
// Go through clearColorBuffers and set the appropriate loadOp and clear values.
for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{
if (clearColorBuffers.test(colorIndexGL))
{
RenderTargetVk *renderTarget = getColorDrawRenderTarget(colorIndexGL);
// If the render target doesn't have alpha, but its emulated format has it, clear the
// alpha to 1.
VkClearColorValue value = clearColorValue;
if (mEmulatedAlphaAttachmentMask[colorIndexGL])
{
SetEmulatedAlphaValue(renderTarget->getImageFormat(), &value);
}
mFramebuffer->clearRenderPassColorAttachment(attachmentIndexVk, value);
}
++attachmentIndexVk;
}
// Set the appropriate loadOp and clear values for depth and stencil.
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
if (clearDepth)
{
mFramebuffer->clearRenderPassDepthAttachment(attachmentIndexVk,
clearDepthStencilValue.depth);
}
if (clearStencil)
{
mFramebuffer->clearRenderPassStencilAttachment(attachmentIndexVk,
clearDepthStencilValue.stencil);
}
}
return angle::Result::Continue;
}
angle::Result FramebufferVk::clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
@ -1519,15 +1313,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
vk::AttachmentOpsArray renderPassAttachmentOps;
std::vector<VkClearValue> attachmentClearValues;
vk::CommandBuffer *writeCommands = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mFramebuffer->recordCommands(contextVk, &writeCommands));
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
ANGLE_TRY(contextVk->endRenderPass());
// Initialize RenderPass info.
const auto &colorRenderTargets = mRenderTargetCache.getColors();
@ -1536,7 +1322,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget);
ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk, mFramebuffer, writeCommands));
ANGLE_TRY(colorRenderTarget->onColorDraw(contextVk));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
@ -1547,8 +1333,7 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
RenderTargetVk *depthStencilRenderTarget = mRenderTargetCache.getDepthStencil();
if (depthStencilRenderTarget)
{
ANGLE_TRY(
depthStencilRenderTarget->onDepthStencilDraw(contextVk, mFramebuffer, writeCommands));
ANGLE_TRY(depthStencilRenderTarget->onDepthStencilDraw(contextVk));
renderPassAttachmentOps.initWithLoadStore(attachmentClearValues.size(),
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
@ -1556,18 +1341,9 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
attachmentClearValues.emplace_back(kUninitializedClearValue);
}
if (contextVk->commandGraphEnabled())
{
return mFramebuffer->beginRenderPass(contextVk, *framebuffer, renderArea, mRenderPassDesc,
renderPassAttachmentOps, attachmentClearValues,
commandBufferOut);
}
else
{
return contextVk->beginRenderPass(*framebuffer, renderArea, mRenderPassDesc,
renderPassAttachmentOps, attachmentClearValues,
commandBufferOut);
}
return contextVk->beginRenderPass(*framebuffer, renderArea, mRenderPassDesc,
renderPassAttachmentOps, attachmentClearValues,
commandBufferOut);
}
void FramebufferVk::updateActiveColorMasks(size_t colorIndexGL, bool r, bool g, bool b, bool a)

Просмотреть файл

@ -109,16 +109,6 @@ class FramebufferVk : public FramebufferImpl
RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const;
RenderTargetVk *getColorReadRenderTarget() const;
// This will clear the current write operation if it is complete.
bool appendToStartedRenderPass(vk::ResourceUseList *resourceUseList,
const gl::Rectangle &renderArea,
vk::CommandBuffer **commandBufferOut)
{
ASSERT(mFramebuffer);
return mFramebuffer->appendToStartedRenderPass(resourceUseList, renderArea,
commandBufferOut);
}
vk::FramebufferHelper *getFramebuffer() { return mFramebuffer; }
angle::Result startNewRenderPass(ContextVk *context,
@ -162,13 +152,6 @@ class FramebufferVk : public FramebufferImpl
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithRenderPassOp(ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,
bool clearDepth,
bool clearStencil,
const VkClearColorValue &clearColorValue,
const VkClearDepthStencilValue &clearDepthStencilValue);
angle::Result clearWithDraw(ContextVk *contextVk,
const gl::Rectangle &clearArea,
gl::DrawBufferMask clearColorBuffers,

Просмотреть файл

@ -121,21 +121,10 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
// Copy font data from staging buffer.
vk::CommandBuffer *fontDataUpload;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mFontImage.recordCommands(contextVk, &fontDataUpload));
fontDataBuffer.get().onRead(contextVk, &mFontImage, VK_ACCESS_TRANSFER_READ_BIT);
mFontImage.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
fontDataUpload);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &fontDataBuffer.get()));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
&mFontImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&fontDataUpload));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &fontDataBuffer.get()));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
&mFontImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&fontDataUpload));
VkBufferImageCopy copy = {};
copy.bufferRowLength = gl::overlay::kFontImageWidth;
@ -150,12 +139,6 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
mFontImage.getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copy);
if (contextVk->commandGraphEnabled())
{
mFontImage.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ComputeShaderReadOnly,
fontDataUpload);
}
return angle::Result::Continue;
}

Просмотреть файл

@ -1389,32 +1389,16 @@ void ProgramVk::updateBuffersDescriptorSet(ContextVk *contextVk,
BufferVk *bufferVk = vk::GetImpl(bufferBinding.get());
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
if (contextVk->getFeatures().commandGraph.enabled)
if (isStorageBuffer)
{
if (isStorageBuffer)
{
// We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
bufferHelper.onWrite(contextVk, recorder, accessFlags);
}
else
{
bufferHelper.onRead(contextVk, recorder, VK_ACCESS_UNIFORM_READ_BIT);
}
// We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
commandBufferHelper->bufferWrite(resourceUseList, accessFlags, &bufferHelper);
}
else
{
if (isStorageBuffer)
{
// We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
commandBufferHelper->bufferWrite(resourceUseList, accessFlags, &bufferHelper);
}
else
{
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
&bufferHelper);
}
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
&bufferHelper);
}
++writeCount;
@ -1475,17 +1459,8 @@ void ProgramVk::updateAtomicCounterBuffersDescriptorSet(ContextVk *contextVk,
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
// We set SHADER_READ_BIT to be conservative.
if (contextVk->commandGraphEnabled())
{
bufferHelper.onWrite(contextVk, recorder,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
commandBufferHelper->bufferWrite(resourceUseList,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
&bufferHelper);
}
commandBufferHelper->bufferWrite(
resourceUseList, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, &bufferHelper);
writtenBindings.set(binding);
}
@ -1614,16 +1589,8 @@ angle::Result ProgramVk::updateShaderResourcesDescriptorSet(
angle::Result ProgramVk::updateTransformFeedbackDescriptorSet(ContextVk *contextVk,
vk::FramebufferHelper *framebuffer)
{
const gl::State &glState = contextVk->getState();
ASSERT(hasTransformFeedbackOutput());
if (contextVk->commandGraphEnabled())
{
TransformFeedbackVk *transformFeedbackVk =
vk::GetImpl(glState.getCurrentTransformFeedback());
transformFeedbackVk->addFramebufferDependency(contextVk, mState, framebuffer);
}
ANGLE_TRY(allocateDescriptorSet(contextVk, kUniformsAndXfbDescriptorSetIndex));
updateDefaultUniformsDescriptorSet(contextVk);

Просмотреть файл

@ -49,14 +49,7 @@ angle::Result QueryVk::begin(const gl::Context *context)
if (getType() == gl::QueryType::TransformFeedbackPrimitivesWritten)
{
mTransformFeedbackPrimitivesDrawn = 0;
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->beginTransformFeedbackEmulatedQuery();
}
else
{
// We could consider using VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT.
}
// We could consider using VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT.
return angle::Result::Continue;
}
@ -101,14 +94,7 @@ angle::Result QueryVk::end(const gl::Context *context)
mCachedResult += transformFeedback->getPrimitivesDrawn();
}
mCachedResultValid = true;
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->endTransformFeedbackEmulatedQuery();
}
else
{
// We could consider using VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT.
}
// We could consider using VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT.
}
else if (getType() == gl::QueryType::TimeElapsed)
{

Просмотреть файл

@ -68,55 +68,25 @@ vk::AttachmentSerial RenderTargetVk::getAssignSerial(ContextVk *contextVk)
return attachmentSerial;
}
angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer)
angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk)
{
ASSERT(!mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
if (contextVk->commandGraphEnabled())
{
ASSERT(commandBuffer->valid());
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
commandBuffer);
// Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk);
}
else
{
contextVk->onRenderPassImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ColorAttachment, mImage);
}
contextVk->onRenderPassImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
mImage);
onImageViewAccess(contextVk);
return angle::Result::Continue;
}
angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer)
angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk)
{
ASSERT(mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
const angle::Format &format = mImage->getFormat().actualImageFormat();
VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
if (contextVk->commandGraphEnabled())
{
ASSERT(commandBuffer->valid());
mImage->changeLayout(aspectFlags, vk::ImageLayout::DepthStencilAttachment, commandBuffer);
// Set up dependencies between the RT resource and the Framebuffer.
mImage->addWriteDependency(contextVk, framebufferVk);
}
else
{
contextVk->onRenderPassImageWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment,
mImage);
}
contextVk->onRenderPassImageWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment, mImage);
onImageViewAccess(contextVk);
return angle::Result::Continue;
@ -161,42 +131,9 @@ void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageViewH
mImageViews = imageViews;
}
vk::ImageHelper *RenderTargetVk::getImageForRead(ContextVk *contextVk,
vk::CommandGraphResource *readingResource,
vk::ImageLayout layout,
vk::CommandBuffer *commandBuffer)
vk::ImageHelper *RenderTargetVk::getImageForWrite(ContextVk *contextVk) const
{
ASSERT(mImage && mImage->valid());
// TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679
//
// A better alternative would be:
//
// if (mImage->isLayoutChangeNecessary(layout)
// {
// vk::CommandBuffer *srcLayoutChange;
// ANGLE_TRY(mImage->recordCommands(contextVk, &srcLayoutChange));
// mImage->changeLayout(mImage->getAspectFlags(), layout, srcLayoutChange);
// }
// mImage->addReadDependency(readingResource);
//
// I.e. the transition should happen on a node generated from mImage itself.
// However, this needs context to be available here, or all call sites changed
// to perform the layout transition and set the dependency.
mImage->addWriteDependency(contextVk, readingResource);
mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer);
onImageViewAccess(contextVk);
return mImage;
}
vk::ImageHelper *RenderTargetVk::getImageForWrite(ContextVk *contextVk,
vk::CommandGraphResource *writingResource) const
{
ASSERT(mImage && mImage->valid());
if (contextVk->commandGraphEnabled())
{
mImage->addWriteDependency(contextVk, writingResource);
}
onImageViewAccess(contextVk);
return mImage;
}
@ -208,14 +145,7 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
return angle::Result::Continue;
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
return mImage->flushStagedUpdates(contextVk, mLevelIndex, mLevelIndex + 1, mLayerIndex,
mLayerIndex + 1, commandBuffer);
}

Просмотреть файл

@ -52,23 +52,14 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
vk::AttachmentSerial getAssignSerial(ContextVk *contextVk);
// Note: RenderTargets should be called in order, with the depth/stencil onRender last.
angle::Result onColorDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer);
angle::Result onDepthStencilDraw(ContextVk *contextVk,
vk::FramebufferHelper *framebufferVk,
vk::CommandBuffer *commandBuffer);
angle::Result onColorDraw(ContextVk *contextVk);
angle::Result onDepthStencilDraw(ContextVk *contextVk);
vk::ImageHelper &getImage();
const vk::ImageHelper &getImage() const;
// getImageForRead will also transition the resource to the given layout.
vk::ImageHelper *getImageForRead(ContextVk *contextVk,
vk::CommandGraphResource *readingResource,
vk::ImageLayout layout,
vk::CommandBuffer *commandBuffer);
vk::ImageHelper *getImageForWrite(ContextVk *contextVk,
vk::CommandGraphResource *writingResource) const;
vk::ImageHelper *getImageForWrite(ContextVk *contextVk) const;
// For cube maps we use single-level single-layer 2D array views.
angle::Result getImageView(ContextVk *contextVk, const vk::ImageView **imageViewOut) const;

Просмотреть файл

@ -126,14 +126,7 @@ angle::Result RenderbufferVk::setStorageEGLImageTarget(const gl::Context *contex
if (mImage->isQueueChangeNeccesary(rendererQueueFamilyIndex))
{
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
mImage->changeLayoutAndQueue(aspect, vk::ImageLayout::ColorAttachment,
rendererQueueFamilyIndex, commandBuffer);
}

Просмотреть файл

@ -1613,8 +1613,6 @@ void RendererVk::initFeatures(DisplayVk *displayVk, const ExtensionNameList &dev
ANGLE_FEATURE_CONDITION((&mFeatures), disableFlippingBlitWithCommand,
IsAndroid() && isQualcomm);
ANGLE_FEATURE_CONDITION((&mFeatures), commandGraph, false);
// Allocation sanitization disabled by default because of a heaveyweight implementation
// that can cause OOM and timeouts.
ANGLE_FEATURE_CONDITION((&mFeatures), allocateNonZeroMemory, false);

Просмотреть файл

@ -87,14 +87,7 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
if (!bufferBarriers.empty() || !textureBarriers.empty())
{
// Create one global memory barrier to cover all barriers.
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->syncExternalMemory();
}
else
{
ANGLE_TRY(contextVk->syncExternalMemory());
}
ANGLE_TRY(contextVk->syncExternalMemory());
}
uint32_t rendererQueueFamilyIndex = contextVk->getRenderer()->getQueueFamilyIndex();
@ -108,18 +101,7 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
// If there were GL commands using this buffer prior to this call, that's a
// synchronization error on behalf of the program.
ASSERT(!bufferHelper.hasRecordedCommands());
ANGLE_TRY(bufferHelper.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Queue ownership transfer.
bufferHelper.changeQueue(rendererQueueFamilyIndex, commandBuffer);
@ -141,17 +123,8 @@ angle::Result SemaphoreVk::wait(gl::Context *context,
image.onExternalLayoutChange(layout);
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
// If there were GL commands using this image prior to this call, that's a
// synchronization error on behalf of the program.
ASSERT(!image.hasRecordedCommands());
ANGLE_TRY(image.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Queue ownership transfer.
image.changeLayoutAndQueue(image.getAspectFlags(), layout, rendererQueueFamilyIndex,
commandBuffer);
@ -177,14 +150,7 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(bufferHelper.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Queue ownership transfer.
bufferHelper.changeQueue(VK_QUEUE_FAMILY_EXTERNAL, commandBuffer);
@ -210,14 +176,7 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
}
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(image.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Queue ownership transfer and layout transition.
image.changeLayoutAndQueue(image.getAspectFlags(), layout, VK_QUEUE_FAMILY_EXTERNAL,
@ -228,14 +187,7 @@ angle::Result SemaphoreVk::signal(gl::Context *context,
if (!bufferBarriers.empty() || !textureBarriers.empty())
{
// Create one global memory barrier to cover all barriers.
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->syncExternalMemory();
}
else
{
ANGLE_TRY(contextVk->syncExternalMemory());
}
ANGLE_TRY(contextVk->syncExternalMemory());
}
return contextVk->flushImpl(&mSemaphore);

Просмотреть файл

@ -1072,34 +1072,16 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
SwapchainImage &image = mSwapchainImages[mCurrentSwapchainImageIndex];
vk::CommandBuffer *commandBuffer = nullptr;
if (!contextVk->commandGraphEnabled())
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
if (mColorImageMS.valid())
{
// Transition the multisampled image to TRANSFER_SRC for resolve.
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mColorImageMS.recordCommands(contextVk, &commandBuffer));
mColorImageMS.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
commandBuffer);
image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Setup graph dependency between the swapchain image and the multisampled one.
image.image.addReadDependency(contextVk, &mColorImageMS);
ANGLE_TRY(image.image.recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferSrc, &mColorImageMS));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, &image.image));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
&mColorImageMS));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
&image.image));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkImageResolve resolveRegion = {};
resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -1116,10 +1098,6 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
ANGLE_TRY(updateAndDrawOverlay(contextVk, &image));
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(image.image.recordCommands(contextVk, &commandBuffer));
}
image.image.changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::Present, commandBuffer);
// Knowing that the kSwapHistorySize'th submission ago has finished, we can know that the
@ -1509,6 +1487,7 @@ angle::Result WindowSurfaceVk::updateAndDrawOverlay(ContextVk *contextVk,
image->imageViews.getLevelLayerDrawImageView(contextVk, image->image, 0, 0, &imageView));
ANGLE_TRY(overlayVk->onPresent(contextVk, &image->image, imageView));
// TODO(jmadill): Remove this. http://anglebug.com/4029
overlay->getRunningGraphWidget(gl::WidgetId::VulkanCommandGraphSize)->next();
return angle::Result::Continue;

Просмотреть файл

@ -52,17 +52,9 @@ angle::Result SyncHelper::initialize(ContextVk *contextVk)
mEvent = event.release();
if (contextVk->commandGraphEnabled())
{
CommandGraph *commandGraph = contextVk->getCommandGraph();
commandGraph->setFenceSync(mEvent);
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primary));
primary->setEvent(mEvent.getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
}
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primary));
primary->setEvent(mEvent.getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
contextVk->getResourceUseList().add(mUse);
return angle::Result::Continue;
@ -114,19 +106,10 @@ angle::Result SyncHelper::clientWait(Context *context,
angle::Result SyncHelper::serverWait(ContextVk *contextVk)
{
if (contextVk->commandGraphEnabled())
{
CommandGraph *commandGraph = contextVk->getCommandGraph();
commandGraph->waitFenceSync(mEvent);
}
else
{
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primary));
primary->waitEvents(1, mEvent.ptr(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0,
nullptr);
}
vk::PrimaryCommandBuffer *primary;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primary));
primary->waitEvents(1, mEvent.ptr(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0, nullptr);
contextVk->getResourceUseList().add(mUse);
return angle::Result::Continue;
}

Просмотреть файл

@ -573,21 +573,8 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
gl::Extents extents = {sourceArea.width, sourceArea.height, 1};
// Change source layout if necessary
if (contextVk->commandGraphEnabled())
{
if (srcImage->isLayoutChangeNecessary(vk::ImageLayout::TransferSrc))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(srcImage->recordCommands(contextVk, &srcLayoutChange));
srcImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcLayoutChange);
}
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc,
srcImage));
}
ANGLE_TRY(
contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferSrc, srcImage));
VkImageSubresourceLayers srcSubresource = {};
srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -602,23 +589,9 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
// Change the image layout before the transfer
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, mImage);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, mImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
mImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkImageSubresourceLayers destSubresource = srcSubresource;
destSubresource.mipLevel = level;
@ -646,23 +619,9 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
destFormat, kTransferStagingImageFlags, layerCount));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(stagingImage->recordCommands(contextVk, &commandBuffer));
// Change the image layout before the transfer
stagingImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Source's layout change should happen before the copy
srcImage->addReadDependency(contextVk, stagingImage.get());
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::TransferDst, stagingImage.get()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
stagingImage.get()));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkImageSubresourceLayers destSubresource = srcSubresource;
destSubresource.mipLevel = 0;
@ -863,14 +822,7 @@ angle::Result TextureVk::setEGLImageTarget(const gl::Context *context,
if (mImage->isQueueChangeNeccesary(rendererQueueFamilyIndex))
{
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
mImage->changeLayoutAndQueue(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::AllGraphicsShadersReadOnly,
rendererQueueFamilyIndex, commandBuffer);
@ -1079,23 +1031,10 @@ angle::Result TextureVk::copyBufferDataToImage(ContextVk *contextVk,
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
commandBuffer);
// Source's layout change should happen before the copy
// Also updates the serial of the srcBuffer
srcBuffer->addReadDependency(contextVk, mImage);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, srcBuffer));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
mImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, srcBuffer));
ANGLE_TRY(
contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst, mImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkBufferImageCopy region = {};
region.bufferOffset = offset;
@ -1155,7 +1094,7 @@ angle::Result TextureVk::generateMipmapsWithCPU(const gl::Context *context)
}
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
return mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0), mImage->getLevelCount(),
getNativeImageLayer(0), mImage->getLayerCount(),
commandBuffer);
@ -1199,15 +1138,8 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
if (mImage->hasStagedUpdates())
{
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
mImage->onResourceAccess(&contextVk->getResourceUseList());
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
mImage->onResourceAccess(&contextVk->getResourceUseList());
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
ANGLE_TRY(mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0),
mImage->getLevelCount(), getNativeImageLayer(0),
mImage->getLayerCount(), commandBuffer));
@ -1218,16 +1150,6 @@ angle::Result TextureVk::generateMipmap(const gl::Context *context)
ANGLE_TRY(copyAndStageImageSubresource(contextVk, baseLevelDesc, false,
getNativeImageLayer(0), 0, mImage->getBaseLevel()));
// Create a new node for the image and add a global memory barrier for the staging buffer.
// It's written to and staged to be read from when ensureImageInitialized() is called.
if (contextVk->commandGraphEnabled())
{
mImage->finishCurrentCommands(contextVk);
mImage->addGlobalMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
onStagingBufferChange();
// Release the origin image and recreate it with new mipmap counts.
releaseImage(contextVk);
@ -1339,15 +1261,7 @@ angle::Result TextureVk::changeLevels(ContextVk *contextVk,
if (mImage->valid() && mImage->hasStagedUpdates())
{
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
ANGLE_TRY(mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0),
mImage->getLevelCount(), getNativeImageLayer(0),
mImage->getLayerCount(), commandBuffer));
@ -1397,17 +1311,6 @@ angle::Result TextureVk::changeLevels(ContextVk *contextVk,
}
}
// This global barrier is no longer needed without the command graph as barriers are correctly
// inserted using the normal command APIs.
if (contextVk->commandGraphEnabled())
{
// Create a new node for the image and add a global memory barrier for the staging buffers.
// They are written to and staged to be read from when ensureImageInitialized() is called.
mImage->finishCurrentCommands(contextVk);
mImage->addGlobalMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
// Inform the front end that we've updated the staging buffer
onStagingBufferChange();
// Now that we've staged all the updates, release the current image so that it will be
@ -1498,14 +1401,7 @@ angle::Result TextureVk::ensureImageInitializedImpl(ContextVk *contextVk,
}
vk::CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
return mImage->flushStagedUpdates(contextVk, getNativeImageLevel(0), mImage->getLevelCount(),
getNativeImageLayer(0), mImage->getLayerCount(),
commandBuffer);

Просмотреть файл

@ -81,8 +81,8 @@ angle::Result TransformFeedbackVk::pause(const gl::Context *context)
if (contextVk->getFeatures().supportsTransformFeedbackExtension.enabled)
{
// We need to create new commandGraphNode to perform transform feedback pause/resume
// becasue vkCmdBegin/EndTransformFeedback can be placed once per commandGraphNode.
// We need to end the RenderPass to perform transform feedback pause/resume
// becasue vkCmdBegin/EndTransformFeedback can be placed once per RenderPass.
ANGLE_TRY(onTransformFeedbackStateChanged(contextVk));
}
@ -97,8 +97,8 @@ angle::Result TransformFeedbackVk::resume(const gl::Context *context)
if (contextVk->getFeatures().supportsTransformFeedbackExtension.enabled)
{
// We need to create new commandGraphNode to perform transform feedback pause/resume
// becasue vkCmdBegin/EndTransformFeedback can be placed once per commandGraphNode.
// We need to end the RenderPass to perform transform feedback pause/resume
// becasue vkCmdBegin/EndTransformFeedback can be placed once per RenderPass.
ANGLE_TRY(onTransformFeedbackStateChanged(contextVk));
}
@ -176,39 +176,6 @@ void TransformFeedbackVk::updateDescriptorSetLayout(
}
}
void TransformFeedbackVk::addFramebufferDependency(ContextVk *contextVk,
const gl::ProgramState &programState,
vk::FramebufferHelper *framebuffer) const
{
const std::vector<gl::OffsetBindingPointer<gl::Buffer>> &xfbBuffers =
mState.getIndexedBuffers();
size_t xfbBufferCount = programState.getTransformFeedbackBufferCount();
ASSERT(xfbBufferCount > 0);
ASSERT(programState.getTransformFeedbackBufferMode() != GL_INTERLEAVED_ATTRIBS ||
xfbBufferCount == 1);
VkAccessFlags writeAccessType = VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
if (!contextVk->getFeatures().supportsTransformFeedbackExtension.enabled)
{
writeAccessType = VK_ACCESS_SHADER_WRITE_BIT;
}
// Set framebuffer dependent to the transform feedback buffers. This is especially done
// separately from |updateDescriptorSet|, to avoid introducing unnecessary buffer barriers
// every time the descriptor set is updated (which, as the set is shared with default uniforms,
// could get updated frequently).
for (size_t bufferIndex = 0; bufferIndex < xfbBufferCount; ++bufferIndex)
{
const gl::OffsetBindingPointer<gl::Buffer> &bufferBinding = xfbBuffers[bufferIndex];
gl::Buffer *buffer = bufferBinding.get();
ASSERT(buffer != nullptr);
vk::BufferHelper &bufferHelper = vk::GetImpl(buffer)->getBuffer();
bufferHelper.onWrite(contextVk, framebuffer, writeAccessType);
}
}
void TransformFeedbackVk::initDescriptorSet(ContextVk *contextVk,
size_t xfbBufferCount,
vk::BufferHelper *emptyBuffer,
@ -319,22 +286,7 @@ angle::Result TransformFeedbackVk::onTransformFeedbackStateChanged(ContextVk *co
// TODO(syoussefi): detect changes to buffer usage (e.g. as transform feedback output, vertex
// or index data etc) in the front end and notify the backend. A new node should be created
// only on such changes. http://anglebug.com/3205
FramebufferVk *framebufferVk = vk::GetImpl(contextVk->getState().getDrawFramebuffer());
vk::FramebufferHelper *framebuffer = framebufferVk->getFramebuffer();
if (contextVk->commandGraphEnabled())
{
framebuffer->updateCurrentAccessNodes();
if (framebuffer->hasStartedRenderPass())
{
framebuffer->finishCurrentCommands(contextVk);
}
}
else
{
ANGLE_TRY(contextVk->endRenderPass());
}
ANGLE_TRY(contextVk->endRenderPass());
return angle::Result::Continue;
}

Просмотреть файл

@ -56,9 +56,6 @@ class TransformFeedbackVk : public TransformFeedbackImpl
void updateDescriptorSetLayout(ContextVk *contextVk,
const gl::ProgramState &programState,
vk::DescriptorSetLayoutDesc *descSetLayoutOut) const;
void addFramebufferDependency(ContextVk *contextVk,
const gl::ProgramState &programState,
vk::FramebufferHelper *framebuffer) const;
void initDescriptorSet(ContextVk *contextVk,
size_t xfbBufferCount,
vk::BufferHelper *emptyBuffer,

Просмотреть файл

@ -777,19 +777,9 @@ angle::Result UtilsVk::clearBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureBufferClearResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dest->recordCommands(contextVk, &commandBuffer));
// Tell dest it's being written to.
dest->onSelfReadWrite(contextVk, VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
// Tell the context dest that we are writing to dest.
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
// Tell the context dest that we are writing to dest.
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
const vk::Format &destFormat = dest->getViewFormat();
@ -838,19 +828,9 @@ angle::Result UtilsVk::convertIndexBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertIndexResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dest->recordCommands(contextVk, &commandBuffer));
// Tell src we are going to read from it and dest it's being written to.
src->onReadByBuffer(contextVk, dest, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
@ -910,28 +890,11 @@ angle::Result UtilsVk::convertIndexIndirectBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertIndexIndirectResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dstIndexBuf->recordCommands(contextVk, &commandBuffer));
// Tell src we are going to read from it and dest it's being written to.
srcIndexBuf->onReadByBuffer(contextVk, dstIndexBuf, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
srcIndirectBuf->onReadByBuffer(contextVk, dstIndexBuf, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
ANGLE_TRY(dstIndirectBuf->recordCommands(contextVk, &commandBuffer));
srcIndirectBuf->onReadByBuffer(contextVk, dstIndirectBuf, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuf));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndexBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndirectBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndexBuf));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuf));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndexBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndirectBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndexBuf));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
@ -995,29 +958,11 @@ angle::Result UtilsVk::convertLineLoopIndexIndirectBuffer(
ANGLE_TRY(ensureConvertIndexIndirectLineLoopResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dstIndexBuffer->recordCommands(contextVk, &commandBuffer));
// Tell src we are going to read from it and dest it's being written to.
srcIndexBuffer->onReadByBuffer(contextVk, dstIndexBuffer, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
srcIndirectBuffer->onReadByBuffer(contextVk, dstIndexBuffer, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
ANGLE_TRY(dstIndirectBuffer->recordCommands(contextVk, &commandBuffer));
srcIndirectBuffer->onReadByBuffer(contextVk, dstIndirectBuffer, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndexBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndexBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndexBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dstIndexBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
@ -1077,26 +1022,10 @@ angle::Result UtilsVk::convertLineLoopArrayIndirectBuffer(
ANGLE_TRY(ensureConvertIndirectLineLoopResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(destIndexBuffer->recordCommands(contextVk, &commandBuffer));
// Tell src we are going to read from it and dest it's being written to.
srcIndirectBuffer->onReadByBuffer(contextVk, destIndexBuffer, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
ANGLE_TRY(destIndirectBuffer->recordCommands(contextVk, &commandBuffer));
srcIndirectBuffer->onReadByBuffer(contextVk, destIndirectBuffer, VK_ACCESS_SHADER_READ_BIT,
VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, destIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, destIndexBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, destIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, destIndexBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
@ -1149,19 +1078,9 @@ angle::Result UtilsVk::convertVertexBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertVertexResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dest->recordCommands(contextVk, &commandBuffer));
// Tell src we are going to read from it and dest it's being written to.
src->onReadByBuffer(contextVk, dest, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_SHADER_WRITE_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
ConvertVertexShaderParams shaderParams;
shaderParams.Ns = params.srcFormat->channelCount;
@ -1254,17 +1173,8 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
renderPassAttachmentOps.initWithLoadStore(0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(image->beginRenderPass(contextVk, framebuffer, renderArea, renderPassDesc,
ANGLE_TRY(contextVk->beginRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues, commandBufferOut));
}
else
{
ANGLE_TRY(contextVk->beginRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, clearValues,
commandBufferOut));
}
contextVk->addGarbage(&framebuffer);
@ -1280,12 +1190,7 @@ angle::Result UtilsVk::clearFramebuffer(ContextVk *contextVk,
const gl::Rectangle &scissoredRenderArea = params.clearArea;
vk::CommandBuffer *commandBuffer;
if (!contextVk->commandGraphEnabled() ||
!framebuffer->appendToStartedRenderPass(&contextVk->getResourceUseList(),
scissoredRenderArea, &commandBuffer))
{
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, scissoredRenderArea, &commandBuffer));
}
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, scissoredRenderArea, &commandBuffer));
ImageClearShaderParams shaderParams;
shaderParams.clearValue = params.colorClearValue;
@ -1501,35 +1406,11 @@ angle::Result UtilsVk::blitResolveImpl(ContextVk *contextVk,
pipelineDesc.setScissor(gl_vk::GetRect(params.blitArea));
// Change source layout outside render pass
if (contextVk->commandGraphEnabled())
{
if (src->isLayoutChangeNecessary(vk::ImageLayout::AllGraphicsShadersReadOnly))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(src->recordCommands(contextVk, &srcLayoutChange));
src->changeLayout(src->getAspectFlags(), vk::ImageLayout::AllGraphicsShadersReadOnly,
srcLayoutChange);
}
}
else
{
ANGLE_TRY(contextVk->onImageRead(src->getAspectFlags(),
vk::ImageLayout::AllGraphicsShadersReadOnly, src));
}
ANGLE_TRY(contextVk->onImageRead(src->getAspectFlags(),
vk::ImageLayout::AllGraphicsShadersReadOnly, src));
vk::CommandBuffer *commandBuffer;
if (!contextVk->commandGraphEnabled() ||
!framebuffer->appendToStartedRenderPass(&contextVk->getResourceUseList(), params.blitArea,
&commandBuffer))
{
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer));
}
if (contextVk->commandGraphEnabled())
{
// Source's layout change should happen before rendering
src->addReadDependency(contextVk, framebuffer->getFramebuffer());
}
ANGLE_TRY(framebuffer->startNewRenderPass(contextVk, params.blitArea, &commandBuffer));
VkDescriptorImageInfo imageInfos[2] = {};
@ -1669,32 +1550,12 @@ angle::Result UtilsVk::stencilBlitResolveNoShaderExport(ContextVk *contextVk,
vk::ImageHelper *depthStencilImage = &depthStencilRenderTarget->getImage();
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
// Change source layout prior to computation.
if (src->isLayoutChangeNecessary(vk::ImageLayout::ComputeShaderReadOnly))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(src->recordCommands(contextVk, &srcLayoutChange));
src->changeLayout(src->getAspectFlags(), vk::ImageLayout::ComputeShaderReadOnly,
srcLayoutChange);
}
ANGLE_TRY(framebuffer->getFramebuffer()->recordCommands(contextVk, &commandBuffer));
src->addReadDependency(contextVk, framebuffer->getFramebuffer());
depthStencilImage->changeLayout(depthStencilImage->getAspectFlags(),
vk::ImageLayout::TransferDst, commandBuffer);
}
else
{
// Change source layout prior to computation.
ANGLE_TRY(contextVk->onImageRead(src->getAspectFlags(),
vk::ImageLayout::ComputeShaderReadOnly, src));
ANGLE_TRY(contextVk->onImageWrite(depthStencilImage->getAspectFlags(),
vk::ImageLayout::TransferDst, depthStencilImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
// Change source layout prior to computation.
ANGLE_TRY(
contextVk->onImageRead(src->getAspectFlags(), vk::ImageLayout::ComputeShaderReadOnly, src));
ANGLE_TRY(contextVk->onImageWrite(depthStencilImage->getAspectFlags(),
vk::ImageLayout::TransferDst, depthStencilImage));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// Blit/resolve stencil into the buffer.
VkDescriptorImageInfo imageInfo = {};
@ -1853,41 +1714,15 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
pipelineDesc.setScissor(scissor);
// Change source layout outside render pass
if (contextVk->commandGraphEnabled())
{
if (src->isLayoutChangeNecessary(vk::ImageLayout::AllGraphicsShadersReadOnly))
{
vk::CommandBuffer *srcLayoutChange;
ANGLE_TRY(src->recordCommands(contextVk, &srcLayoutChange));
src->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::AllGraphicsShadersReadOnly, srcLayoutChange);
}
// Change destination layout outside render pass as well
vk::CommandBuffer *destLayoutChange;
ANGLE_TRY(dest->recordCommands(contextVk, &destLayoutChange));
dest->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
destLayoutChange);
}
else
{
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::AllGraphicsShadersReadOnly, src));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ColorAttachment, dest));
}
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::AllGraphicsShadersReadOnly, src));
ANGLE_TRY(
contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment, dest));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(
startRenderPass(contextVk, dest, destView, renderPassDesc, renderArea, &commandBuffer));
if (contextVk->commandGraphEnabled())
{
// Source's layout change should happen before rendering
src->addReadDependency(contextVk, dest);
}
VkDescriptorImageInfo imageInfo = {};
imageInfo.imageView = srcView->getHandle();
imageInfo.imageLayout = src->getCurrentLayout();
@ -1948,21 +1783,10 @@ angle::Result UtilsVk::cullOverlayWidgets(ContextVk *contextVk,
&descriptorSet));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dest->recordCommands(contextVk, &commandBuffer));
dest->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ComputeShaderWrite,
commandBuffer);
enabledWidgetsBuffer->onRead(contextVk, dest, VK_ACCESS_SHADER_READ_BIT);
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, enabledWidgetsBuffer));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderWrite, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, enabledWidgetsBuffer));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderWrite, dest));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorImageInfo imageInfo = {};
imageInfo.imageView = destView->getHandle();
@ -1999,12 +1823,6 @@ angle::Result UtilsVk::cullOverlayWidgets(ContextVk *contextVk,
commandBuffer->dispatch(dest->getExtents().width, dest->getExtents().height, 1);
descriptorPoolBinding.reset();
if (contextVk->commandGraphEnabled())
{
dest->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ComputeShaderReadOnly,
commandBuffer);
}
return angle::Result::Continue;
}
@ -2036,30 +1854,16 @@ angle::Result UtilsVk::drawOverlay(ContextVk *contextVk,
&descriptorSet));
vk::CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(dest->recordCommands(contextVk, &commandBuffer));
dest->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ComputeShaderWrite,
commandBuffer);
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderWrite, dest));
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderReadOnly, culledWidgets));
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderReadOnly, font));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, textWidgetsBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, graphWidgetsBuffer));
culledWidgets->addReadDependency(contextVk, dest);
font->addReadDependency(contextVk, dest);
textWidgetsBuffer->onRead(contextVk, dest, VK_ACCESS_SHADER_READ_BIT);
graphWidgetsBuffer->onRead(contextVk, dest, VK_ACCESS_SHADER_READ_BIT);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderWrite, dest));
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderReadOnly, culledWidgets));
ANGLE_TRY(contextVk->onImageRead(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderReadOnly, font));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, textWidgetsBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, graphWidgetsBuffer));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkDescriptorImageInfo imageInfos[3] = {};
imageInfos[0].imageView = destView->getHandle();

Просмотреть файл

@ -1021,53 +1021,32 @@ void QueryHelper::deinit()
angle::Result QueryHelper::beginQuery(ContextVk *contextVk)
{
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->beginQuery(getQueryPool(), getQuery());
}
else
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->beginQuery(queryPool, mQuery, 0);
}
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->beginQuery(queryPool, mQuery, 0);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue;
}
angle::Result QueryHelper::endQuery(ContextVk *contextVk)
{
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->endQuery(getQueryPool(), getQuery());
}
else
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->endQuery(queryPool, mQuery);
}
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->endQuery(queryPool, mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue;
}
angle::Result QueryHelper::writeTimestamp(ContextVk *contextVk)
{
if (contextVk->commandGraphEnabled())
{
contextVk->getCommandGraph()->writeTimestamp(getQueryPool(), getQuery());
}
else
{
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery);
}
vk::PrimaryCommandBuffer *primaryCommands;
ANGLE_TRY(contextVk->getPrimaryCommandBuffer(&primaryCommands));
VkQueryPool queryPool = getQueryPool()->getHandle();
primaryCommands->resetQueryPool(queryPool, mQuery, 1);
primaryCommands->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, queryPool, mQuery);
mMostRecentSerial = contextVk->getCurrentQueueSerial();
return angle::Result::Continue;
}
@ -1457,8 +1436,7 @@ void LineLoopHelper::Draw(uint32_t count, uint32_t baseVertex, CommandBuffer *co
// BufferHelper implementation.
BufferHelper::BufferHelper()
: CommandGraphResource(CommandGraphResourceType::Buffer),
mMemoryPropertyFlags{},
: mMemoryPropertyFlags{},
mSize(0),
mMappedMemory(nullptr),
mViewFormat(nullptr),
@ -1587,21 +1565,6 @@ bool BufferHelper::needsOnWriteBarrier(VkAccessFlags writeAccessType,
return needsBarrier;
}
void BufferHelper::onWriteAccess(ContextVk *contextVk, VkAccessFlags writeAccessType)
{
VkAccessFlags barrierSrc, barrierDst;
if (needsOnWriteBarrier(writeAccessType, &barrierSrc, &barrierDst))
{
addGlobalMemoryBarrier(barrierSrc, barrierDst, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
bool hostVisible = mMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
if (hostVisible && writeAccessType != VK_ACCESS_HOST_WRITE_BIT)
{
contextVk->onHostVisibleBufferWrite();
}
}
angle::Result BufferHelper::copyFromBuffer(ContextVk *contextVk,
const Buffer &buffer,
VkAccessFlags bufferAccessType,
@ -1609,14 +1572,7 @@ angle::Result BufferHelper::copyFromBuffer(ContextVk *contextVk,
{
// 'recordCommands' will implicitly stop any reads from using the old buffer data.
CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0 || bufferAccessType != 0)
{
@ -1776,8 +1732,7 @@ void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType,
// ImageHelper implementation.
ImageHelper::ImageHelper()
: CommandGraphResource(CommandGraphResourceType::Image),
mFormat(nullptr),
: mFormat(nullptr),
mSamples(1),
mSerial(rx::kZeroSerial),
mCurrentLayout(ImageLayout::Undefined),
@ -1789,8 +1744,7 @@ ImageHelper::ImageHelper()
{}
ImageHelper::ImageHelper(ImageHelper &&other)
: CommandGraphResource(CommandGraphResourceType::Image),
mImage(std::move(other.mImage)),
: mImage(std::move(other.mImage)),
mDeviceMemory(std::move(other.mDeviceMemory)),
mExtents(other.mExtents),
mFormat(other.mFormat),
@ -2348,18 +2302,8 @@ void ImageHelper::Copy(ImageHelper *srcImage,
angle::Result ImageHelper::generateMipmapsWithBlit(ContextVk *contextVk, GLuint maxLevel)
{
CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, ImageLayout::TransferDst, commandBuffer);
}
else
{
ANGLE_TRY(
contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, ImageLayout::TransferDst, this));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, ImageLayout::TransferDst, this));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
// We are able to use blitImage since the image format we are using supports it. This
// is a faster way we can generate the mips.
@ -3015,14 +2959,7 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
uint64_t subresourceUploadsInProgress = 0;
// Start in TransferDst.
if (contextVk->commandGraphEnabled())
{
changeLayout(aspectFlags, ImageLayout::TransferDst, commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageWrite(aspectFlags, ImageLayout::TransferDst, this));
}
ANGLE_TRY(contextVk->onImageWrite(aspectFlags, ImageLayout::TransferDst, this));
for (SubresourceUpdate &update : mSubresourceUpdates)
{
@ -3121,31 +3058,15 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
BufferHelper *currentBuffer = bufferUpdate.bufferHelper;
ASSERT(currentBuffer && currentBuffer->valid());
if (contextVk->commandGraphEnabled())
{
currentBuffer->onResourceAccess(&contextVk->getResourceUseList());
}
else
{
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, currentBuffer));
}
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, currentBuffer));
commandBuffer->copyBufferToImage(currentBuffer->getBuffer().getHandle(), mImage,
getCurrentLayout(), 1, &update.buffer.copyRegion);
}
else
{
if (contextVk->commandGraphEnabled())
{
update.image.image->changeLayout(aspectFlags, ImageLayout::TransferSrc,
commandBuffer);
update.image.image->addReadDependency(contextVk, this);
}
else
{
ANGLE_TRY(contextVk->onImageRead(aspectFlags, ImageLayout::TransferSrc,
update.image.image));
}
ANGLE_TRY(
contextVk->onImageRead(aspectFlags, ImageLayout::TransferSrc, update.image.image));
commandBuffer->copyImage(update.image.image->getImage(),
update.image.image->getCurrentLayout(), mImage,
@ -3170,14 +3091,7 @@ angle::Result ImageHelper::flushAllStagedUpdates(ContextVk *contextVk)
{
// Clear the image.
CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
}
else
{
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
return flushStagedUpdates(contextVk, 0, mLevelCount, 0, mLayerCount, commandBuffer);
}
@ -3261,19 +3175,9 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk,
nullptr));
CommandBuffer *commandBuffer = nullptr;
if (contextVk->commandGraphEnabled())
{
ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
// Transition the image to readable layout
changeLayout(aspectFlags, ImageLayout::TransferSrc, commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageRead(aspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, *bufferOut));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
}
ANGLE_TRY(contextVk->onImageRead(aspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, *bufferOut));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
VkBufferImageCopy regions[2] = {};
// Default to non-combined DS case
@ -3429,26 +3333,13 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
// Note that although we're reading from the image, we need to update the layout below.
CommandBuffer *commandBuffer;
if (contextVk->commandGraphEnabled())
if (isMultisampled)
{
ANGLE_TRY(recordCommands(contextVk, &commandBuffer));
if (isMultisampled)
{
resolvedImage.get().changeLayout(copyAspectFlags, ImageLayout::TransferDst,
commandBuffer);
}
changeLayout(copyAspectFlags, ImageLayout::TransferSrc, commandBuffer);
}
else
{
if (isMultisampled)
{
ANGLE_TRY(contextVk->onImageWrite(copyAspectFlags, ImageLayout::TransferDst,
&resolvedImage.get()));
}
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
ANGLE_TRY(contextVk->onImageWrite(copyAspectFlags, ImageLayout::TransferDst,
&resolvedImage.get()));
}
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(&commandBuffer));
const angle::Format *readFormat = &mFormat->actualImageFormat();
@ -3495,16 +3386,8 @@ angle::Result ImageHelper::readPixels(ContextVk *contextVk,
resolve(&resolvedImage.get(), resolveRegion, commandBuffer);
if (contextVk->commandGraphEnabled())
{
resolvedImage.get().changeLayout(copyAspectFlags, ImageLayout::TransferSrc,
commandBuffer);
}
else
{
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc,
&resolvedImage.get()));
}
ANGLE_TRY(contextVk->onImageRead(copyAspectFlags, ImageLayout::TransferSrc,
&resolvedImage.get()));
// Make the resolved image the target of buffer copy.
src = &resolvedImage.get();
@ -3627,13 +3510,11 @@ bool ImageHelper::SubresourceUpdate::isUpdateToLayerLevel(uint32_t layerIndex,
}
// FramebufferHelper implementation.
FramebufferHelper::FramebufferHelper() : CommandGraphResource(CommandGraphResourceType::Framebuffer)
{}
FramebufferHelper::FramebufferHelper() = default;
FramebufferHelper::~FramebufferHelper() = default;
FramebufferHelper::FramebufferHelper(FramebufferHelper &&other)
: CommandGraphResource(CommandGraphResourceType::Framebuffer)
{
mFramebuffer = std::move(other.mFramebuffer);
}
@ -3862,7 +3743,7 @@ void SamplerHelper::release(RendererVk *renderer)
}
// DispatchHelper implementation.
DispatchHelper::DispatchHelper() : CommandGraphResource(CommandGraphResourceType::Dispatcher) {}
DispatchHelper::DispatchHelper() = default;
DispatchHelper::~DispatchHelper() = default;

Просмотреть файл

@ -476,42 +476,6 @@ class BufferHelper final : public CommandGraphResource
const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
VkDeviceSize getSize() const { return mSize; }
// Helpers for setting the graph dependencies *and* setting the appropriate barrier. These are
// made for dependencies to non-buffer resources, as only one of two resources participating in
// the dependency would require a memory barrier. Note that onWrite takes read access flags
// too, as output buffers could be read as well.
void onRead(ContextVk *contextVk, CommandGraphResource *reader, VkAccessFlags readAccessType)
{
addReadDependency(contextVk, reader);
onReadAccess(reader, readAccessType);
}
void onWrite(ContextVk *contextVk, CommandGraphResource *writer, VkAccessFlags writeAccessType)
{
addWriteDependency(contextVk, writer);
onWriteAccess(contextVk, writeAccessType);
}
// Helper for setting a graph dependency between two buffers. This is a specialized function as
// both buffers may incur a memory barrier. Using |onRead| followed by |onWrite| between the
// buffers is impossible as it would result in a command graph loop.
void onReadByBuffer(ContextVk *contextVk,
BufferHelper *reader,
VkAccessFlags readAccessType,
VkAccessFlags writeAccessType)
{
addReadDependency(contextVk, reader);
onReadAccess(reader, readAccessType);
reader->onWriteAccess(contextVk, writeAccessType);
}
// Helper for setting a barrier when different parts of the same buffer is being read from and
// written to in the same command.
void onSelfReadWrite(ContextVk *contextVk, VkAccessFlags writeAccessType)
{
if (mCurrentReadAccess || mCurrentWriteAccess)
{
finishCurrentCommands(contextVk);
}
onWriteAccess(contextVk, writeAccessType);
}
// Set write access mask when the buffer is modified externally, e.g. by host. There is no
// graph resource to create a dependency to.
void onExternalWrite(VkAccessFlags writeAccessType) { mCurrentWriteAccess |= writeAccessType; }
@ -557,7 +521,7 @@ class BufferHelper final : public CommandGraphResource
void changeQueue(uint32_t newQueueFamilyIndex, CommandBuffer *commandBuffer);
// New methods used when the CommandGraph is disabled.
// Currently always returns false. Should be smarter about accumulation.
bool canAccumulateRead(ContextVk *contextVk, VkAccessFlags readAccessType);
bool canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeAccessType);
@ -584,19 +548,9 @@ class BufferHelper final : public CommandGraphResource
mCurrentReadAccess |= readAccessType;
return needsBarrier;
}
void onReadAccess(CommandGraphResource *reader, VkAccessFlags readAccessType)
{
VkAccessFlags barrierSrc, barrierDst;
if (needsOnReadBarrier(readAccessType, &barrierSrc, &barrierDst))
{
reader->addGlobalMemoryBarrier(barrierSrc, barrierDst,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
}
bool needsOnWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut);
void onWriteAccess(ContextVk *contextVk, VkAccessFlags writeAccessType);
angle::Result initializeNonZeroMemory(Context *context, VkDeviceSize size);