зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
519163eeb4
Коммит
c58458e633
|
@ -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, ©);
|
||||
|
||||
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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче