Vulkan: Simplify image read barrier necessity check

RAW hazards were being tested for if the layouts were identical, but
that's impossible.

Bug: angleproject:4911
Change-Id: I73f568b1df2cbffe943217e19b115561e48a56c9
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2370862
Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Charlie Lao <cclao@google.com>
This commit is contained in:
Shahbaz Youssefi
2020-08-22 23:52:51 -04:00
committed by Commit Bot
parent f9a062c975
commit 7bce5194d1
4 changed files with 18 additions and 17 deletions

View File

@@ -4444,8 +4444,17 @@ angle::Result ContextVk::onImageRead(VkImageAspectFlags aspectFlags,
ASSERT(!image->isReleasedToExternal());
ASSERT(image->getImageSerial().valid());
// Layout transitions for images used in the render pass are handled especially. This function
// is only called when the image is used outside the render pass. As such, if the image is used
// inside the render pass, its layout is necessarily different from imageLayout, and thus a
// layout transition is necessary (and the render pass has to break).
ASSERT(image->isReadBarrierNecessary(imageLayout) ||
!(mRenderPassCommands->started() && mRenderPassCommands->usesImageInRenderPass(*image)));
// Note that different read methods are not compatible. A shader read uses a different layout
// than a transfer read. So we cannot support simultaneous read usage as easily as for Buffers.
// TODO: Don't close the render pass if the image was only used read-only in the render pass.
// http://anglebug.com/4984
ANGLE_TRY(endRenderPassIfImageUsed(*image));
image->recordReadBarrier(aspectFlags, imageLayout,

View File

@@ -1194,7 +1194,7 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
ANGLE_TRY(drawOverlay(contextVk, &image));
}
// This does nothing if it already in the requested layout
// This does nothing if it's already in the requested layout
image.image.recordReadBarrier(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::Present,
commandBuffer);

View File

@@ -692,7 +692,7 @@ void CommandBufferHelper::imageRead(ResourceUseList *resourceUseList,
if (mIsRenderPassCommandBuffer)
{
// As noted in the header we don't support multiple layouts reads for Images.
// As noted in the header we don't support multiple read layouts for Images.
// We allow duplicate uses in the RP to accomodate for normal GL sampler usage.
if (!usesImageInRenderPass(*image))
{
@@ -720,7 +720,7 @@ void CommandBufferHelper::imageWrite(ResourceUseList *resourceUseList,
if (mIsRenderPassCommandBuffer)
{
// When used as a storage buffer we allow for aliased writes.
// When used as a storage image we allow for aliased writes.
if (aliasingMode == AliasingMode::Disallowed)
{
ASSERT(!usesImageInRenderPass(*image));
@@ -3373,19 +3373,6 @@ bool ImageHelper::isDepthOrStencil() const
return mFormat->actualImageFormat().hasDepthOrStencilBits();
}
bool ImageHelper::isReadBarrierNecessary(ImageLayout newLayout) const
{
// If transitioning to a different layout, we need always need a barrier.
if (mCurrentLayout != newLayout)
{
return true;
}
// RAW (read-after-write) hazards always requires a memory barrier.
const ImageMemoryBarrierData &layoutData = kImageMemoryBarrierData[mCurrentLayout];
return layoutData.type == BarrierType::Write;
}
void ImageHelper::changeLayoutAndQueue(VkImageAspectFlags aspectMask,
ImageLayout newLayout,
uint32_t newQueueFamilyIndex,

View File

@@ -1432,7 +1432,12 @@ class ImageHelper final : public Resource, public angle::Subject
}
// This function can be used to prevent issuing redundant layout transition commands.
bool isReadBarrierNecessary(ImageLayout newLayout) const;
bool isReadBarrierNecessary(ImageLayout newLayout) const
{
// If transitioning to a different layout, we always need a barrier. Otherwise RAR
// (read-after-read) is not a hazard and doesn't require a barrier.
return mCurrentLayout != newLayout;
}
void recordReadBarrier(VkImageAspectFlags aspectMask,
ImageLayout newLayout,