diff --git a/include/platform/FeaturesVk.h b/include/platform/FeaturesVk.h index 9677fe187..8cee0f493 100644 --- a/include/platform/FeaturesVk.h +++ b/include/platform/FeaturesVk.h @@ -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 = { diff --git a/src/libANGLE/renderer/vulkan/BufferVk.cpp b/src/libANGLE/renderer/vulkan/BufferVk.cpp index 9e88eafeb..61ea46d35 100644 --- a/src/libANGLE/renderer/vulkan/BufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/BufferVk.cpp @@ -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(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; } diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.cpp b/src/libANGLE/renderer/vulkan/CommandGraph.cpp index ad522ec7e..a7650cd22 100644 --- a/src/libANGLE/renderer/vulkan/CommandGraph.cpp +++ b/src/libANGLE/renderer/vulkan/CommandGraph.cpp @@ -24,244 +24,8 @@ namespace rx { namespace vk { -namespace -{ -ANGLE_MAYBE_UNUSED -angle::Result InitAndBeginCommandBuffer(ContextVk *context, - const CommandPool &commandPool, - const VkCommandBufferInheritanceInfo &inheritanceInfo, - VkCommandBufferUsageFlags flags, - angle::PoolAllocator *poolAllocator, - priv::SecondaryCommandBuffer *commandBuffer) -{ - ASSERT(!commandBuffer->valid()); - commandBuffer->initialize(poolAllocator); - return angle::Result::Continue; -} - -ANGLE_MAYBE_UNUSED -angle::Result InitAndBeginCommandBuffer(vk::Context *context, - const CommandPool &commandPool, - const VkCommandBufferInheritanceInfo &inheritanceInfo, - VkCommandBufferUsageFlags flags, - angle::PoolAllocator *poolAllocator, - priv::CommandBuffer *commandBuffer) -{ - ASSERT(!commandBuffer->valid()); - ASSERT(commandPool.valid()); - VkCommandBufferAllocateInfo createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - createInfo.commandPool = commandPool.getHandle(); - createInfo.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY; - createInfo.commandBufferCount = 1; - - ANGLE_VK_TRY(context, commandBuffer->init(context->getDevice(), createInfo)); - - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = flags | VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - beginInfo.pInheritanceInfo = &inheritanceInfo; - - ANGLE_VK_TRY(context, commandBuffer->begin(beginInfo)); - return angle::Result::Continue; -} - -const char *GetResourceTypeName(CommandGraphResourceType resourceType, - CommandGraphNodeFunction function) -{ - switch (resourceType) - { - case CommandGraphResourceType::Buffer: - return "Buffer"; - case CommandGraphResourceType::Framebuffer: - return "Framebuffer"; - case CommandGraphResourceType::Image: - return "Image"; - case CommandGraphResourceType::Query: - switch (function) - { - case CommandGraphNodeFunction::BeginQuery: - return "BeginQuery"; - case CommandGraphNodeFunction::EndQuery: - return "EndQuery"; - case CommandGraphNodeFunction::WriteTimestamp: - return "WriteTimestamp"; - default: - UNREACHABLE(); - return "Query"; - } - case CommandGraphResourceType::Dispatcher: - return "Dispatcher"; - case CommandGraphResourceType::EmulatedQuery: - switch (function) - { - case CommandGraphNodeFunction::BeginTransformFeedbackQuery: - return "BeginTransformFeedbackQuery"; - case CommandGraphNodeFunction::EndTransformFeedbackQuery: - return "EndTransformFeedbackQuery"; - default: - UNREACHABLE(); - return "EmulatedQuery"; - } - case CommandGraphResourceType::FenceSync: - switch (function) - { - case CommandGraphNodeFunction::SetFenceSync: - return "SetFenceSync"; - case CommandGraphNodeFunction::WaitFenceSync: - return "WaitFenceSync"; - default: - UNREACHABLE(); - return "FenceSync"; - } - case CommandGraphResourceType::GraphBarrier: - return "GraphBarrier"; - case CommandGraphResourceType::DebugMarker: - switch (function) - { - case CommandGraphNodeFunction::InsertDebugMarker: - return "InsertDebugMarker"; - case CommandGraphNodeFunction::PushDebugMarker: - return "PushDebugMarker"; - case CommandGraphNodeFunction::PopDebugMarker: - return "PopDebugMarker"; - default: - UNREACHABLE(); - return "DebugMarker"; - } - case CommandGraphResourceType::HostAvailabilityOperation: - switch (function) - { - case CommandGraphNodeFunction::HostAvailabilityOperation: - return "HostAvailabilityOperation"; - default: - UNREACHABLE(); - return "HostAvailabilityOperation"; - } - default: - UNREACHABLE(); - return ""; - } -} - -const char *GetLoadOpShorthand(uint32_t loadOp) -{ - switch (loadOp) - { - case VK_ATTACHMENT_LOAD_OP_CLEAR: - return "C"; - case VK_ATTACHMENT_LOAD_OP_LOAD: - return "L"; - default: - return "D"; - } -} - -const char *GetStoreOpShorthand(uint32_t storeOp) -{ - switch (storeOp) - { - case VK_ATTACHMENT_STORE_OP_STORE: - return "S"; - default: - return "D"; - } -} - -constexpr VkSubpassContents kRenderPassContents = - CommandBuffer::ExecutesInline() ? VK_SUBPASS_CONTENTS_INLINE - : VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS; - -// Helpers to unify executeCommands call based on underlying cmd buffer type -ANGLE_MAYBE_UNUSED -void ExecuteCommands(PrimaryCommandBuffer *primCmdBuffer, - priv::SecondaryCommandBuffer *secCmdBuffer) -{ - secCmdBuffer->executeCommands(primCmdBuffer->getHandle()); -} - -ANGLE_MAYBE_UNUSED -void ExecuteCommands(PrimaryCommandBuffer *primCmdBuffer, priv::CommandBuffer *secCmdBuffer) -{ - primCmdBuffer->executeCommands(1, secCmdBuffer); -} - -ANGLE_MAYBE_UNUSED -void InsertBeginTransformFeedback(PrimaryCommandBuffer *primCmdBuffer, - priv::SecondaryCommandBuffer &commandBuffer, - uint32_t validBufferCount, - const VkBuffer *counterBuffers, - bool rebindBuffer) -{ - uint32_t counterBufferCount = (rebindBuffer) ? 0 : validBufferCount; - primCmdBuffer->beginTransformFeedbackEXT(0, counterBufferCount, counterBuffers, nullptr); -} - -ANGLE_MAYBE_UNUSED -void InsertEndTransformFeedback(PrimaryCommandBuffer *primCmdBuffer, - priv::SecondaryCommandBuffer &commandBuffer, - uint32_t validBufferCount, - const VkBuffer *counterBuffers) -{ - primCmdBuffer->endTransformFeedbackEXT(0, validBufferCount, counterBuffers, nullptr); -} - -ANGLE_MAYBE_UNUSED -void InsertCounterBufferPipelineBarrier(PrimaryCommandBuffer *primCmdBuffer, - priv::SecondaryCommandBuffer &commandBuffer, - const VkBuffer *counterBuffers) -{ - VkBufferMemoryBarrier bufferBarrier = {}; - bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - bufferBarrier.pNext = nullptr; - bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT; - bufferBarrier.dstAccessMask = VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT; - bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - bufferBarrier.buffer = counterBuffers[0]; - bufferBarrier.offset = 0; - bufferBarrier.size = VK_WHOLE_SIZE; - - vkCmdPipelineBarrier(primCmdBuffer->getHandle(), VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, - VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 0u, nullptr, 1u, &bufferBarrier, - 0u, nullptr); -} - -ANGLE_MAYBE_UNUSED -std::string DumpCommands(const priv::SecondaryCommandBuffer &commandBuffer, const char *separator) -{ - return commandBuffer.dumpCommands(separator); -} - -ANGLE_MAYBE_UNUSED -std::string DumpCommands(const priv::CommandBuffer &commandBuffer, const char *separator) -{ - return "--blob--"; -} - -float CalculateSecondaryCommandBufferPoolWaste(const std::vector nodes) -{ - size_t used = 0; - size_t allocated = 0; - - for (const CommandGraphNode *node : nodes) - { - size_t nodeUsed; - size_t nodeAllocated; - node->getMemoryUsageStatsForDiagnostics(&nodeUsed, &nodeAllocated); - used += nodeUsed; - allocated += nodeAllocated; - } - - allocated = std::max(allocated, 1); - return static_cast(used) / static_cast(allocated); -} - -} // anonymous namespace - // CommandGraphResource implementation. -CommandGraphResource::CommandGraphResource(CommandGraphResourceType resourceType) - : mCurrentWritingNode(nullptr), mResourceType(resourceType) +CommandGraphResource::CommandGraphResource() { mUse.init(); } @@ -276,603 +40,6 @@ angle::Result CommandGraphResource::finishRunningCommands(ContextVk *contextVk) return contextVk->finishToSerial(mUse.getSerial()); } -angle::Result CommandGraphResource::recordCommands(ContextVk *contextVk, - CommandBuffer **commandBufferOut) -{ - ASSERT(contextVk->commandGraphEnabled()); - - updateCurrentAccessNodes(); - - if (!hasChildlessWritingNode() || hasStartedRenderPass()) - { - startNewCommands(contextVk); - return mCurrentWritingNode->beginOutsideRenderPassRecording( - contextVk, contextVk->getCommandPool(), commandBufferOut); - } - - CommandBuffer *outsideRenderPassCommands = mCurrentWritingNode->getOutsideRenderPassCommands(); - if (!outsideRenderPassCommands->valid()) - { - ANGLE_TRY(mCurrentWritingNode->beginOutsideRenderPassRecording( - contextVk, contextVk->getCommandPool(), commandBufferOut)); - } - else - { - *commandBufferOut = outsideRenderPassCommands; - } - - // Store reference to usage in graph. - contextVk->getResourceUseList().add(mUse); - - return angle::Result::Continue; -} - -angle::Result CommandGraphResource::beginRenderPass( - ContextVk *contextVk, - const Framebuffer &framebuffer, - const gl::Rectangle &renderArea, - const RenderPassDesc &renderPassDesc, - const AttachmentOpsArray &renderPassAttachmentOps, - const std::vector &clearValues, - CommandBuffer **commandBufferOut) -{ - // If a barrier has been inserted in the meantime, stop the command buffer. - if (!hasChildlessWritingNode()) - { - startNewCommands(contextVk); - } - - mCurrentWritingNode->storeRenderPassInfo(framebuffer, renderArea, renderPassDesc, - renderPassAttachmentOps, clearValues); - - mCurrentWritingNode->setRenderPassOwner(contextVk); - - return mCurrentWritingNode->beginInsideRenderPassRecording(contextVk, commandBufferOut); -} - -void CommandGraphResource::addWriteDependency(ContextVk *contextVk, - CommandGraphResource *writingResource) -{ - ASSERT(contextVk->commandGraphEnabled()); - - CommandGraphNode *writingNode = writingResource->mCurrentWritingNode; - ASSERT(writingNode); - - onWriteImpl(contextVk, writingNode); -} - -void CommandGraphResource::addReadDependency(ContextVk *contextVk, - CommandGraphResource *readingResource) -{ - ASSERT(contextVk->commandGraphEnabled()); - - onResourceAccess(&contextVk->getResourceUseList()); - - CommandGraphNode *readingNode = readingResource->mCurrentWritingNode; - ASSERT(readingNode); - - if (mCurrentWritingNode) - { - // Ensure 'readingNode' happens after the current writing node. - CommandGraphNode::SetHappensBeforeDependency(mCurrentWritingNode, readingNode); - } - - // Add the read node to the list of nodes currently reading this resource. - mCurrentReadingNodes.push_back(readingNode); -} - -void CommandGraphResource::finishCurrentCommands(ContextVk *contextVk) -{ - ASSERT(contextVk->commandGraphEnabled()); - startNewCommands(contextVk); -} - -void CommandGraphResource::startNewCommands(ContextVk *contextVk) -{ - ASSERT(contextVk->commandGraphEnabled()); - CommandGraphNode *newCommands = - contextVk->getCommandGraph()->allocateNode(CommandGraphNodeFunction::Generic); - newCommands->setDiagnosticInfo(mResourceType, reinterpret_cast(this)); - onWriteImpl(contextVk, newCommands); -} - -void CommandGraphResource::onWriteImpl(ContextVk *contextVk, CommandGraphNode *writingNode) -{ - onResourceAccess(&contextVk->getResourceUseList()); - - // Make sure any open reads and writes finish before we execute 'writingNode'. - if (!mCurrentReadingNodes.empty()) - { - CommandGraphNode::SetHappensBeforeDependencies(mCurrentReadingNodes.data(), - mCurrentReadingNodes.size(), writingNode); - mCurrentReadingNodes.clear(); - } - - if (mCurrentWritingNode && mCurrentWritingNode != writingNode) - { - CommandGraphNode::SetHappensBeforeDependency(mCurrentWritingNode, writingNode); - } - - mCurrentWritingNode = writingNode; -} - -// CommandGraphNode implementation. -CommandGraphNode::CommandGraphNode(CommandGraphNodeFunction function, - angle::PoolAllocator *poolAllocator) - : mRenderPassClearValues{}, - mFunction(function), - mPoolAllocator(poolAllocator), - mQueryPool(VK_NULL_HANDLE), - mQueryIndex(0), - mFenceSyncEvent(VK_NULL_HANDLE), - mHasChildren(false), - mVisitedState(VisitedState::Unvisited), - mGlobalMemoryBarrierSrcAccess(0), - mGlobalMemoryBarrierDstAccess(0), - mGlobalMemoryBarrierStages(0), - mRenderPassOwner(nullptr), - mValidTransformFeedbackBufferCount(0) -{} - -CommandGraphNode::~CommandGraphNode() -{ - mRenderPassFramebuffer.setHandle(VK_NULL_HANDLE); - // Command buffers are managed by the command pool, so don't need to be freed. - mOutsideRenderPassCommands.releaseHandle(); - mInsideRenderPassCommands.releaseHandle(); -} - -angle::Result CommandGraphNode::beginOutsideRenderPassRecording(ContextVk *context, - const CommandPool &commandPool, - CommandBuffer **commandsOut) -{ - ASSERT(!mHasChildren); - - VkCommandBufferInheritanceInfo inheritanceInfo = {}; - inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - inheritanceInfo.renderPass = VK_NULL_HANDLE; - inheritanceInfo.subpass = 0; - inheritanceInfo.framebuffer = VK_NULL_HANDLE; - inheritanceInfo.occlusionQueryEnable = - CommandBuffer::SupportsQueries(context->getRenderer()->getPhysicalDeviceFeatures()); - inheritanceInfo.queryFlags = 0; - inheritanceInfo.pipelineStatistics = 0; - - ANGLE_TRY(InitAndBeginCommandBuffer(context, commandPool, inheritanceInfo, 0, mPoolAllocator, - &mOutsideRenderPassCommands)); - - *commandsOut = &mOutsideRenderPassCommands; - return angle::Result::Continue; -} - -angle::Result CommandGraphNode::beginInsideRenderPassRecording(ContextVk *context, - CommandBuffer **commandsOut) -{ - context->getCommandGraph()->tickRenderPassCount(); - - ASSERT(!mHasChildren); - - // Get a compatible RenderPass from the cache so we can initialize the inheritance info. - // TODO(jmadill): Support query for compatible/conformant render pass. http://anglebug.com/2361 - RenderPass *compatibleRenderPass; - ANGLE_TRY(context->getCompatibleRenderPass(mRenderPassDesc, &compatibleRenderPass)); - - VkCommandBufferInheritanceInfo inheritanceInfo = {}; - inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - inheritanceInfo.renderPass = compatibleRenderPass->getHandle(); - inheritanceInfo.subpass = 0; - inheritanceInfo.framebuffer = mRenderPassFramebuffer.getHandle(); - inheritanceInfo.occlusionQueryEnable = - CommandBuffer::SupportsQueries(context->getRenderer()->getPhysicalDeviceFeatures()); - inheritanceInfo.queryFlags = 0; - inheritanceInfo.pipelineStatistics = 0; - - ANGLE_TRY(InitAndBeginCommandBuffer(context, context->getCommandPool(), inheritanceInfo, - VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, - mPoolAllocator, &mInsideRenderPassCommands)); - - *commandsOut = &mInsideRenderPassCommands; - return angle::Result::Continue; -} - -void CommandGraphNode::storeRenderPassInfo(const Framebuffer &framebuffer, - const gl::Rectangle renderArea, - const vk::RenderPassDesc &renderPassDesc, - const AttachmentOpsArray &renderPassAttachmentOps, - const std::vector &clearValues) -{ - mRenderPassDesc = renderPassDesc; - mRenderPassAttachmentOps = renderPassAttachmentOps; - mRenderPassFramebuffer.setHandle(framebuffer.getHandle()); - mRenderPassRenderArea = renderArea; - std::copy(clearValues.begin(), clearValues.end(), mRenderPassClearValues.begin()); -} - -// static -void CommandGraphNode::SetHappensBeforeDependencies(CommandGraphNode **beforeNodes, - size_t beforeNodesCount, - CommandGraphNode *afterNode) -{ - afterNode->mParents.insert(afterNode->mParents.end(), beforeNodes, - beforeNodes + beforeNodesCount); - - // TODO(jmadill): is there a faster way to do this? - for (size_t i = 0; i < beforeNodesCount; ++i) - { - beforeNodes[i]->setHasChildren(); - - ASSERT(beforeNodes[i] != afterNode && !beforeNodes[i]->isChildOf(afterNode)); - } -} - -void CommandGraphNode::SetHappensBeforeDependencies(CommandGraphNode *beforeNode, - CommandGraphNode **afterNodes, - size_t afterNodesCount) -{ - for (size_t i = 0; i < afterNodesCount; ++i) - { - SetHappensBeforeDependency(beforeNode, afterNodes[i]); - } -} - -bool CommandGraphNode::hasParents() const -{ - return !mParents.empty(); -} - -void CommandGraphNode::setQueryPool(const QueryPool *queryPool, uint32_t queryIndex) -{ - ASSERT(mFunction == CommandGraphNodeFunction::BeginQuery || - mFunction == CommandGraphNodeFunction::EndQuery || - mFunction == CommandGraphNodeFunction::WriteTimestamp || - mFunction == CommandGraphNodeFunction::BeginTransformFeedbackQuery || - mFunction == CommandGraphNodeFunction::EndTransformFeedbackQuery); - mQueryPool = queryPool->getHandle(); - mQueryIndex = queryIndex; -} - -void CommandGraphNode::setFenceSync(const vk::Event &event) -{ - ASSERT(mFunction == CommandGraphNodeFunction::SetFenceSync || - mFunction == CommandGraphNodeFunction::WaitFenceSync); - mFenceSyncEvent = event.getHandle(); -} - -void CommandGraphNode::setDebugMarker(GLenum source, std::string &&marker) -{ - ASSERT(mFunction == CommandGraphNodeFunction::InsertDebugMarker || - mFunction == CommandGraphNodeFunction::PushDebugMarker); - mDebugMarkerSource = source; - mDebugMarker = std::move(marker); -} - -// Do not call this in anything but testing code, since it's slow. -bool CommandGraphNode::isChildOf(CommandGraphNode *parent) -{ - std::set visitedList; - std::vector openList; - openList.insert(openList.begin(), mParents.begin(), mParents.end()); - while (!openList.empty()) - { - CommandGraphNode *current = openList.back(); - openList.pop_back(); - if (visitedList.count(current) == 0) - { - if (current == parent) - { - return true; - } - visitedList.insert(current); - openList.insert(openList.end(), current->mParents.begin(), current->mParents.end()); - } - } - - return false; -} - -VisitedState CommandGraphNode::visitedState() const -{ - return mVisitedState; -} - -void CommandGraphNode::visitParents(std::vector *stack) -{ - ASSERT(mVisitedState == VisitedState::Unvisited); - stack->insert(stack->end(), mParents.begin(), mParents.end()); - mVisitedState = VisitedState::Ready; -} - -angle::Result CommandGraphNode::visitAndExecute(vk::Context *context, - Serial serial, - RenderPassCache *renderPassCache, - PrimaryCommandBuffer *primaryCommandBuffer) -{ - // Record the deferred pipeline barrier if necessary. - ASSERT((mGlobalMemoryBarrierDstAccess == 0) == (mGlobalMemoryBarrierSrcAccess == 0)); - if (mGlobalMemoryBarrierSrcAccess) - { - VkMemoryBarrier memoryBarrier = {}; - memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; - memoryBarrier.srcAccessMask = mGlobalMemoryBarrierSrcAccess; - memoryBarrier.dstAccessMask = mGlobalMemoryBarrierDstAccess; - - primaryCommandBuffer->memoryBarrier(mGlobalMemoryBarrierStages, mGlobalMemoryBarrierStages, - &memoryBarrier); - } - - switch (mFunction) - { - case CommandGraphNodeFunction::Generic: - ASSERT(mQueryPool == VK_NULL_HANDLE && mFenceSyncEvent == VK_NULL_HANDLE); - - if (mOutsideRenderPassCommands.valid()) - { - ANGLE_VK_TRY(context, mOutsideRenderPassCommands.end()); - ExecuteCommands(primaryCommandBuffer, &mOutsideRenderPassCommands); - } - - if (mInsideRenderPassCommands.valid()) - { - // Pull a RenderPass from the cache. - // TODO(jmadill): Insert layout transitions. - RenderPass *renderPass = nullptr; - ANGLE_TRY(renderPassCache->getRenderPassWithOps( - context, serial, mRenderPassDesc, mRenderPassAttachmentOps, &renderPass)); - - ANGLE_VK_TRY(context, mInsideRenderPassCommands.end()); - - VkRenderPassBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - beginInfo.renderPass = renderPass->getHandle(); - beginInfo.framebuffer = mRenderPassFramebuffer.getHandle(); - beginInfo.renderArea.offset.x = static_cast(mRenderPassRenderArea.x); - beginInfo.renderArea.offset.y = static_cast(mRenderPassRenderArea.y); - beginInfo.renderArea.extent.width = - static_cast(mRenderPassRenderArea.width); - beginInfo.renderArea.extent.height = - static_cast(mRenderPassRenderArea.height); - beginInfo.clearValueCount = - static_cast(mRenderPassDesc.attachmentCount()); - beginInfo.pClearValues = mRenderPassClearValues.data(); - - primaryCommandBuffer->beginRenderPass(beginInfo, kRenderPassContents); - if (mValidTransformFeedbackBufferCount == 0) - { - ExecuteCommands(primaryCommandBuffer, &mInsideRenderPassCommands); - primaryCommandBuffer->endRenderPass(); - } - else - { - InsertBeginTransformFeedback(primaryCommandBuffer, mInsideRenderPassCommands, - mValidTransformFeedbackBufferCount, - mTransformFeedbackCounterBuffers.data(), - mRebindTransformFeedbackBuffers); - ExecuteCommands(primaryCommandBuffer, &mInsideRenderPassCommands); - InsertEndTransformFeedback(primaryCommandBuffer, mInsideRenderPassCommands, - mValidTransformFeedbackBufferCount, - mTransformFeedbackCounterBuffers.data()); - primaryCommandBuffer->endRenderPass(); - InsertCounterBufferPipelineBarrier(primaryCommandBuffer, - mInsideRenderPassCommands, - mTransformFeedbackCounterBuffers.data()); - } - } - break; - - case CommandGraphNodeFunction::BeginQuery: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - ASSERT(mQueryPool != VK_NULL_HANDLE); - - primaryCommandBuffer->resetQueryPool(mQueryPool, mQueryIndex, 1); - primaryCommandBuffer->beginQuery(mQueryPool, mQueryIndex, 0); - - break; - - case CommandGraphNodeFunction::EndQuery: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - ASSERT(mQueryPool != VK_NULL_HANDLE); - - primaryCommandBuffer->endQuery(mQueryPool, mQueryIndex); - - break; - - case CommandGraphNodeFunction::WriteTimestamp: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - ASSERT(mQueryPool != VK_NULL_HANDLE); - - primaryCommandBuffer->resetQueryPool(mQueryPool, mQueryIndex, 1); - primaryCommandBuffer->writeTimestamp(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, mQueryPool, - mQueryIndex); - - break; - - case CommandGraphNodeFunction::BeginTransformFeedbackQuery: - // Unless using VK_EXT_transform_feedback (not implemented currently), there's nothing - // to do. - break; - - case CommandGraphNodeFunction::EndTransformFeedbackQuery: - // Same as BeginTransformFeedbackQuery. - break; - - case CommandGraphNodeFunction::SetFenceSync: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - ASSERT(mFenceSyncEvent != VK_NULL_HANDLE); - - primaryCommandBuffer->setEvent(mFenceSyncEvent, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); - - break; - - case CommandGraphNodeFunction::WaitFenceSync: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - ASSERT(mFenceSyncEvent != VK_NULL_HANDLE); - - // Fence Syncs are purely execution barriers, so there are no memory barriers attached. - primaryCommandBuffer->waitEvents( - 1, &mFenceSyncEvent, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, nullptr, 0, nullptr, 0, nullptr); - - break; - - case CommandGraphNodeFunction::GraphBarrier: - // Nothing to do. The memory barrier, if any, is already handled above through global - // memory barrier flags. - break; - - case CommandGraphNodeFunction::InsertDebugMarker: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - - if (context->getRenderer()->enableDebugUtils()) - { - VkDebugUtilsLabelEXT label; - MakeDebugUtilsLabel(mDebugMarkerSource, mDebugMarker.c_str(), &label); - primaryCommandBuffer->insertDebugUtilsLabelEXT(label); - } - break; - - case CommandGraphNodeFunction::PushDebugMarker: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - - if (context->getRenderer()->enableDebugUtils()) - { - VkDebugUtilsLabelEXT label; - MakeDebugUtilsLabel(mDebugMarkerSource, mDebugMarker.c_str(), &label); - primaryCommandBuffer->beginDebugUtilsLabelEXT(label); - } - break; - - case CommandGraphNodeFunction::PopDebugMarker: - ASSERT(!mOutsideRenderPassCommands.valid() && !mInsideRenderPassCommands.valid()); - - if (context->getRenderer()->enableDebugUtils()) - { - primaryCommandBuffer->endDebugUtilsLabelEXT(); - } - break; - - case CommandGraphNodeFunction::HostAvailabilityOperation: - // 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; - - primaryCommandBuffer->memoryBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_HOST_BIT, &memoryBarrier); - } - break; - - default: - UNREACHABLE(); - } - - mVisitedState = VisitedState::Visited; - return angle::Result::Continue; -} - -const std::vector &CommandGraphNode::getParentsForDiagnostics() const -{ - return mParents; -} - -void CommandGraphNode::setDiagnosticInfo(CommandGraphResourceType resourceType, - uintptr_t resourceID) -{ - mResourceType = resourceType; - mResourceID = resourceID; -} - -bool CommandGraphNode::hasDiagnosticID() const -{ - // All nodes have diagnostic IDs to differentiate them except the following select few. - return mResourceType != CommandGraphResourceType::HostAvailabilityOperation && - mResourceType != CommandGraphResourceType::GraphBarrier; -} - -std::string CommandGraphNode::dumpCommandsForDiagnostics(const char *separator) const -{ - std::string result; - if (mGlobalMemoryBarrierSrcAccess != 0 || mGlobalMemoryBarrierDstAccess != 0) - { - result += separator; - - std::ostringstream out; - out << "Memory Barrier Src: 0x" << std::hex << mGlobalMemoryBarrierSrcAccess - << " → Dst: 0x" << std::hex << mGlobalMemoryBarrierDstAccess; - result += out.str(); - } - if (mOutsideRenderPassCommands.valid()) - { - result += separator; - result += "Outside RP:"; - result += DumpCommands(mOutsideRenderPassCommands, separator); - } - if (mInsideRenderPassCommands.valid()) - { - result += separator; - result += "Inside RP:"; - - size_t attachmentCount = mRenderPassDesc.attachmentCount(); - size_t depthStencilAttachmentCount = mRenderPassDesc.hasDepthStencilAttachment(); - size_t colorAttachmentCount = attachmentCount - depthStencilAttachmentCount; - - std::string loadOps, storeOps; - - if (colorAttachmentCount > 0) - { - loadOps += " Color: "; - storeOps += " Color: "; - - for (size_t i = 0; i < colorAttachmentCount; ++i) - { - loadOps += GetLoadOpShorthand(mRenderPassAttachmentOps[i].loadOp); - storeOps += GetStoreOpShorthand(mRenderPassAttachmentOps[i].storeOp); - } - } - - if (depthStencilAttachmentCount > 0) - { - ASSERT(depthStencilAttachmentCount == 1); - - loadOps += " Depth/Stencil: "; - storeOps += " Depth/Stencil: "; - size_t dsIndex = colorAttachmentCount; - - loadOps += GetLoadOpShorthand(mRenderPassAttachmentOps[dsIndex].loadOp); - loadOps += GetLoadOpShorthand(mRenderPassAttachmentOps[dsIndex].stencilLoadOp); - - storeOps += GetStoreOpShorthand(mRenderPassAttachmentOps[dsIndex].storeOp); - storeOps += GetStoreOpShorthand(mRenderPassAttachmentOps[dsIndex].stencilStoreOp); - } - - if (attachmentCount > 0) - { - result += " LoadOp: " + loadOps; - result += separator; - result += "------------ StoreOp: " + storeOps; - } - - result += DumpCommands(mInsideRenderPassCommands, separator); - } - return result; -} - -void CommandGraphNode::getMemoryUsageStatsForDiagnostics(size_t *usedMemoryOut, - size_t *allocatedMemoryOut) const -{ - size_t commandBufferUsed; - size_t commandBufferAllocated; - - mOutsideRenderPassCommands.getMemoryUsageStats(usedMemoryOut, allocatedMemoryOut); - mInsideRenderPassCommands.getMemoryUsageStats(&commandBufferUsed, &commandBufferAllocated); - - *usedMemoryOut += commandBufferUsed; - *allocatedMemoryOut += commandBufferAllocated; -} - // SharedGarbage implementation. SharedGarbage::SharedGarbage() = default; @@ -909,426 +76,6 @@ bool SharedGarbage::destroyIfComplete(VkDevice device, Serial completedSerial) return true; } -// CommandGraph implementation. -CommandGraph::CommandGraph(bool enableGraphDiagnostics, angle::PoolAllocator *poolAllocator) - : mEnableGraphDiagnostics(enableGraphDiagnostics), - mPoolAllocator(poolAllocator), - mLastBarrierIndex(kInvalidNodeIndex), - mRenderPassCount(0) -{ - // Push so that allocations made from here will be recycled in clear() below. - mPoolAllocator->push(); -} - -CommandGraph::~CommandGraph() -{ - ASSERT(empty()); -} - -CommandGraphNode *CommandGraph::allocateNode(CommandGraphNodeFunction function) -{ - // TODO(jmadill): Use a pool allocator for the CPU node allocations. - CommandGraphNode *newCommands = new CommandGraphNode(function, mPoolAllocator); - mNodes.emplace_back(newCommands); - return newCommands; -} - -CommandGraphNode *CommandGraph::allocateBarrierNode(CommandGraphNodeFunction function, - CommandGraphResourceType resourceType, - uintptr_t resourceID) -{ - CommandGraphNode *newNode = allocateNode(function); - newNode->setDiagnosticInfo(resourceType, resourceID); - setNewBarrier(newNode); - - return newNode; -} - -void CommandGraph::setNewBarrier(CommandGraphNode *newBarrier) -{ - size_t previousBarrierIndex = 0; - CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex); - - // Add a dependency from previousBarrier to all nodes in (previousBarrier, newBarrier). - if (previousBarrier && previousBarrierIndex + 1 < mNodes.size()) - { - size_t afterNodesCount = mNodes.size() - (previousBarrierIndex + 2); - CommandGraphNode::SetHappensBeforeDependencies( - previousBarrier, &mNodes[previousBarrierIndex + 1], afterNodesCount); - } - - // Add a dependency from all nodes in [previousBarrier, newBarrier) to newBarrier. - addDependenciesToNextBarrier(previousBarrierIndex, mNodes.size() - 1, newBarrier); - - mLastBarrierIndex = mNodes.size() - 1; -} - -angle::Result CommandGraph::submitCommands(ContextVk *context, - Serial serial, - RenderPassCache *renderPassCache, - PrimaryCommandBuffer *primaryCommandBuffer) -{ - // There is no point in submitting an empty command buffer, so make sure not to call this - // function if there's nothing to do. - ASSERT(!mNodes.empty()); - - updateOverlay(context); - mRenderPassCount = 0; - - size_t previousBarrierIndex = 0; - CommandGraphNode *previousBarrier = getLastBarrierNode(&previousBarrierIndex); - - // Add a dependency from previousBarrier to all nodes in (previousBarrier, end]. - if (previousBarrier && previousBarrierIndex + 1 < mNodes.size()) - { - size_t afterNodesCount = mNodes.size() - (previousBarrierIndex + 1); - CommandGraphNode::SetHappensBeforeDependencies( - previousBarrier, &mNodes[previousBarrierIndex + 1], afterNodesCount); - } - - if (mEnableGraphDiagnostics) - { - dumpGraphDotFile(std::cout); - } - - std::vector nodeStack; - - VkCommandBufferBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - beginInfo.pInheritanceInfo = nullptr; - - ANGLE_VK_TRY(context, primaryCommandBuffer->begin(beginInfo)); - - ANGLE_TRY(context->traceGpuEvent(primaryCommandBuffer, TRACE_EVENT_PHASE_BEGIN, - "Primary Command Buffer")); - - for (CommandGraphNode *topLevelNode : mNodes) - { - // Only process commands that don't have child commands. The others will be pulled in - // automatically. Also skip commands that have already been visited. - if (topLevelNode->hasChildren() || topLevelNode->visitedState() != VisitedState::Unvisited) - continue; - - nodeStack.push_back(topLevelNode); - - while (!nodeStack.empty()) - { - CommandGraphNode *node = nodeStack.back(); - - switch (node->visitedState()) - { - case VisitedState::Unvisited: - node->visitParents(&nodeStack); - break; - case VisitedState::Ready: - ANGLE_TRY(node->visitAndExecute(context, serial, renderPassCache, - primaryCommandBuffer)); - nodeStack.pop_back(); - break; - case VisitedState::Visited: - nodeStack.pop_back(); - break; - default: - UNREACHABLE(); - break; - } - } - } - - ANGLE_TRY(context->traceGpuEvent(primaryCommandBuffer, TRACE_EVENT_PHASE_END, - "Primary Command Buffer")); - - ANGLE_VK_TRY(context, primaryCommandBuffer->end()); - - clear(); - - return angle::Result::Continue; -} - -bool CommandGraph::empty() const -{ - return mNodes.empty(); -} - -void CommandGraph::clear() -{ - mLastBarrierIndex = kInvalidNodeIndex; - // Release cmd graph pool memory now that cmds are submitted - // NOTE: This frees all memory since last push. Right now only the CommandGraph - // will push the allocator (at creation and below). If other people start - // pushing the allocator this (and/or the allocator) will need to be updated. - mPoolAllocator->pop(); - mPoolAllocator->push(); - - // TODO(jmadill): Use pool allocator for performance. http://anglebug.com/2951 - for (CommandGraphNode *node : mNodes) - { - delete node; - } - mNodes.clear(); -} - -void CommandGraph::beginQuery(const QueryPool *queryPool, uint32_t queryIndex) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::BeginQuery, - CommandGraphResourceType::Query, 0); - newNode->setQueryPool(queryPool, queryIndex); -} - -void CommandGraph::endQuery(const QueryPool *queryPool, uint32_t queryIndex) -{ - CommandGraphNode *newNode = - allocateBarrierNode(CommandGraphNodeFunction::EndQuery, CommandGraphResourceType::Query, 0); - newNode->setQueryPool(queryPool, queryIndex); -} - -void CommandGraph::writeTimestamp(const QueryPool *queryPool, uint32_t queryIndex) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::WriteTimestamp, - CommandGraphResourceType::Query, 0); - newNode->setQueryPool(queryPool, queryIndex); -} - -void CommandGraph::beginTransformFeedbackEmulatedQuery() -{ - allocateBarrierNode(CommandGraphNodeFunction::BeginTransformFeedbackQuery, - CommandGraphResourceType::EmulatedQuery, 0); -} - -void CommandGraph::endTransformFeedbackEmulatedQuery() -{ - allocateBarrierNode(CommandGraphNodeFunction::EndTransformFeedbackQuery, - CommandGraphResourceType::EmulatedQuery, 0); -} - -void CommandGraph::setFenceSync(const vk::Event &event) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::SetFenceSync, - CommandGraphResourceType::FenceSync, - reinterpret_cast(&event)); - newNode->setFenceSync(event); -} - -void CommandGraph::waitFenceSync(const vk::Event &event) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::WaitFenceSync, - CommandGraphResourceType::FenceSync, - reinterpret_cast(&event)); - newNode->setFenceSync(event); -} - -void CommandGraph::memoryBarrier(VkFlags srcAccess, VkFlags dstAccess, VkPipelineStageFlags stages) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::GraphBarrier, - CommandGraphResourceType::GraphBarrier, 0); - newNode->addGlobalMemoryBarrier(srcAccess, dstAccess, stages); -} - -void CommandGraph::insertDebugMarker(GLenum source, std::string &&marker) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::InsertDebugMarker, - CommandGraphResourceType::DebugMarker, 0); - newNode->setDebugMarker(source, std::move(marker)); -} - -void CommandGraph::pushDebugMarker(GLenum source, std::string &&marker) -{ - CommandGraphNode *newNode = allocateBarrierNode(CommandGraphNodeFunction::PushDebugMarker, - CommandGraphResourceType::DebugMarker, 0); - newNode->setDebugMarker(source, std::move(marker)); -} - -void CommandGraph::popDebugMarker() -{ - allocateBarrierNode(CommandGraphNodeFunction::PopDebugMarker, - CommandGraphResourceType::DebugMarker, 0); -} - -void CommandGraph::makeHostVisibleBufferWriteAvailable() -{ - allocateBarrierNode(CommandGraphNodeFunction::HostAvailabilityOperation, - CommandGraphResourceType::HostAvailabilityOperation, 0); -} - -void CommandGraph::syncExternalMemory() -{ - // Add an all-inclusive memory barrier. - memoryBarrier(VK_ACCESS_MEMORY_WRITE_BIT, - VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); -} - -// Dumps the command graph into a dot file that works with graphviz. -void CommandGraph::dumpGraphDotFile(std::ostream &out) const -{ - // This ID maps a node pointer to a monotonic ID. It allows us to look up parent node IDs. - std::map nodeIDMap; - std::map objectIDMap; - std::map, int> queryIDMap; - - // Map nodes to ids. - for (size_t nodeIndex = 0; nodeIndex < mNodes.size(); ++nodeIndex) - { - const CommandGraphNode *node = mNodes[nodeIndex]; - nodeIDMap[node] = static_cast(nodeIndex) + 1; - } - - int bufferIDCounter = 1; - int framebufferIDCounter = 1; - int imageIDCounter = 1; - int queryIDCounter = 1; - int dispatcherIDCounter = 1; - int fenceIDCounter = 1; - int xfbIDCounter = 1; - - out << "digraph {" << std::endl; - - for (const CommandGraphNode *node : mNodes) - { - int nodeID = nodeIDMap[node]; - - std::stringstream strstr; - strstr << GetResourceTypeName(node->getResourceTypeForDiagnostics(), node->getFunction()); - - if (node->getResourceTypeForDiagnostics() == CommandGraphResourceType::DebugMarker) - { - // For debug markers, use the string from the debug marker itself. - if (node->getFunction() != CommandGraphNodeFunction::PopDebugMarker) - { - strstr << " " << node->getDebugMarker(); - } - } - else if (node->getResourceTypeForDiagnostics() == CommandGraphResourceType::Query) - { - // Special case for queries as they cannot generate a resource ID at creation time that - // would reliably fit in a uintptr_t. - strstr << " "; - - ASSERT(node->getResourceIDForDiagnostics() == 0); - - auto queryID = std::make_pair(node->getQueryPool(), node->getQueryIndex()); - - auto it = queryIDMap.find(queryID); - if (it != queryIDMap.end()) - { - strstr << it->second; - } - else - { - int id = queryIDCounter++; - - queryIDMap[queryID] = id; - strstr << id; - } - } - else if (!node->hasDiagnosticID()) - { - // Nothing to append for these special nodes. The name is sufficient. - } - else - { - strstr << " "; - - // Otherwise assign each object an ID, so all the nodes of the same object have the same - // label. - ASSERT(node->getResourceIDForDiagnostics() != 0); - auto it = objectIDMap.find(node->getResourceIDForDiagnostics()); - if (it != objectIDMap.end()) - { - strstr << it->second; - } - else - { - int id = 0; - - switch (node->getResourceTypeForDiagnostics()) - { - case CommandGraphResourceType::Buffer: - id = bufferIDCounter++; - break; - case CommandGraphResourceType::Framebuffer: - id = framebufferIDCounter++; - break; - case CommandGraphResourceType::Image: - id = imageIDCounter++; - break; - case CommandGraphResourceType::Dispatcher: - id = dispatcherIDCounter++; - break; - case CommandGraphResourceType::FenceSync: - id = fenceIDCounter++; - break; - case CommandGraphResourceType::EmulatedQuery: - id = xfbIDCounter++; - break; - default: - UNREACHABLE(); - break; - } - - objectIDMap[node->getResourceIDForDiagnostics()] = id; - strstr << id; - } - } - - const std::string &label = strstr.str(); - out << " " << nodeID << "[label =<" << label << "
Node ID " - << nodeID << node->dumpCommandsForDiagnostics("
") << "
>];" << std::endl; - } - - for (const CommandGraphNode *node : mNodes) - { - int nodeID = nodeIDMap[node]; - - for (const CommandGraphNode *parent : node->getParentsForDiagnostics()) - { - int parentID = nodeIDMap[parent]; - out << " " << parentID << " -> " << nodeID << ";" << std::endl; - } - } - - out << "}" << std::endl; -} - -void CommandGraph::updateOverlay(ContextVk *contextVk) const -{ - const gl::OverlayType *overlay = contextVk->getOverlay(); - - overlay->getRunningGraphWidget(gl::WidgetId::VulkanCommandGraphSize)->add(mNodes.size()); - - gl::RunningHistogramWidget *poolWaste = - overlay->getRunningHistogramWidget(gl::WidgetId::VulkanSecondaryCommandBufferPoolWaste); - poolWaste->set(CalculateSecondaryCommandBufferPoolWaste(mNodes)); - poolWaste->next(); - - gl::RunningGraphWidget *renderPassCount = - overlay->getRunningGraphWidget(gl::WidgetId::VulkanRenderPassCount); - renderPassCount->add(mRenderPassCount); - renderPassCount->next(); -} - -CommandGraphNode *CommandGraph::getLastBarrierNode(size_t *indexOut) -{ - *indexOut = mLastBarrierIndex == kInvalidNodeIndex ? 0 : mLastBarrierIndex; - return mLastBarrierIndex == kInvalidNodeIndex ? nullptr : mNodes[mLastBarrierIndex]; -} - -void CommandGraph::addDependenciesToNextBarrier(size_t begin, - size_t end, - CommandGraphNode *nextBarrier) -{ - for (size_t i = begin; i < end; ++i) - { - // As a small optimization, only add edges to childless nodes. The others have an - // indirect dependency. - if (!mNodes[i]->hasChildren()) - { - CommandGraphNode::SetHappensBeforeDependency(mNodes[i], nextBarrier); - } - } -} - // ResourceUseList implementation. ResourceUseList::ResourceUseList() = default; diff --git a/src/libANGLE/renderer/vulkan/CommandGraph.h b/src/libANGLE/renderer/vulkan/CommandGraph.h index 3c76fed38..f185a7da0 100644 --- a/src/libANGLE/renderer/vulkan/CommandGraph.h +++ b/src/libANGLE/renderer/vulkan/CommandGraph.h @@ -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 &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 *stack); - angle::Result visitAndExecute(Context *context, - Serial serial, - RenderPassCache *renderPassCache, - PrimaryCommandBuffer *primaryCommandBuffer); - - // Only used in the command graph diagnostics. - const std::vector &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(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 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 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 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 &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 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 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::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 diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index 432e99136..811947b40 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -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::max(), std::numeric_limits::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 &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> &xfbBuffers = + mState.getCurrentTransformFeedback()->getIndexedBuffers(); + + for (size_t bufferIndex = 0; bufferIndex < bufferCount; ++bufferIndex) { - size_t bufferCount = mProgram->getState().getTransformFeedbackBufferCount(); - const std::vector> &xfbBuffers = - mState.getCurrentTransformFeedback()->getIndexedBuffers(); + const gl::OffsetBindingPointer &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 &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(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 &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 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 &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); } diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index feee61e58..baa1b2e01 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -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 *sharedFenceOut); vk::Shared 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; diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp index ce8a457e4..d6654ed36 100644 --- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp @@ -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 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) diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.h b/src/libANGLE/renderer/vulkan/FramebufferVk.h index b2baeca5c..82ad5c494 100644 --- a/src/libANGLE/renderer/vulkan/FramebufferVk.h +++ b/src/libANGLE/renderer/vulkan/FramebufferVk.h @@ -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, diff --git a/src/libANGLE/renderer/vulkan/OverlayVk.cpp b/src/libANGLE/renderer/vulkan/OverlayVk.cpp index da81d2b40..04df9148b 100644 --- a/src/libANGLE/renderer/vulkan/OverlayVk.cpp +++ b/src/libANGLE/renderer/vulkan/OverlayVk.cpp @@ -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; } diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp index 9d0d890f2..5d031e96d 100644 --- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp +++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp @@ -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); diff --git a/src/libANGLE/renderer/vulkan/QueryVk.cpp b/src/libANGLE/renderer/vulkan/QueryVk.cpp index 356ecff37..8068c8bde 100644 --- a/src/libANGLE/renderer/vulkan/QueryVk.cpp +++ b/src/libANGLE/renderer/vulkan/QueryVk.cpp @@ -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) { diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp index af865ae0c..582dfe98e 100644 --- a/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp +++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.cpp @@ -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); } diff --git a/src/libANGLE/renderer/vulkan/RenderTargetVk.h b/src/libANGLE/renderer/vulkan/RenderTargetVk.h index cdccc27b7..1a38f18c3 100644 --- a/src/libANGLE/renderer/vulkan/RenderTargetVk.h +++ b/src/libANGLE/renderer/vulkan/RenderTargetVk.h @@ -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; diff --git a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp index 0118588b0..583b33614 100644 --- a/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp +++ b/src/libANGLE/renderer/vulkan/RenderbufferVk.cpp @@ -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); } diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp index 52ce011c3..5070f3120 100644 --- a/src/libANGLE/renderer/vulkan/RendererVk.cpp +++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp @@ -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); diff --git a/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp b/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp index 0dc46caa1..6ec33ceef 100644 --- a/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp +++ b/src/libANGLE/renderer/vulkan/SemaphoreVk.cpp @@ -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); diff --git a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp index 4c6c4d3e5..c102cd56d 100644 --- a/src/libANGLE/renderer/vulkan/SurfaceVk.cpp +++ b/src/libANGLE/renderer/vulkan/SurfaceVk.cpp @@ -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; diff --git a/src/libANGLE/renderer/vulkan/SyncVk.cpp b/src/libANGLE/renderer/vulkan/SyncVk.cpp index 2abfa7bc7..a97249f45 100644 --- a/src/libANGLE/renderer/vulkan/SyncVk.cpp +++ b/src/libANGLE/renderer/vulkan/SyncVk.cpp @@ -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; } diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp index c11865466..e066ff2f1 100644 --- a/src/libANGLE/renderer/vulkan/TextureVk.cpp +++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp @@ -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); diff --git a/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp b/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp index 5b2ebb0c4..1184b6cba 100644 --- a/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp +++ b/src/libANGLE/renderer/vulkan/TransformFeedbackVk.cpp @@ -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> &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 &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; } diff --git a/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h b/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h index 35db0c426..4e862b005 100644 --- a/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h +++ b/src/libANGLE/renderer/vulkan/TransformFeedbackVk.h @@ -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, diff --git a/src/libANGLE/renderer/vulkan/UtilsVk.cpp b/src/libANGLE/renderer/vulkan/UtilsVk.cpp index 183cefba3..39396fb8d 100644 --- a/src/libANGLE/renderer/vulkan/UtilsVk.cpp +++ b/src/libANGLE/renderer/vulkan/UtilsVk.cpp @@ -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(); diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index 3d9a7a5c2..1e8f6b827 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -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; diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h index 8d8bae34c..bc2691438 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.h +++ b/src/libANGLE/renderer/vulkan/vk_helpers.h @@ -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);