Commit 234ea5b1 by Charlie Lao Committed by Commit Bot

Vulkan: Wrap barrier data into PipelineBarrier class

This is preparation CL without introducing any functional change. This Cl wraps barrier data into its own class and put necessary data structures in place. It still uses one vkCmdPipelineBarrier call. Bug: b/155341891 Change-Id: If9c70d24873bd9b89e598acfba2eeee364f0b6c1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2185149 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent dae210e6
...@@ -1059,7 +1059,7 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context, ...@@ -1059,7 +1059,7 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
GLsizei instanceCount = 1; GLsizei instanceCount = 1;
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, indirectBuffer); vk::PipelineStage::DrawIndirect, indirectBuffer);
ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount, ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount,
gl::DrawElementsType::InvalidEnum, nullptr, dirtyBitMask, gl::DrawElementsType::InvalidEnum, nullptr, dirtyBitMask,
...@@ -1372,7 +1372,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(const gl::Context *con ...@@ -1372,7 +1372,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(const gl::Context *con
if (arrayBuffer) if (arrayBuffer)
{ {
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, arrayBuffer); vk::PipelineStage::VertexInput, arrayBuffer);
} }
} }
...@@ -1390,7 +1390,7 @@ angle::Result ContextVk::handleDirtyGraphicsIndexBuffer(const gl::Context *conte ...@@ -1390,7 +1390,7 @@ angle::Result ContextVk::handleDirtyGraphicsIndexBuffer(const gl::Context *conte
getVkIndexType(mCurrentDrawElementsType)); getVkIndexType(mCurrentDrawElementsType));
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT, mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, elementArrayBuffer); vk::PipelineStage::VertexInput, elementArrayBuffer);
return angle::Result::Continue; return angle::Result::Continue;
} }
...@@ -1450,7 +1450,7 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation( ...@@ -1450,7 +1450,7 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation(
vk::BufferHelper &bufferHelper = bufferVk->getBuffer(); vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
mRenderPassCommands.bufferWrite(&mResourceUseList, VK_ACCESS_SHADER_WRITE_BIT, mRenderPassCommands.bufferWrite(&mResourceUseList, VK_ACCESS_SHADER_WRITE_BIT,
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, &bufferHelper); vk::PipelineStage::VertexShader, &bufferHelper);
} }
// TODO(http://anglebug.com/3570): Need to update to handle Program Pipelines // TODO(http://anglebug.com/3570): Need to update to handle Program Pipelines
...@@ -1489,9 +1489,9 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension( ...@@ -1489,9 +1489,9 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension(
vk::BufferHelper &bufferHelper = bufferVk->getBuffer(); vk::BufferHelper &bufferHelper = bufferVk->getBuffer();
bufferHandles[bufferIndex] = bufferHelper.getBuffer().getHandle(); bufferHandles[bufferIndex] = bufferHelper.getBuffer().getHandle();
mRenderPassCommands.bufferWrite( mRenderPassCommands.bufferWrite(&mResourceUseList,
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT, &bufferHelper); vk::PipelineStage::TransformFeedback, &bufferHelper);
} }
const TransformFeedbackBufferRange &xfbBufferRangeExtension = const TransformFeedbackBufferRange &xfbBufferRangeExtension =
...@@ -2158,7 +2158,7 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context, ...@@ -2158,7 +2158,7 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any()) if (mVertexArray->getStreamingVertexAttribsMask().any())
{ {
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, currentIndirectBuf); vk::PipelineStage::DrawIndirect, currentIndirectBuf);
// We have instanced vertex attributes that need to be emulated for Vulkan. // 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. // invalidate any cache and map the buffer so that we can read the indirect data.
...@@ -2212,7 +2212,7 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context, ...@@ -2212,7 +2212,7 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
if (mVertexArray->getStreamingVertexAttribsMask().any()) if (mVertexArray->getStreamingVertexAttribsMask().any())
{ {
mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, mRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, currentIndirectBuf); vk::PipelineStage::DrawIndirect, currentIndirectBuf);
// We have instanced vertex attributes that need to be emulated for Vulkan. // 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. // invalidate any cache and map the buffer so that we can read the indirect data.
...@@ -3249,7 +3249,7 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi ...@@ -3249,7 +3249,7 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi
gl::Buffer *glBuffer = getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect); gl::Buffer *glBuffer = getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
vk::BufferHelper &buffer = vk::GetImpl(glBuffer)->getBuffer(); vk::BufferHelper &buffer = vk::GetImpl(glBuffer)->getBuffer();
mOutsideRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, mOutsideRenderPassCommands.bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &buffer); vk::PipelineStage::DrawIndirect, &buffer);
commandBuffer->dispatchIndirect(buffer.getBuffer(), indirect); commandBuffer->dispatchIndirect(buffer.getBuffer(), indirect);
...@@ -4039,7 +4039,7 @@ bool ContextVk::shouldUseOldRewriteStructSamplers() const ...@@ -4039,7 +4039,7 @@ bool ContextVk::shouldUseOldRewriteStructSamplers() const
} }
angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType,
VkPipelineStageFlags readStage, vk::PipelineStage readStage,
vk::BufferHelper *buffer) vk::BufferHelper *buffer)
{ {
ANGLE_TRY(endRenderPass()); ANGLE_TRY(endRenderPass());
...@@ -4055,7 +4055,7 @@ angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType, ...@@ -4055,7 +4055,7 @@ angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType,
} }
angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType, angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage, vk::PipelineStage writeStage,
vk::BufferHelper *buffer) vk::BufferHelper *buffer)
{ {
ANGLE_TRY(endRenderPass()); ANGLE_TRY(endRenderPass());
......
...@@ -464,21 +464,19 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -464,21 +464,19 @@ class ContextVk : public ContextImpl, public vk::Context
angle::Result onBufferTransferRead(vk::BufferHelper *buffer) angle::Result onBufferTransferRead(vk::BufferHelper *buffer)
{ {
return onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, buffer); return onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, vk::PipelineStage::Transfer, buffer);
} }
angle::Result onBufferTransferWrite(vk::BufferHelper *buffer) angle::Result onBufferTransferWrite(vk::BufferHelper *buffer)
{ {
return onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, buffer); return onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, vk::PipelineStage::Transfer, buffer);
} }
angle::Result onBufferComputeShaderRead(vk::BufferHelper *buffer) angle::Result onBufferComputeShaderRead(vk::BufferHelper *buffer)
{ {
return onBufferRead(VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, return onBufferRead(VK_ACCESS_SHADER_READ_BIT, vk::PipelineStage::ComputeShader, buffer);
buffer);
} }
angle::Result onBufferComputeShaderWrite(vk::BufferHelper *buffer) angle::Result onBufferComputeShaderWrite(vk::BufferHelper *buffer)
{ {
return onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, return onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, vk::PipelineStage::ComputeShader, buffer);
buffer);
} }
angle::Result onImageRead(VkImageAspectFlags aspectFlags, angle::Result onImageRead(VkImageAspectFlags aspectFlags,
...@@ -799,10 +797,10 @@ class ContextVk : public ContextImpl, public vk::Context ...@@ -799,10 +797,10 @@ class ContextVk : public ContextImpl, public vk::Context
ANGLE_INLINE void onRenderPassFinished() { mRenderPassCommandBuffer = nullptr; } ANGLE_INLINE void onRenderPassFinished() { mRenderPassCommandBuffer = nullptr; }
angle::Result onBufferRead(VkAccessFlags readAccessType, angle::Result onBufferRead(VkAccessFlags readAccessType,
VkPipelineStageFlags readStage, vk::PipelineStage readStage,
vk::BufferHelper *buffer); vk::BufferHelper *buffer);
angle::Result onBufferWrite(VkAccessFlags writeAccessType, angle::Result onBufferWrite(VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage, vk::PipelineStage writeStage,
vk::BufferHelper *buffer); vk::BufferHelper *buffer);
void initIndexTypeMap(); void initIndexTypeMap();
......
...@@ -22,6 +22,13 @@ namespace rx ...@@ -22,6 +22,13 @@ namespace rx
{ {
namespace namespace
{ {
constexpr gl::ShaderMap<vk::PipelineStage> kPipelineStageShaderMap = {
{gl::ShaderType::Vertex, vk::PipelineStage::VertexShader},
{gl::ShaderType::Fragment, vk::PipelineStage::FragmentShader},
{gl::ShaderType::Geometry, vk::PipelineStage::GeometryShader},
{gl::ShaderType::Compute, vk::PipelineStage::ComputeShader},
};
VkDeviceSize GetShaderBufferBindingSize(const gl::OffsetBindingPointer<gl::Buffer> &bufferBinding) VkDeviceSize GetShaderBufferBindingSize(const gl::OffsetBindingPointer<gl::Buffer> &bufferBinding)
{ {
if (bufferBinding.getSize() != 0) if (bufferBinding.getSize() != 0)
...@@ -942,14 +949,12 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk, ...@@ -942,14 +949,12 @@ void ProgramExecutableVk::updateBuffersDescriptorSet(ContextVk *contextVk,
// We set the SHADER_READ_BIT to be conservative. // We set the SHADER_READ_BIT to be conservative.
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT; VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
commandBufferHelper->bufferWrite(resourceUseList, accessFlags, commandBufferHelper->bufferWrite(resourceUseList, accessFlags,
gl_vk::kPipelineStageShaderMap[shaderType], kPipelineStageShaderMap[shaderType], &bufferHelper);
&bufferHelper);
} }
else else
{ {
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT, commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
gl_vk::kPipelineStageShaderMap[shaderType], kPipelineStageShaderMap[shaderType], &bufferHelper);
&bufferHelper);
} }
++writeCount; ++writeCount;
...@@ -1022,7 +1027,7 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet( ...@@ -1022,7 +1027,7 @@ void ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
// We set SHADER_READ_BIT to be conservative. // We set SHADER_READ_BIT to be conservative.
commandBufferHelper->bufferWrite(resourceUseList, commandBufferHelper->bufferWrite(resourceUseList,
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
gl_vk::kPipelineStageShaderMap[shaderType], &bufferHelper); kPipelineStageShaderMap[shaderType], &bufferHelper);
writtenBindings.set(binding); writtenBindings.set(binding);
} }
......
...@@ -79,5 +79,5 @@ More implementation details can be found in the `doc` directory: ...@@ -79,5 +79,5 @@ More implementation details can be found in the `doc` directory:
[VkDevice]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDevice.html [VkDevice]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkDevice.html
[VkQueue]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkQueue.html [VkQueue]: https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkQueue.html
[CommandAPIs]: https://chromium.googlesource.com/angle/angle/+/aa09ca69e4173cb14261e39be3b7bdf56bbd3840/src/libANGLE/renderer/vulkan/ContextVk.h#579 [CommandAPIs]: https://chromium.googlesource.com/angle/angle/+/df31624eaf3df986a0bdf3f58a87b79b0cc8db5c/src/libANGLE/renderer/vulkan/ContextVk.h#620
...@@ -47,6 +47,22 @@ constexpr int kLineLoopDynamicIndirectBufferInitialSize = sizeof(VkDrawIndirectC ...@@ -47,6 +47,22 @@ constexpr int kLineLoopDynamicIndirectBufferInitialSize = sizeof(VkDrawIndirectC
// This is an arbitrary max. We can change this later if necessary. // This is an arbitrary max. We can change this later if necessary.
constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128; constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128;
constexpr angle::PackedEnumMap<PipelineStage, VkPipelineStageFlagBits> kPipelineStageFlagBitMap = {
{PipelineStage::TopOfPipe, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT},
{PipelineStage::DrawIndirect, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT},
{PipelineStage::VertexInput, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT},
{PipelineStage::VertexShader, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT},
{PipelineStage::GeometryShader, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT},
{PipelineStage::TransformFeedback, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT},
{PipelineStage::EarlyFragmentTest, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT},
{PipelineStage::FragmentShader, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT},
{PipelineStage::LateFragmentTest, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT},
{PipelineStage::ColorAttachmentOutput, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT},
{PipelineStage::ComputeShader, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT},
{PipelineStage::Transfer, VK_PIPELINE_STAGE_TRANSFER_BIT},
{PipelineStage::BottomOfPipe, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT},
{PipelineStage::Host, VK_PIPELINE_STAGE_HOST_BIT}};
struct ImageMemoryBarrierData struct ImageMemoryBarrierData
{ {
// The Vk layout corresponding to the ImageLayout key. // The Vk layout corresponding to the ImageLayout key.
...@@ -455,12 +471,7 @@ VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout) ...@@ -455,12 +471,7 @@ VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout)
// CommandBufferHelper implementation. // CommandBufferHelper implementation.
CommandBufferHelper::CommandBufferHelper(bool hasRenderPass) CommandBufferHelper::CommandBufferHelper(bool hasRenderPass)
: mImageBarrierSrcStageMask(0), : mPipelineBarrier(),
mImageBarrierDstStageMask(0),
mGlobalMemoryBarrierSrcAccess(0),
mGlobalMemoryBarrierDstAccess(0),
mGlobalMemoryBarrierSrcStages(0),
mGlobalMemoryBarrierDstStages(0),
mCounter(0), mCounter(0),
mClearValues{}, mClearValues{},
mRenderPassStarted(false), mRenderPassStarted(false),
...@@ -482,34 +493,29 @@ void CommandBufferHelper::initialize(angle::PoolAllocator *poolAllocator) ...@@ -482,34 +493,29 @@ void CommandBufferHelper::initialize(angle::PoolAllocator *poolAllocator)
void CommandBufferHelper::bufferRead(vk::ResourceUseList *resourceUseList, void CommandBufferHelper::bufferRead(vk::ResourceUseList *resourceUseList,
VkAccessFlags readAccessType, VkAccessFlags readAccessType,
VkPipelineStageFlags readStage, vk::PipelineStage readStage,
vk::BufferHelper *buffer) vk::BufferHelper *buffer)
{ {
buffer->retain(resourceUseList); buffer->retain(resourceUseList);
buffer->updateReadBarrier(readAccessType, &mGlobalMemoryBarrierSrcAccess, VkPipelineStageFlagBits stageBits = kPipelineStageFlagBitMap[readStage];
&mGlobalMemoryBarrierDstAccess, readStage, buffer->updateReadBarrier(readAccessType, stageBits, &mPipelineBarrier);
&mGlobalMemoryBarrierSrcStages, &mGlobalMemoryBarrierDstStages);
} }
void CommandBufferHelper::bufferWrite(vk::ResourceUseList *resourceUseList, void CommandBufferHelper::bufferWrite(vk::ResourceUseList *resourceUseList,
VkAccessFlags writeAccessType, VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage, vk::PipelineStage writeStage,
vk::BufferHelper *buffer) vk::BufferHelper *buffer)
{ {
buffer->retain(resourceUseList); buffer->retain(resourceUseList);
buffer->updateWriteBarrier(writeAccessType, &mGlobalMemoryBarrierSrcAccess, VkPipelineStageFlagBits stageBits = kPipelineStageFlagBitMap[writeStage];
&mGlobalMemoryBarrierDstAccess, writeStage, buffer->updateWriteBarrier(writeAccessType, stageBits, &mPipelineBarrier);
&mGlobalMemoryBarrierSrcStages, &mGlobalMemoryBarrierDstStages);
} }
void CommandBufferHelper::imageBarrier(VkPipelineStageFlags srcStageMask, void CommandBufferHelper::imageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask, VkPipelineStageFlags dstStageMask,
const VkImageMemoryBarrier &imageMemoryBarrier) const VkImageMemoryBarrier &imageMemoryBarrier)
{ {
ASSERT(imageMemoryBarrier.pNext == nullptr); mPipelineBarrier.mergeImageBarrier(srcStageMask, dstStageMask, imageMemoryBarrier);
mImageBarrierSrcStageMask |= srcStageMask;
mImageBarrierDstStageMask |= dstStageMask;
mImageMemoryBarriers.push_back(imageMemoryBarrier);
} }
void CommandBufferHelper::imageRead(vk::ResourceUseList *resourceUseList, void CommandBufferHelper::imageRead(vk::ResourceUseList *resourceUseList,
...@@ -535,41 +541,7 @@ void CommandBufferHelper::imageWrite(vk::ResourceUseList *resourceUseList, ...@@ -535,41 +541,7 @@ void CommandBufferHelper::imageWrite(vk::ResourceUseList *resourceUseList,
void CommandBufferHelper::executeBarriers(vk::PrimaryCommandBuffer *primary) void CommandBufferHelper::executeBarriers(vk::PrimaryCommandBuffer *primary)
{ {
if (mImageMemoryBarriers.empty() && mGlobalMemoryBarrierSrcAccess == 0) mPipelineBarrier.writeCommand(primary);
{
return;
}
VkPipelineStageFlags srcStages = 0;
VkPipelineStageFlags dstStages = 0;
VkMemoryBarrier memoryBarrier = {};
uint32_t memoryBarrierCount = 0;
if (mGlobalMemoryBarrierSrcAccess != 0)
{
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = mGlobalMemoryBarrierSrcAccess;
memoryBarrier.dstAccessMask = mGlobalMemoryBarrierDstAccess;
memoryBarrierCount++;
srcStages |= mGlobalMemoryBarrierSrcStages;
dstStages |= mGlobalMemoryBarrierDstStages;
mGlobalMemoryBarrierSrcAccess = 0;
mGlobalMemoryBarrierDstAccess = 0;
mGlobalMemoryBarrierSrcStages = 0;
mGlobalMemoryBarrierDstStages = 0;
}
srcStages |= mImageBarrierSrcStageMask;
dstStages |= mImageBarrierDstStageMask;
primary->pipelineBarrier(srcStages, dstStages, 0, memoryBarrierCount, &memoryBarrier, 0,
nullptr, static_cast<uint32_t>(mImageMemoryBarriers.size()),
mImageMemoryBarriers.data());
mImageMemoryBarriers.clear();
mImageBarrierSrcStageMask = 0;
mImageBarrierDstStageMask = 0;
} }
void CommandBufferHelper::beginRenderPass(const vk::Framebuffer &framebuffer, void CommandBufferHelper::beginRenderPass(const vk::Framebuffer &framebuffer,
...@@ -705,11 +677,11 @@ char GetStoreOpShorthand(uint32_t storeOp) ...@@ -705,11 +677,11 @@ char GetStoreOpShorthand(uint32_t storeOp)
void CommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk) void CommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk)
{ {
std::ostringstream out; std::ostringstream out;
if (mGlobalMemoryBarrierSrcAccess != 0 || mGlobalMemoryBarrierDstAccess != 0)
{ out << "Memory Barrier: ";
out << "Memory Barrier Src: 0x" << std::hex << mGlobalMemoryBarrierSrcAccess mPipelineBarrier.addDiagnosticsString(out);
<< " &rarr; Dst: 0x" << std::hex << mGlobalMemoryBarrierDstAccess << "\\l"; out << "\\l";
}
if (mIsRenderPassCommandBuffer) if (mIsRenderPassCommandBuffer)
{ {
size_t attachmentCount = mRenderPassDesc.attachmentCount(); size_t attachmentCount = mRenderPassDesc.attachmentCount();
...@@ -2029,6 +2001,17 @@ void LineLoopHelper::Draw(uint32_t count, uint32_t baseVertex, CommandBuffer *co ...@@ -2029,6 +2001,17 @@ void LineLoopHelper::Draw(uint32_t count, uint32_t baseVertex, CommandBuffer *co
commandBuffer->drawIndexedBaseVertex(count, baseVertex); commandBuffer->drawIndexedBaseVertex(count, baseVertex);
} }
// PipelineBarrier implementation.
void PipelineBarrier::addDiagnosticsString(std::ostringstream &out) const
{
if (mMemoryBarrierSrcAccess != 0 || mMemoryBarrierDstAccess != 0)
{
out << "{"
<< "Src: 0x" << std::hex << mMemoryBarrierSrcAccess << " -> Dst: 0x" << std::hex
<< mMemoryBarrierDstAccess << "}";
}
}
// BufferHelper implementation. // BufferHelper implementation.
BufferHelper::BufferHelper() BufferHelper::BufferHelper()
: mMemoryPropertyFlags{}, : mMemoryPropertyFlags{},
...@@ -2289,21 +2272,16 @@ bool BufferHelper::canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeA ...@@ -2289,21 +2272,16 @@ bool BufferHelper::canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeA
} }
void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType, void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags readStage, VkPipelineStageFlags readStage,
VkPipelineStageFlags *barrierSrcStageOut, PipelineBarrier *barrier)
VkPipelineStageFlags *barrierDstStageOut)
{ {
// If there was a prior write and we are making a read that is either a new access type or from // 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 // a new stage, we need a barrier
if (mCurrentWriteAccess != 0 && (((mCurrentReadAccess & readAccessType) != readAccessType) || if (mCurrentWriteAccess != 0 && (((mCurrentReadAccess & readAccessType) != readAccessType) ||
((mCurrentReadStages & readStage) != readStage))) ((mCurrentReadStages & readStage) != readStage)))
{ {
*barrierSrcOut |= mCurrentWriteAccess; barrier->mergeMemoryBarrier(mCurrentWriteStages, readStage, mCurrentWriteAccess,
*barrierDstOut |= readAccessType; readAccessType);
*barrierSrcStageOut |= mCurrentWriteStages;
*barrierDstStageOut |= readStage;
} }
// Accumulate new read usage. // Accumulate new read usage.
...@@ -2312,11 +2290,8 @@ void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType, ...@@ -2312,11 +2290,8 @@ void BufferHelper::updateReadBarrier(VkAccessFlags readAccessType,
} }
void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType, void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags writeStage, VkPipelineStageFlags writeStage,
VkPipelineStageFlags *barrierSrcStageOut, PipelineBarrier *barrier)
VkPipelineStageFlags *barrierDstStageOut)
{ {
// We don't need to check mCurrentReadStages here since if it is not zero, mCurrentReadAccess // 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. // must not be zero as well. stage is finer grain than accessType.
...@@ -2324,10 +2299,8 @@ void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType, ...@@ -2324,10 +2299,8 @@ void BufferHelper::updateWriteBarrier(VkAccessFlags writeAccessType,
(mCurrentReadStages && mCurrentReadAccess)); (mCurrentReadStages && mCurrentReadAccess));
if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0) if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0)
{ {
*barrierSrcOut |= mCurrentWriteAccess; barrier->mergeMemoryBarrier(mCurrentWriteStages | mCurrentReadStages, writeStage,
*barrierDstOut |= writeAccessType; mCurrentWriteAccess, writeAccessType);
*barrierSrcStageOut |= mCurrentWriteStages | mCurrentReadStages;
*barrierDstStageOut |= writeStage;
} }
// Reset usages on the new write. // Reset usages on the new write.
......
...@@ -552,6 +552,128 @@ class LineLoopHelper final : angle::NonCopyable ...@@ -552,6 +552,128 @@ class LineLoopHelper final : angle::NonCopyable
DynamicBuffer mDynamicIndirectBuffer; DynamicBuffer mDynamicIndirectBuffer;
}; };
// This defines enum for VkPipelineStageFlagBits so that we can use it to compare and index into
// array.
enum class PipelineStage : uint16_t
{
// Bellow are ordered based on Graphics Pipeline Stages
TopOfPipe = 0,
DrawIndirect = 1,
VertexInput = 2,
VertexShader = 3,
GeometryShader = 4,
TransformFeedback = 5,
EarlyFragmentTest = 6,
FragmentShader = 7,
LateFragmentTest = 8,
ColorAttachmentOutput = 9,
// Compute specific pipeline Stage
ComputeShader = 10,
// Transfer specific pipeline Stage
Transfer = 11,
BottomOfPipe = 12,
// Host specific pipeline stage
Host = 13,
InvalidEnum = 14,
EnumCount = InvalidEnum,
};
using PipelineStagesMask = angle::PackedEnumBitSet<PipelineStage, uint16_t>;
// This wraps data and API for vkCmdPipelineBarrier call
class PipelineBarrier : angle::NonCopyable
{
public:
PipelineBarrier()
: mSrcStageMask(0),
mDstStageMask(0),
mMemoryBarrierSrcAccess(0),
mMemoryBarrierDstAccess(0),
mImageMemoryBarriers()
{}
~PipelineBarrier() = default;
bool isEmpty() const { return mImageMemoryBarriers.empty() && mMemoryBarrierSrcAccess == 0; }
void writeCommand(PrimaryCommandBuffer *primary)
{
if (isEmpty())
{
return;
}
// Issue vkCmdPipelineBarrier call
VkMemoryBarrier memoryBarrier = {};
uint32_t memoryBarrierCount = 0;
if (mMemoryBarrierSrcAccess != 0)
{
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = mMemoryBarrierSrcAccess;
memoryBarrier.dstAccessMask = mMemoryBarrierDstAccess;
memoryBarrierCount++;
}
primary->pipelineBarrier(
mSrcStageMask, mDstStageMask, 0, memoryBarrierCount, &memoryBarrier, 0, nullptr,
static_cast<uint32_t>(mImageMemoryBarriers.size()), mImageMemoryBarriers.data());
reset();
}
// merge two barriers into one
void merge(const PipelineBarrier &other)
{
mSrcStageMask |= other.mSrcStageMask;
mDstStageMask |= other.mDstStageMask;
mMemoryBarrierSrcAccess |= other.mMemoryBarrierSrcAccess;
mMemoryBarrierDstAccess |= other.mMemoryBarrierDstAccess;
mImageMemoryBarriers.insert(mImageMemoryBarriers.end(), other.mImageMemoryBarriers.begin(),
other.mImageMemoryBarriers.end());
}
void mergeMemoryBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
VkFlags srcAccess,
VkFlags dstAccess)
{
mSrcStageMask |= srcStageMask;
mDstStageMask |= dstStageMask;
mMemoryBarrierSrcAccess |= srcAccess;
mMemoryBarrierDstAccess |= dstAccess;
}
void mergeImageBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
const VkImageMemoryBarrier &imageMemoryBarrier)
{
ASSERT(imageMemoryBarrier.pNext == nullptr);
mSrcStageMask |= srcStageMask;
mDstStageMask |= dstStageMask;
mImageMemoryBarriers.push_back(imageMemoryBarrier);
}
void reset()
{
mSrcStageMask = 0;
mDstStageMask = 0;
mMemoryBarrierSrcAccess = 0;
mMemoryBarrierDstAccess = 0;
mImageMemoryBarriers.clear();
}
void addDiagnosticsString(std::ostringstream &out) const;
private:
VkPipelineStageFlags mSrcStageMask;
VkPipelineStageFlags mDstStageMask;
VkFlags mMemoryBarrierSrcAccess;
VkFlags mMemoryBarrierDstAccess;
std::vector<VkImageMemoryBarrier> mImageMemoryBarriers;
};
using PipelineBarrierArray = angle::PackedEnumMap<PipelineStage, PipelineBarrier>;
class FramebufferHelper; class FramebufferHelper;
class BufferHelper final : public Resource class BufferHelper final : public Resource
...@@ -654,18 +776,12 @@ class BufferHelper final : public Resource ...@@ -654,18 +776,12 @@ class BufferHelper final : public Resource
bool canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeAccessType); bool canAccumulateWrite(ContextVk *contextVk, VkAccessFlags writeAccessType);
void updateReadBarrier(VkAccessFlags readAccessType, void updateReadBarrier(VkAccessFlags readAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags readStage, VkPipelineStageFlags readStage,
VkPipelineStageFlags *barrierSrcStageOut, PipelineBarrier *barrier);
VkPipelineStageFlags *barrierDstStageOut);
void updateWriteBarrier(VkAccessFlags writeAccessType, void updateWriteBarrier(VkAccessFlags writeAccessType,
VkAccessFlags *barrierSrcOut,
VkAccessFlags *barrierDstOut,
VkPipelineStageFlags writeStage, VkPipelineStageFlags writeStage,
VkPipelineStageFlags *barrierSrcStageOut, PipelineBarrier *barrier);
VkPipelineStageFlags *barrierDstStageOut);
private: private:
angle::Result mapImpl(ContextVk *contextVk); angle::Result mapImpl(ContextVk *contextVk);
...@@ -709,11 +825,11 @@ struct CommandBufferHelper : angle::NonCopyable ...@@ -709,11 +825,11 @@ struct CommandBufferHelper : angle::NonCopyable
void bufferRead(vk::ResourceUseList *resourceUseList, void bufferRead(vk::ResourceUseList *resourceUseList,
VkAccessFlags readAccessType, VkAccessFlags readAccessType,
VkPipelineStageFlags readStage, vk::PipelineStage readStage,
vk::BufferHelper *buffer); vk::BufferHelper *buffer);
void bufferWrite(vk::ResourceUseList *resourceUseList, void bufferWrite(vk::ResourceUseList *resourceUseList,
VkAccessFlags writeAccessType, VkAccessFlags writeAccessType,
VkPipelineStageFlags writeStage, vk::PipelineStage writeStage,
vk::BufferHelper *buffer); vk::BufferHelper *buffer);
void imageRead(vk::ResourceUseList *resourceUseList, void imageRead(vk::ResourceUseList *resourceUseList,
...@@ -813,13 +929,7 @@ struct CommandBufferHelper : angle::NonCopyable ...@@ -813,13 +929,7 @@ struct CommandBufferHelper : angle::NonCopyable
void addCommandDiagnostics(ContextVk *contextVk); void addCommandDiagnostics(ContextVk *contextVk);
// General state (non-renderPass related) // General state (non-renderPass related)
VkPipelineStageFlags mImageBarrierSrcStageMask; vk::PipelineBarrier mPipelineBarrier;
VkPipelineStageFlags mImageBarrierDstStageMask;
std::vector<VkImageMemoryBarrier> mImageMemoryBarriers;
VkFlags mGlobalMemoryBarrierSrcAccess;
VkFlags mGlobalMemoryBarrierDstAccess;
VkPipelineStageFlags mGlobalMemoryBarrierSrcStages;
VkPipelineStageFlags mGlobalMemoryBarrierDstStages;
vk::CommandBuffer mCommandBuffer; vk::CommandBuffer mCommandBuffer;
// RenderPass state // RenderPass state
......
...@@ -730,13 +730,6 @@ constexpr gl::ShaderMap<VkShaderStageFlagBits> kShaderStageMap = { ...@@ -730,13 +730,6 @@ constexpr gl::ShaderMap<VkShaderStageFlagBits> kShaderStageMap = {
{gl::ShaderType::Compute, VK_SHADER_STAGE_COMPUTE_BIT}, {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 GetOffset(const gl::Offset &glOffset, VkOffset3D *vkOffset);
void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent); void GetExtent(const gl::Extents &glExtent, VkExtent3D *vkExtent);
VkImageType GetImageType(gl::TextureType textureType); 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