Commit fd3b8faf by Charlie Lao Committed by Commit Bot

Vulkan: Split fragment shader from ColorAttachmentAndAllShadersRead

Even though it is not common usage case that the same texture is used as attachment and texture, but aztec ruins is using it. And earlier version of gfxbench's T-Rex also running into this. So performance is still important. This CL splits the texture from fragment shader usage case out so we can have lighter barrier. Bug: angleproject:5780 Change-Id: Ifdcbfe24488fdac62826c5af6ecfbb05f87c0499 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2795269 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 259ead0d
...@@ -1487,13 +1487,6 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl( ...@@ -1487,13 +1487,6 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(
// using specialized barriers without breaking the RenderPass. // using specialized barriers without breaking the RenderPass.
textureLayout = vk::ImageLayout::DepthStencilReadOnly; textureLayout = vk::ImageLayout::DepthStencilReadOnly;
} }
else if (image.hasRenderPassUseFlag(vk::RenderPassUsage::RenderTargetAttachment))
{
// Right now we set this flag only when RenderTargetAttachment is set since we do not
// track all textures in the renderpass.
image.setRenderPassUsageFlag(vk::RenderPassUsage::TextureSampler);
textureLayout = vk::ImageLayout::ColorAttachmentAndShaderRead;
}
else else
{ {
gl::ShaderBitSet remainingShaderBits = gl::ShaderBitSet remainingShaderBits =
...@@ -1503,22 +1496,41 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl( ...@@ -1503,22 +1496,41 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(
gl::ShaderType lastShader = remainingShaderBits.last(); gl::ShaderType lastShader = remainingShaderBits.last();
remainingShaderBits.reset(firstShader); remainingShaderBits.reset(firstShader);
remainingShaderBits.reset(lastShader); remainingShaderBits.reset(lastShader);
// We barrier against either:
// - Vertex only if (image.hasRenderPassUseFlag(vk::RenderPassUsage::RenderTargetAttachment))
// - Fragment only
// - Pre-fragment only (vertex, geometry and tessellation together)
if (remainingShaderBits.any() || firstShader != lastShader)
{ {
textureLayout = lastShader == gl::ShaderType::Fragment // Right now we set this flag only when RenderTargetAttachment is set since we do
? vk::ImageLayout::AllGraphicsShadersReadOnly // not track all textures in the renderpass.
: vk::ImageLayout::PreFragmentShadersReadOnly; image.setRenderPassUsageFlag(vk::RenderPassUsage::TextureSampler);
if (firstShader == gl::ShaderType::Fragment)
{
textureLayout = vk::ImageLayout::ColorAttachmentAndFragmentShaderRead;
}
else
{
textureLayout = vk::ImageLayout::ColorAttachmentAndAllShadersRead;
}
} }
else else
{ {
textureLayout = kShaderReadOnlyImageLayouts[firstShader]; // We barrier against either:
// - Vertex only
// - Fragment only
// - Pre-fragment only (vertex, geometry and tessellation together)
if (remainingShaderBits.any() || firstShader != lastShader)
{
textureLayout = lastShader == gl::ShaderType::Fragment
? vk::ImageLayout::AllGraphicsShadersReadOnly
: vk::ImageLayout::PreFragmentShadersReadOnly;
}
else
{
textureLayout = kShaderReadOnlyImageLayouts[firstShader];
}
} }
} }
// Ensure the image is in read-only layout // Ensure the image is in the desired layout
commandBufferHelper->imageRead(this, image.getAspectFlags(), textureLayout, &image); commandBufferHelper->imageRead(this, image.getAspectFlags(), textureLayout, &image);
textureVk->retainImageViews(&mResourceUseList); textureVk->retainImageViews(&mResourceUseList);
......
...@@ -145,17 +145,33 @@ constexpr angle::PackedEnumMap<ImageLayout, ImageMemoryBarrierData> kImageMemory ...@@ -145,17 +145,33 @@ constexpr angle::PackedEnumMap<ImageLayout, ImageMemoryBarrierData> kImageMemory
}, },
}, },
{ {
ImageLayout::ColorAttachmentAndShaderRead, ImageLayout::ColorAttachmentAndFragmentShaderRead,
ImageMemoryBarrierData{ ImageMemoryBarrierData{
"ColorAttachmentAndShaderRead", "ColorAttachmentAndFragmentShaderRead",
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | kAllShadersPipelineStageFlags, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | kAllShadersPipelineStageFlags, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
// Transition to: all reads and writes must happen after barrier. // Transition to: all reads and writes must happen after barrier.
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
// Transition from: all writes must finish before barrier. // Transition from: all writes must finish before barrier.
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
ResourceAccess::Write, ResourceAccess::Write,
PipelineStage::FragmentShader,
},
},
{
ImageLayout::ColorAttachmentAndAllShadersRead,
ImageMemoryBarrierData{
"ColorAttachmentAndAllShadersRead",
VK_IMAGE_LAYOUT_GENERAL,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | kAllShadersPipelineStageFlags,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | kAllShadersPipelineStageFlags,
// Transition to: all reads must happen after barrier.
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT,
// Transition from: RAR and WAR don't need memory barrier.
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
ResourceAccess::Write,
// In case of multiple destination stages, We barrier the earliest stage
PipelineStage::VertexShader, PipelineStage::VertexShader,
}, },
}, },
...@@ -1239,7 +1255,8 @@ void CommandBufferHelper::finalizeColorImageLayout(Context *context, ...@@ -1239,7 +1255,8 @@ void CommandBufferHelper::finalizeColorImageLayout(Context *context,
{ {
// texture code already picked layout and inserted barrier // texture code already picked layout and inserted barrier
imageLayout = image->getCurrentImageLayout(); imageLayout = image->getCurrentImageLayout();
ASSERT(imageLayout == ImageLayout::ColorAttachmentAndShaderRead); ASSERT(imageLayout == ImageLayout::ColorAttachmentAndFragmentShaderRead ||
imageLayout == ImageLayout::ColorAttachmentAndAllShadersRead);
} }
else else
{ {
......
...@@ -1348,7 +1348,8 @@ enum class ImageLayout ...@@ -1348,7 +1348,8 @@ enum class ImageLayout
// Framebuffer attachment layouts are placed first, so they can fit in fewer bits in // Framebuffer attachment layouts are placed first, so they can fit in fewer bits in
// PackedAttachmentOpsDesc. // PackedAttachmentOpsDesc.
ColorAttachment, ColorAttachment,
ColorAttachmentAndShaderRead, ColorAttachmentAndFragmentShaderRead,
ColorAttachmentAndAllShadersRead,
DepthStencilReadOnly, DepthStencilReadOnly,
DepthStencilAttachment, DepthStencilAttachment,
DepthStencilResolveAttachment, DepthStencilResolveAttachment,
......
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