Commit f07d0072 by Charlie Lao Committed by Commit Bot

Vulkan: use fine grain stage for buffer barriers

We are using VK_PIPELINE_STAGE_ALL_COMMANDS_BIT for mGlobalMemoryBarrierStages, which is used for both src and dst. This will cause a full pipeline stall whenever a buffer object introduces a barrier. This CL will let the caller pass in the specific stage it will be used for, allowing us to track write and read stage dependencies separately and request the corresponding barriers. Bug: b/155122200 Change-Id: I8b8bd291a03b77d07cfbcbe7c3cda2d3771588b9 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2169014 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 95741743
......@@ -305,8 +305,10 @@ angle::Result BufferVk::copySubData(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &sourceBuffer->getBuffer()));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, mBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
&sourceBuffer->getBuffer()));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
mBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
// Enqueue a copy command on the GPU.
......@@ -500,11 +502,11 @@ angle::Result BufferVk::stagedUpdate(ContextVk *contextVk,
ASSERT(mapPointer);
memcpy(mapPointer, data, size);
mStagingBuffer.getCurrentBuffer()->onExternalWrite(VK_ACCESS_HOST_WRITE_BIT);
// Enqueue a copy command on the GPU.
VkBufferCopy copyRegion = {stagingBufferOffset, offset, size};
ANGLE_TRY(mBuffer->copyFromBuffer(contextVk, mStagingBuffer.getCurrentBuffer(),
VK_ACCESS_HOST_WRITE_BIT, copyRegion));
ANGLE_TRY(mBuffer->copyFromBuffer(contextVk, mStagingBuffer.getCurrentBuffer(), copyRegion));
mStagingBuffer.getCurrentBuffer()->retain(&contextVk->getResourceUseList());
return angle::Result::Continue;
......@@ -551,8 +553,10 @@ angle::Result BufferVk::copyToBufferImpl(ContextVk *contextVk,
const VkBufferCopy *copies)
{
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, mBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
destBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
mBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
commandBuffer->copyBuffer(mBuffer->getBuffer(), destBuffer->getBuffer(), copyCount, copies);
......
......@@ -1043,7 +1043,7 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
GLsizei instanceCount = 1;
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
indirectBuffer);
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, indirectBuffer);
ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount,
gl::DrawElementsType::InvalidEnum, nullptr, dirtyBitMask,
......@@ -1356,7 +1356,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(const gl::Context *con
if (arrayBuffer)
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
arrayBuffer);
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, arrayBuffer);
}
}
......@@ -1373,7 +1373,8 @@ angle::Result ContextVk::handleDirtyGraphicsIndexBuffer(const gl::Context *conte
mVertexArray->getCurrentElementArrayBufferOffset(),
getVkIndexType(mCurrentDrawElementsType));
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT, elementArrayBuffer);
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, elementArrayBuffer);
return angle::Result::Continue;
}
......@@ -1433,7 +1434,8 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation(
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
mRenderPassCommands.bufferWrite(
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, &bufferHelper);
}
// TODO(http://anglebug.com/3570): Need to update to handle Program Pipelines
......@@ -1472,8 +1474,9 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension(
vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
bufferHandles[bufferIndex] = bufferHelper.getBuffer().getHandle();
mRenderPassCommands.bufferWrite(&mResourceUseList,
VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, &bufferHelper);
mRenderPassCommands.bufferWrite(
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, &bufferHelper);
}
const TransformFeedbackBufferRange &xfbBufferRangeExtension =
......@@ -2140,7 +2143,7 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any())
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
VK_PIPELINE_STAGE_DRAW_INDIRECT_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.
......@@ -2194,7 +2197,7 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any())
{
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
currentIndirectBuf);
VK_PIPELINE_STAGE_DRAW_INDIRECT_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.
......@@ -3338,7 +3341,7 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi
gl::Buffer *glBuffer = getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
vk::BufferHelper &buffer = vk::GetImpl(glBuffer)->getBuffer();
mOutsideRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
&buffer);
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &buffer);
commandBuffer->dispatchIndirect(buffer.getBuffer(), indirect);
......@@ -4125,7 +4128,9 @@ bool ContextVk::shouldUseOldRewriteStructSamplers() const
return mRenderer->getFeatures().forceOldRewriteStructSamplers.enabled;
}
angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer)
angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType,
VkPipelineStageFlags readStage,
vk::BufferHelper *buffer)
{
ANGLE_TRY(endRenderPass());
......@@ -4134,12 +4139,14 @@ angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, vk::BufferHe
flushOutsideRenderPassCommands();
}
mOutsideRenderPassCommands.bufferRead(&mResourceUseList, readAccessType, buffer);
mOutsideRenderPassCommands.bufferRead(&mResourceUseList, readAccessType, readStage, buffer);
return angle::Result::Continue;
}
angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer)
angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage,
vk::BufferHelper *buffer)
{
ANGLE_TRY(endRenderPass());
......@@ -4148,7 +4155,7 @@ angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType, vk::Buffer
flushOutsideRenderPassCommands();
}
mOutsideRenderPassCommands.bufferWrite(&mResourceUseList, writeAccessType, buffer);
mOutsideRenderPassCommands.bufferWrite(&mResourceUseList, writeAccessType, writeStage, buffer);
return angle::Result::Continue;
}
......@@ -4428,29 +4435,32 @@ CommandBufferHelper::CommandBufferHelper()
mImageBarrierDstStageMask(0),
mGlobalMemoryBarrierSrcAccess(0),
mGlobalMemoryBarrierDstAccess(0),
mGlobalMemoryBarrierStages(0)
mGlobalMemoryBarrierSrcStages(0),
mGlobalMemoryBarrierDstStages(0)
{}
CommandBufferHelper::~CommandBufferHelper() = default;
void CommandBufferHelper::bufferRead(vk::ResourceUseList *resourceUseList,
VkAccessFlags readAccessType,
VkPipelineStageFlags readStage,
vk::BufferHelper *buffer)
{
buffer->retain(resourceUseList);
buffer->updateReadBarrier(readAccessType, &mGlobalMemoryBarrierSrcAccess,
&mGlobalMemoryBarrierDstAccess);
mGlobalMemoryBarrierStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
&mGlobalMemoryBarrierDstAccess, readStage,
&mGlobalMemoryBarrierSrcStages, &mGlobalMemoryBarrierDstStages);
}
void CommandBufferHelper::bufferWrite(vk::ResourceUseList *resourceUseList,
VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage,
vk::BufferHelper *buffer)
{
buffer->retain(resourceUseList);
buffer->updateWriteBarrier(writeAccessType, &mGlobalMemoryBarrierSrcAccess,
&mGlobalMemoryBarrierDstAccess);
mGlobalMemoryBarrierStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
&mGlobalMemoryBarrierDstAccess, writeStage,
&mGlobalMemoryBarrierSrcStages, &mGlobalMemoryBarrierDstStages);
}
void CommandBufferHelper::imageBarrier(VkPipelineStageFlags srcStageMask,
......@@ -4504,12 +4514,13 @@ void CommandBufferHelper::executeBarriers(vk::PrimaryCommandBuffer *primary)
memoryBarrier.dstAccessMask = mGlobalMemoryBarrierDstAccess;
memoryBarrierCount++;
srcStages |= mGlobalMemoryBarrierStages;
dstStages |= mGlobalMemoryBarrierStages;
srcStages |= mGlobalMemoryBarrierSrcStages;
dstStages |= mGlobalMemoryBarrierDstStages;
mGlobalMemoryBarrierSrcAccess = 0;
mGlobalMemoryBarrierDstAccess = 0;
mGlobalMemoryBarrierStages = 0;
mGlobalMemoryBarrierSrcStages = 0;
mGlobalMemoryBarrierDstStages = 0;
}
srcStages |= mImageBarrierSrcStageMask;
......
......@@ -117,9 +117,11 @@ struct CommandBufferHelper : angle::NonCopyable
public:
void bufferRead(vk::ResourceUseList *resourceUseList,
VkAccessFlags readAccessType,
VkPipelineStageFlags readStage,
vk::BufferHelper *buffer);
void bufferWrite(vk::ResourceUseList *resourceUseList,
VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage,
vk::BufferHelper *buffer);
void imageRead(vk::ResourceUseList *resourceUseList,
......@@ -149,7 +151,8 @@ struct CommandBufferHelper : angle::NonCopyable
std::vector<VkImageMemoryBarrier> mImageMemoryBarriers;
VkFlags mGlobalMemoryBarrierSrcAccess;
VkFlags mGlobalMemoryBarrierDstAccess;
VkPipelineStageFlags mGlobalMemoryBarrierStages;
VkPipelineStageFlags mGlobalMemoryBarrierSrcStages;
VkPipelineStageFlags mGlobalMemoryBarrierDstStages;
vk::CommandBuffer mCommandBuffer;
};
......@@ -614,8 +617,12 @@ class ContextVk : public ContextImpl, public vk::Context
vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }
angle::Result onBufferRead(VkAccessFlags readAccessType, vk::BufferHelper *buffer);
angle::Result onBufferWrite(VkAccessFlags writeAccessType, vk::BufferHelper *buffer);
angle::Result onBufferRead(VkAccessFlags readAccessType,
VkPipelineStageFlags readStage,
vk::BufferHelper *buffer);
angle::Result onBufferWrite(VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage,
vk::BufferHelper *buffer);
angle::Result onImageRead(VkImageAspectFlags aspectFlags,
vk::ImageLayout imageLayout,
......
......@@ -122,7 +122,8 @@ angle::Result OverlayVk::createFont(ContextVk *contextVk)
// Copy font data from staging buffer.
vk::CommandBuffer *fontDataUpload;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, &fontDataBuffer.get()));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
&fontDataBuffer.get()));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst,
&mFontImage));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&fontDataUpload));
......
......@@ -941,11 +941,14 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
{
// 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);
commandBufferHelper->bufferWrite(resourceUseList, accessFlags,
gl_vk::kPipelineStageShaderMap[shaderType],
&bufferHelper);
}
else
{
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
gl_vk::kPipelineStageShaderMap[shaderType],
&bufferHelper);
}
......@@ -1017,8 +1020,9 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
&writeInfo);
// We set SHADER_READ_BIT to be conservative.
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,
gl_vk::kPipelineStageShaderMap[shaderType], &bufferHelper);
writtenBindings.set(binding);
}
......
......@@ -1035,7 +1035,8 @@ angle::Result TextureVk::copyBufferDataToImage(ContextVk *contextVk,
ANGLE_TRY(ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels));
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, srcBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
srcBuffer));
ANGLE_TRY(
contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::TransferDst, mImage));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
......
......@@ -795,7 +795,8 @@ angle::Result UtilsVk::clearBuffer(ContextVk *contextVk,
vk::CommandBuffer *commandBuffer;
// Tell the context dest that we are writing to dest.
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dest));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
const vk::Format &destFormat = dest->getViewFormat();
......@@ -845,8 +846,10 @@ angle::Result UtilsVk::convertIndexBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertIndexResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dest));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
......@@ -907,10 +910,14 @@ angle::Result UtilsVk::convertIndexIndirectBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertIndexIndirectResourcesInitialized(contextVk));
vk::CommandBuffer *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->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, srcIndirectBuf));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, srcIndexBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dstIndirectBuf));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dstIndexBuf));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
......@@ -975,10 +982,14 @@ angle::Result UtilsVk::convertLineLoopIndexIndirectBuffer(
ANGLE_TRY(ensureConvertIndexIndirectLineLoopResourcesInitialized(contextVk));
vk::CommandBuffer *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->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, srcIndexBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dstIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dstIndexBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
......@@ -1035,9 +1046,12 @@ angle::Result UtilsVk::convertLineLoopArrayIndirectBuffer(
ANGLE_TRY(ensureConvertIndirectLineLoopResourcesInitialized(contextVk));
vk::CommandBuffer *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->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, srcIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, destIndirectBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, destIndexBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
VkDescriptorSet descriptorSet;
......@@ -1091,8 +1105,10 @@ angle::Result UtilsVk::convertVertexBuffer(ContextVk *contextVk,
ANGLE_TRY(ensureConvertVertexResourcesInitialized(contextVk));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, dest));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, src));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dest));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
ConvertVertexShaderParams shaderParams;
......@@ -1803,7 +1819,8 @@ angle::Result UtilsVk::cullOverlayWidgets(ContextVk *contextVk,
&descriptorSet));
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT, enabledWidgetsBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, enabledWidgetsBuffer));
ANGLE_TRY(contextVk->onImageWrite(VK_IMAGE_ASPECT_COLOR_BIT,
vk::ImageLayout::ComputeShaderWrite, dest));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
......@@ -1880,8 +1897,10 @@ angle::Result UtilsVk::drawOverlay(ContextVk *contextVk,
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->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, textWidgetsBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_SHADER_READ_BIT,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, graphWidgetsBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
......
......@@ -1687,7 +1687,9 @@ BufferHelper::BufferHelper()
mViewFormat(nullptr),
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mCurrentWriteAccess(0),
mCurrentReadAccess(0)
mCurrentReadAccess(0),
mCurrentWriteStages(0),
mCurrentReadStages(0)
{}
BufferHelper::~BufferHelper() = default;
......@@ -1806,31 +1808,15 @@ void BufferHelper::release(RendererVk *renderer)
renderer->collectGarbageAndReinit(&mUse, &mBuffer, &mBufferView, &mAllocation);
}
bool BufferHelper::needsOnWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut)
{
bool needsBarrier = mCurrentReadAccess != 0 || mCurrentWriteAccess != 0;
// Note: mCurrentReadAccess is not part of barrier src flags as "anything-after-read" is
// satisified by execution barriers alone.
*barrierSrcOut = mCurrentWriteAccess;
*barrierDstOut = writeAccessType;
mCurrentWriteAccess = writeAccessType;
mCurrentReadAccess = 0;
return needsBarrier;
}
angle::Result BufferHelper::copyFromBuffer(ContextVk *contextVk,
BufferHelper *srcBuffer,
VkAccessFlags bufferAccessType,
const VkBufferCopy &copyRegion)
{
CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(contextVk->onBufferWrite(bufferAccessType, this));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, srcBuffer));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
this));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
srcBuffer));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
commandBuffer->copyBuffer(srcBuffer->getBuffer(), mBuffer, 1, &copyRegion);
......@@ -1936,31 +1922,49 @@ bool BufferHelper::canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeA
void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut)
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags readStage,
VkPipelineStageFlags *barrierSrcStageOut,
VkPipelineStageFlags *barrierDstStageOut)
{
if (mCurrentWriteAccess != 0 && (mCurrentReadAccess & readAccessType) != readAccessType)
// If there was a prior write and we are making a read that is either a new access type or from
// a new stage, we need a barrier
if (mCurrentWriteAccess != 0 && (((mCurrentReadAccess & readAccessType) != readAccessType) ||
((mCurrentReadStages & readStage) != readStage)))
{
*barrierSrcOut |= mCurrentWriteAccess;
*barrierDstOut |= readAccessType;
*barrierSrcStageOut |= mCurrentWriteStages;
*barrierDstStageOut |= readStage;
}
// Accumulate new read usage.
mCurrentReadAccess |= readAccessType;
mCurrentReadStages |= readStage;
}
void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut)
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags writeStage,
VkPipelineStageFlags *barrierSrcStageOut,
VkPipelineStageFlags *barrierDstStageOut)
{
// We don't need to check mCurrentReadStages here since if it is not zero, mCurrentReadAccess
// must not be zero as well. stage is finer grain than accessType.
if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0)
{
*barrierSrcOut |= mCurrentWriteAccess;
*barrierDstOut |= writeAccessType;
*barrierSrcStageOut |= mCurrentWriteStages | mCurrentReadStages;
*barrierDstStageOut |= writeStage;
}
// Reset usages on the new write.
mCurrentWriteAccess = writeAccessType;
mCurrentReadAccess = 0;
mCurrentWriteStages = writeStage;
mCurrentReadStages = 0;
}
// ImageHelper implementation.
......@@ -3354,7 +3358,8 @@ angle::Result ImageHelper::flushStagedUpdates(ContextVk *contextVk,
BufferHelper *currentBuffer = bufferUpdate.bufferHelper;
ASSERT(currentBuffer && currentBuffer->valid());
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, currentBuffer));
ANGLE_TRY(contextVk->onBufferRead(VK_ACCESS_TRANSFER_READ_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, currentBuffer));
commandBuffer->copyBufferToImage(currentBuffer->getBuffer().getHandle(), mImage,
getCurrentLayout(), 1, &update.buffer.copyRegion);
......@@ -3472,7 +3477,8 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk,
CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(contextVk->onImageRead(aspectFlags, ImageLayout::TransferSrc, this));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, *bufferOut));
ANGLE_TRY(contextVk->onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
*bufferOut));
ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
VkBufferImageCopy regions[2] = {};
......
......@@ -572,12 +572,16 @@ class BufferHelper final : public Resource
// 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; }
void onExternalWrite(VkAccessFlags writeAccessType)
{
ASSERT(writeAccessType == VK_ACCESS_HOST_WRITE_BIT);
mCurrentWriteAccess |= writeAccessType;
mCurrentWriteStages |= VK_PIPELINE_STAGE_HOST_BIT;
}
// Also implicitly sets up the correct barriers.
angle::Result copyFromBuffer(ContextVk *contextVk,
BufferHelper *srcBuffer,
VkAccessFlags bufferAccessType,
const VkBufferCopy &copyRegion);
// Note: currently only one view is allowed. If needs be, multiple views can be created
......@@ -630,31 +634,20 @@ class BufferHelper final : public Resource
void updateReadBarrier(VkAccessFlags readAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut);
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags readStage,
VkPipelineStageFlags *barrierSrcStageOut,
VkPipelineStageFlags *barrierDstStageOut);
void updateWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut);
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags writeStage,
VkPipelineStageFlags *barrierSrcStageOut,
VkPipelineStageFlags *barrierDstStageOut);
private:
angle::Result mapImpl(ContextVk *contextVk);
bool needsOnReadBarrier(VkAccessFlags readAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut)
{
bool needsBarrier =
mCurrentWriteAccess != 0 && (mCurrentReadAccess & readAccessType) != readAccessType;
*barrierSrcOut = mCurrentWriteAccess;
*barrierDstOut = readAccessType;
mCurrentReadAccess |= readAccessType;
return needsBarrier;
}
bool needsOnWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut);
angle::Result initializeNonZeroMemory(Context *context, VkDeviceSize size);
// Vulkan objects.
......@@ -672,6 +665,8 @@ class BufferHelper final : public Resource
// For memory barriers.
VkFlags mCurrentWriteAccess;
VkFlags mCurrentReadAccess;
VkPipelineStageFlags mCurrentWriteStages;
VkPipelineStageFlags mCurrentReadStages;
};
// Imagine an image going through a few layout transitions:
......
......@@ -696,6 +696,13 @@ constexpr gl::ShaderMap<VkShaderStageFlagBits> kShaderStageMap = {
{gl::ShaderType::Compute, VK_SHADER_STAGE_COMPUTE_BIT},
};
constexpr gl::ShaderMap<VkPipelineStageFlagBits> kPipelineStageShaderMap = {
{gl::ShaderType::Vertex, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
{gl::ShaderType::Fragment, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
{gl::ShaderType::Geometry, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
{gl::ShaderType::Compute, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
};
void GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset);
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
VkImageType GetImageType(gl::TextureType textureType);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment