Commit 06b4fb92 by Charlie Lao Committed by Commit Bot

Vulkan: Fool proof packed attachment index to vulkan and from OpenGL

ANGLE packs FBO attachments from OpenGL and uses packed attachments to create VkFramebuffer and renderpass. When we use attachment index into the attachment array, we must be very careful to use packed index for vulkan objects. It is easy to make mistakes here and introduce hard to debug bugs. This CL defines a PackedAttachmentIndex class that uses that to index into vulkan attachments and pass around APIs so that compiler would catch the error when wrong index is used. This also introduces PackedClearValuesArray that stores clear value in packed attachment index so that it is impossible to mix it with ClearValuesArray that stores clear value in GL attachment index. Bug: b/167301719 Change-Id: I68680522c60beeb5096e5211eaef89da28c7097e Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2410366 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarTim Van Patten <timvp@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 39185acc
......@@ -2516,7 +2516,8 @@ void ContextVk::optimizeRenderPassForPresent(VkFramebuffer framebufferHandle)
// TODO(syoussefi): We currently don't store the layout of the resolve attachments, so once
// multisampled backbuffers are optimized to use resolve attachments, this information needs to
// be stored somewhere. http://anglebug.com/4836
mRenderPassCommands->updateRenderPassAttachmentFinalLayout(0, image.getCurrentImageLayout());
mRenderPassCommands->updateRenderPassAttachmentFinalLayout(vk::kAttachmentIndexZero,
image.getCurrentImageLayout());
}
gl::GraphicsResetStatus ContextVk::getResetStatus()
......@@ -4532,13 +4533,14 @@ angle::Result ContextVk::onImageWrite(VkImageAspectFlags aspectFlags,
return angle::Result::Continue;
}
angle::Result ContextVk::beginNewRenderPass(const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const uint32_t depthStencilAttachmentIndex,
const vk::ClearValuesArray &clearValues,
vk::CommandBuffer **commandBufferOut)
angle::Result ContextVk::beginNewRenderPass(
const vk::Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
const vk::PackedClearValuesArray &clearValues,
vk::CommandBuffer **commandBufferOut)
{
// Next end any currently outstanding renderPass
ANGLE_TRY(flushCommandsAndEndRenderPass());
......
......@@ -547,8 +547,8 @@ class ContextVk : public ContextImpl, public vk::Context
const gl::Rectangle &renderArea,
const vk::RenderPassDesc &renderPassDesc,
const vk::AttachmentOpsArray &renderPassAttachmentOps,
const uint32_t depthStencilAttachmentIndex,
const vk::ClearValuesArray &clearValues,
const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
const vk::PackedClearValuesArray &clearValues,
vk::CommandBuffer **commandBufferOut);
// Only returns true if we have a started RP and we've run setupDraw.
......
......@@ -1476,16 +1476,16 @@ angle::Result FramebufferVk::invalidateImpl(ContextVk *contextVk,
if (contextVk->hasStartedRenderPassWithFramebuffer(currentFramebuffer))
{
// Set the appropriate storeOp for attachments.
size_t attachmentIndexVk = 0;
vk::PackedAttachmentIndex colorIndexVk(0);
for (size_t colorIndexGL : mAttachedColorBufferMask)
{
if (mState.getEnabledDrawBuffers()[colorIndexGL] &&
invalidateColorBuffers.test(colorIndexGL))
{
contextVk->getStartedRenderPassCommands().invalidateRenderPassColorAttachment(
attachmentIndexVk);
colorIndexVk);
}
++attachmentIndexVk;
++colorIndexVk;
}
if (depthStencilRenderTarget)
......@@ -2118,7 +2118,7 @@ void FramebufferVk::clearWithLoadOp(ContextVk *contextVk,
ASSERT(commands.getCommandBuffer().empty());
uint32_t colorIndexVk = 0;
vk::PackedAttachmentIndex colorIndexVk(0);
for (size_t colorIndexGL : mAttachedColorBufferMask)
{
if (mState.getEnabledDrawBuffers()[colorIndexGL] && clearColorBuffers[colorIndexGL])
......@@ -2229,17 +2229,17 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
// Initialize RenderPass info.
vk::AttachmentOpsArray renderPassAttachmentOps;
vk::ClearValuesArray packedClearValues;
vk::PackedClearValuesArray packedClearValues;
// Color attachments.
const auto &colorRenderTargets = mRenderTargetCache.getColors();
uint32_t colorAttachmentCount = 0;
vk::PackedAttachmentIndex colorIndexVk(0);
for (size_t colorIndexGL : mAttachedColorBufferMask)
{
RenderTargetVk *colorRenderTarget = colorRenderTargets[colorIndexGL];
ASSERT(colorRenderTarget);
renderPassAttachmentOps.setLayouts(colorAttachmentCount, vk::ImageLayout::ColorAttachment,
renderPassAttachmentOps.setLayouts(colorIndexVk, vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
const VkAttachmentStoreOp storeOp = colorRenderTarget->isImageTransient()
......@@ -2248,23 +2248,22 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
if (mDeferredClears.test(colorIndexGL))
{
renderPassAttachmentOps.setOps(colorAttachmentCount, VK_ATTACHMENT_LOAD_OP_CLEAR,
storeOp);
packedClearValues.store(colorAttachmentCount, VK_IMAGE_ASPECT_COLOR_BIT,
renderPassAttachmentOps.setOps(colorIndexVk, VK_ATTACHMENT_LOAD_OP_CLEAR, storeOp);
packedClearValues.store(colorIndexVk, VK_IMAGE_ASPECT_COLOR_BIT,
mDeferredClears[colorIndexGL]);
mDeferredClears.reset(colorIndexGL);
}
else
{
renderPassAttachmentOps.setOps(colorAttachmentCount,
renderPassAttachmentOps.setOps(colorIndexVk,
colorRenderTarget->hasDefinedContent()
? VK_ATTACHMENT_LOAD_OP_LOAD
: VK_ATTACHMENT_LOAD_OP_DONT_CARE,
storeOp);
packedClearValues.store(colorAttachmentCount, VK_IMAGE_ASPECT_COLOR_BIT,
packedClearValues.store(colorIndexVk, VK_IMAGE_ASPECT_COLOR_BIT,
kUninitializedClearValue);
}
renderPassAttachmentOps.setStencilOps(colorAttachmentCount, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
renderPassAttachmentOps.setStencilOps(colorIndexVk, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
VK_ATTACHMENT_STORE_OP_DONT_CARE);
// If there's a resolve attachment, and loadOp needs to be LOAD, the multisampled attachment
......@@ -2281,21 +2280,21 @@ angle::Result FramebufferVk::startNewRenderPass(ContextVk *contextVk,
// always ever stays on a tiled renderer's tile and no memory backing is allocated for it.
// http://anglebug.com/4881
if (colorRenderTarget->hasResolveAttachment() && colorRenderTarget->isImageTransient() &&
renderPassAttachmentOps[colorAttachmentCount].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
renderPassAttachmentOps[colorIndexVk].loadOp == VK_ATTACHMENT_LOAD_OP_LOAD)
{
ANGLE_TRY(copyResolveToMultisampedAttachment(contextVk, colorRenderTarget));
}
colorAttachmentCount++;
++colorIndexVk;
}
// Depth/stencil attachment.
uint32_t depthStencilAttachmentIndex = vk::kInvalidAttachmentIndex;
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
vk::PackedAttachmentIndex depthStencilAttachmentIndex = vk::kAttachmentIndexInvalid;
RenderTargetVk *depthStencilRenderTarget = getDepthStencilRenderTarget();
if (depthStencilRenderTarget)
{
// depth stencil attachment always immediately follow color attachment
depthStencilAttachmentIndex = colorAttachmentCount;
depthStencilAttachmentIndex = colorIndexVk;
VkAttachmentLoadOp depthLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
......
......@@ -1120,14 +1120,15 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
ANGLE_VK_TRY(contextVk, framebuffer.init(contextVk->getDevice(), framebufferInfo));
vk::AttachmentOpsArray renderPassAttachmentOps;
vk::ClearValuesArray clearValues;
clearValues.store(0, VK_IMAGE_ASPECT_COLOR_BIT, {});
vk::PackedClearValuesArray clearValues;
clearValues.store(vk::kAttachmentIndexZero, VK_IMAGE_ASPECT_COLOR_BIT, {});
renderPassAttachmentOps.initWithLoadStore(0, vk::ImageLayout::ColorAttachment,
renderPassAttachmentOps.initWithLoadStore(vk::kAttachmentIndexZero,
vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
ANGLE_TRY(contextVk->beginNewRenderPass(framebuffer, renderArea, renderPassDesc,
renderPassAttachmentOps, vk::kInvalidAttachmentIndex,
renderPassAttachmentOps, vk::kAttachmentIndexInvalid,
clearValues, commandBufferOut));
contextVk->addGarbage(&framebuffer);
......
......@@ -243,8 +243,7 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
FramebufferAttachmentArray<VkAttachmentDescription> attachmentDescs;
// Pack color attachments
uint32_t colorAttachmentCount = 0;
uint32_t attachmentCount = 0;
PackedAttachmentIndex attachmentCount(0);
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
{
// Vulkan says:
......@@ -262,19 +261,18 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
continue;
}
uint32_t colorIndexVk = colorAttachmentCount++;
angle::FormatID formatID = desc[colorIndexGL];
ASSERT(formatID != angle::FormatID::NONE);
const vk::Format &format = context->getRenderer()->getFormat(formatID);
VkAttachmentReference colorRef;
colorRef.attachment = colorIndexVk;
colorRef.attachment = attachmentCount.get();
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachmentRefs.push_back(colorRef);
UnpackAttachmentDesc(&attachmentDescs[colorIndexVk], format, desc.samples(),
ops[colorIndexVk]);
UnpackAttachmentDesc(&attachmentDescs[attachmentCount.get()], format, desc.samples(),
ops[attachmentCount]);
++attachmentCount;
}
......@@ -283,14 +281,13 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
if (desc.hasDepthStencilAttachment())
{
ResourceAccess dsAccess = desc.getDepthStencilAccess();
uint32_t depthStencilIndex = static_cast<uint32_t>(desc.depthStencilAttachmentIndex());
uint32_t depthStencilIndexVk = colorAttachmentCount;
uint32_t depthStencilIndexGL = static_cast<uint32_t>(desc.depthStencilAttachmentIndex());
angle::FormatID formatID = desc[depthStencilIndex];
angle::FormatID formatID = desc[depthStencilIndexGL];
ASSERT(formatID != angle::FormatID::NONE);
const vk::Format &format = context->getRenderer()->getFormat(formatID);
depthStencilAttachmentRef.attachment = depthStencilIndexVk;
depthStencilAttachmentRef.attachment = attachmentCount.get();
switch (dsAccess)
{
......@@ -304,14 +301,14 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
UNREACHABLE();
}
UnpackAttachmentDesc(&attachmentDescs[depthStencilIndexVk], format, desc.samples(),
ops[depthStencilIndexVk]);
UnpackAttachmentDesc(&attachmentDescs[attachmentCount.get()], format, desc.samples(),
ops[attachmentCount]);
++attachmentCount;
}
// Pack color resolve attachments
const uint32_t nonResolveAttachmentCount = attachmentCount;
const uint32_t nonResolveAttachmentCount = attachmentCount.get();
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
{
if (!desc.hasColorResolveAttachment(colorIndexGL))
......@@ -322,16 +319,15 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
ASSERT(desc.isColorAttachmentEnabled(colorIndexGL));
uint32_t colorResolveIndexVk = attachmentCount;
const vk::Format &format = context->getRenderer()->getFormat(desc[colorIndexGL]);
const vk::Format &format = context->getRenderer()->getFormat(desc[colorIndexGL]);
VkAttachmentReference colorRef;
colorRef.attachment = colorResolveIndexVk;
colorRef.attachment = attachmentCount.get();
colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorResolveAttachmentRefs.push_back(colorRef);
UnpackResolveAttachmentDesc(&attachmentDescs[colorResolveIndexVk], format);
UnpackResolveAttachmentDesc(&attachmentDescs[attachmentCount.get()], format);
++attachmentCount;
}
......@@ -344,8 +340,9 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
subpassDesc.pInputAttachments = nullptr;
subpassDesc.colorAttachmentCount = static_cast<uint32_t>(colorAttachmentRefs.size());
subpassDesc.pColorAttachments = colorAttachmentRefs.data();
subpassDesc.pResolveAttachments =
attachmentCount > nonResolveAttachmentCount ? colorResolveAttachmentRefs.data() : nullptr;
subpassDesc.pResolveAttachments = attachmentCount.get() > nonResolveAttachmentCount
? colorResolveAttachmentRefs.data()
: nullptr;
subpassDesc.pDepthStencilAttachment =
(depthStencilAttachmentRef.attachment != VK_ATTACHMENT_UNUSED ? &depthStencilAttachmentRef
: nullptr);
......@@ -355,7 +352,7 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
VkRenderPassCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
createInfo.flags = 0;
createInfo.attachmentCount = attachmentCount;
createInfo.attachmentCount = attachmentCount.get();
createInfo.pAttachments = attachmentDescs.data();
createInfo.subpassCount = 1;
createInfo.pSubpasses = &subpassDesc;
......@@ -1555,17 +1552,17 @@ AttachmentOpsArray &AttachmentOpsArray::operator=(const AttachmentOpsArray &othe
return *this;
}
const PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](size_t index) const
const PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](PackedAttachmentIndex index) const
{
return mOps[index];
return mOps[index.get()];
}
PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](size_t index)
PackedAttachmentOpsDesc &AttachmentOpsArray::operator[](PackedAttachmentIndex index)
{
return mOps[index];
return mOps[index.get()];
}
void AttachmentOpsArray::initWithLoadStore(size_t index,
void AttachmentOpsArray::initWithLoadStore(PackedAttachmentIndex index,
ImageLayout initialLayout,
ImageLayout finalLayout)
{
......@@ -1574,42 +1571,42 @@ void AttachmentOpsArray::initWithLoadStore(size_t index,
setStencilOps(index, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE);
}
void AttachmentOpsArray::setLayouts(size_t index,
void AttachmentOpsArray::setLayouts(PackedAttachmentIndex index,
ImageLayout initialLayout,
ImageLayout finalLayout)
{
PackedAttachmentOpsDesc &ops = mOps[index];
PackedAttachmentOpsDesc &ops = mOps[index.get()];
SetBitField(ops.initialLayout, initialLayout);
SetBitField(ops.finalLayout, finalLayout);
}
void AttachmentOpsArray::setOps(size_t index,
void AttachmentOpsArray::setOps(PackedAttachmentIndex index,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp)
{
PackedAttachmentOpsDesc &ops = mOps[index];
PackedAttachmentOpsDesc &ops = mOps[index.get()];
SetBitField(ops.loadOp, loadOp);
SetBitField(ops.storeOp, storeOp);
}
void AttachmentOpsArray::setStencilOps(size_t index,
void AttachmentOpsArray::setStencilOps(PackedAttachmentIndex index,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp)
{
PackedAttachmentOpsDesc &ops = mOps[index];
PackedAttachmentOpsDesc &ops = mOps[index.get()];
SetBitField(ops.stencilLoadOp, loadOp);
SetBitField(ops.stencilStoreOp, storeOp);
}
void AttachmentOpsArray::setClearOp(size_t index)
void AttachmentOpsArray::setClearOp(PackedAttachmentIndex index)
{
PackedAttachmentOpsDesc &ops = mOps[index];
PackedAttachmentOpsDesc &ops = mOps[index.get()];
SetBitField(ops.loadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
}
void AttachmentOpsArray::setClearStencilOp(size_t index)
void AttachmentOpsArray::setClearStencilOp(PackedAttachmentIndex index)
{
PackedAttachmentOpsDesc &ops = mOps[index];
PackedAttachmentOpsDesc &ops = mOps[index.get()];
SetBitField(ops.stencilLoadOp, VK_ATTACHMENT_LOAD_OP_CLEAR);
}
......@@ -2138,7 +2135,7 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk,
// It would be nice to pre-populate the cache in the Renderer so we rarely miss here.
vk::AttachmentOpsArray ops;
uint32_t colorAttachmentCount = 0;
vk::PackedAttachmentIndex colorIndexVk(0);
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
{
if (!desc.isColorAttachmentEnabled(colorIndexGL))
......@@ -2146,9 +2143,9 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk,
continue;
}
uint32_t colorIndexVk = colorAttachmentCount++;
ops.initWithLoadStore(colorIndexVk, vk::ImageLayout::ColorAttachment,
vk::ImageLayout::ColorAttachment);
++colorIndexVk;
}
if (desc.hasDepthStencilAttachment())
......@@ -2165,8 +2162,7 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk,
imageLayout = vk::ImageLayout::DepthStencilAttachment;
}
uint32_t depthStencilIndexVk = colorAttachmentCount;
ops.initWithLoadStore(depthStencilIndexVk, imageLayout, imageLayout);
ops.initWithLoadStore(colorIndexVk, imageLayout, imageLayout);
}
return getRenderPassWithOps(contextVk, serial, desc, ops, renderPassOut);
......
......@@ -237,6 +237,8 @@ struct PackedAttachmentOpsDesc final
static_assert(sizeof(PackedAttachmentOpsDesc) == 2, "Size check failed");
class PackedAttachmentIndex;
class AttachmentOpsArray final
{
public:
......@@ -245,18 +247,26 @@ class AttachmentOpsArray final
AttachmentOpsArray(const AttachmentOpsArray &other);
AttachmentOpsArray &operator=(const AttachmentOpsArray &other);
const PackedAttachmentOpsDesc &operator[](size_t index) const;
PackedAttachmentOpsDesc &operator[](size_t index);
const PackedAttachmentOpsDesc &operator[](PackedAttachmentIndex index) const;
PackedAttachmentOpsDesc &operator[](PackedAttachmentIndex index);
// Initialize an attachment op with all load and store operations.
void initWithLoadStore(size_t index, ImageLayout initialLayout, ImageLayout finalLayout);
void setLayouts(size_t index, ImageLayout initialLayout, ImageLayout finalLayout);
void setOps(size_t index, VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp);
void setStencilOps(size_t index, VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp);
void setClearOp(size_t index);
void setClearStencilOp(size_t index);
void initWithLoadStore(PackedAttachmentIndex index,
ImageLayout initialLayout,
ImageLayout finalLayout);
void setLayouts(PackedAttachmentIndex index,
ImageLayout initialLayout,
ImageLayout finalLayout);
void setOps(PackedAttachmentIndex index,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp);
void setStencilOps(PackedAttachmentIndex index,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp);
void setClearOp(PackedAttachmentIndex index);
void setClearStencilOp(PackedAttachmentIndex index);
size_t hash() const;
......
......@@ -569,6 +569,31 @@ VkImageLayout ConvertImageLayoutToVkImageLayout(ImageLayout imageLayout)
return kImageMemoryBarrierData[imageLayout].layout;
}
// PackedClearValuesArray implementation
PackedClearValuesArray::PackedClearValuesArray() : mValues{} {}
PackedClearValuesArray::~PackedClearValuesArray() = default;
PackedClearValuesArray::PackedClearValuesArray(const PackedClearValuesArray &other) = default;
PackedClearValuesArray &PackedClearValuesArray::operator=(const PackedClearValuesArray &rhs) =
default;
void PackedClearValuesArray::store(PackedAttachmentIndex index,
VkImageAspectFlags aspectFlags,
const VkClearValue &clearValue)
{
ASSERT(aspectFlags != 0);
if (aspectFlags != VK_IMAGE_ASPECT_STENCIL_BIT)
{
storeNoDepthStencil(index, clearValue);
}
}
void PackedClearValuesArray::storeNoDepthStencil(PackedAttachmentIndex index,
const VkClearValue &clearValue)
{
mValues[index.get()] = clearValue;
}
// CommandBufferHelper implementation.
CommandBufferHelper::CommandBufferHelper()
: mPipelineBarriers(),
......@@ -587,7 +612,7 @@ CommandBufferHelper::CommandBufferHelper()
mDepthCmdSizeDisabled(kInfiniteCmdSize),
mStencilCmdSizeInvalidated(kInfiniteCmdSize),
mStencilCmdSizeDisabled(kInfiniteCmdSize),
mDepthStencilAttachmentIndex(kInvalidAttachmentIndex)
mDepthStencilAttachmentIndex(kAttachmentIndexInvalid)
{}
CommandBufferHelper::~CommandBufferHelper()
......@@ -836,8 +861,8 @@ void CommandBufferHelper::beginRenderPass(const Framebuffer &framebuffer,
const gl::Rectangle &renderArea,
const RenderPassDesc &renderPassDesc,
const AttachmentOpsArray &renderPassAttachmentOps,
const uint32_t depthStencilAttachmentIndex,
const ClearValuesArray &clearValues,
const PackedAttachmentIndex depthStencilAttachmentIndex,
const PackedClearValuesArray &clearValues,
CommandBuffer **commandBufferOut)
{
ASSERT(mIsRenderPassCommandBuffer);
......@@ -875,7 +900,7 @@ void CommandBufferHelper::endRenderPass(ContextVk *contextVk)
{
pauseTransformFeedbackIfStarted();
if (mDepthStencilAttachmentIndex == kInvalidAttachmentIndex)
if (mDepthStencilAttachmentIndex == kAttachmentIndexInvalid)
{
return;
}
......@@ -1066,6 +1091,7 @@ void CommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk)
size_t depthStencilAttachmentCount = mRenderPassDesc.hasDepthStencilAttachment() ? 1 : 0;
size_t colorAttachmentCount = attachmentCount - depthStencilAttachmentCount;
PackedAttachmentIndex attachmentIndexVk(0);
std::string loadOps, storeOps;
if (colorAttachmentCount > 0)
......@@ -1075,8 +1101,9 @@ void CommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk)
for (size_t i = 0; i < colorAttachmentCount; ++i)
{
loadOps += GetLoadOpShorthand(mAttachmentOps[i].loadOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[i].storeOp);
loadOps += GetLoadOpShorthand(mAttachmentOps[attachmentIndexVk].loadOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[attachmentIndexVk].storeOp);
++attachmentIndexVk;
}
}
......@@ -1086,13 +1113,12 @@ void CommandBufferHelper::addCommandDiagnostics(ContextVk *contextVk)
loadOps += " Depth/Stencil: ";
storeOps += " Depth/Stencil: ";
size_t dsIndex = colorAttachmentCount;
loadOps += GetLoadOpShorthand(mAttachmentOps[dsIndex].loadOp);
loadOps += GetLoadOpShorthand(mAttachmentOps[dsIndex].stencilLoadOp);
loadOps += GetLoadOpShorthand(mAttachmentOps[attachmentIndexVk].loadOp);
loadOps += GetLoadOpShorthand(mAttachmentOps[attachmentIndexVk].stencilLoadOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[dsIndex].storeOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[dsIndex].stencilStoreOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[attachmentIndexVk].storeOp);
storeOps += GetStoreOpShorthand(mAttachmentOps[attachmentIndexVk].stencilStoreOp);
}
if (attachmentCount > 0)
......@@ -1123,7 +1149,7 @@ void CommandBufferHelper::reset()
mDepthCmdSizeDisabled = kInfiniteCmdSize;
mStencilCmdSizeInvalidated = kInfiniteCmdSize;
mStencilCmdSizeDisabled = kInfiniteCmdSize;
mDepthStencilAttachmentIndex = kInvalidAttachmentIndex;
mDepthStencilAttachmentIndex = kAttachmentIndexInvalid;
mRenderPassUsedImages.clear();
}
// This state should never change for non-renderPass command buffer
......@@ -1167,11 +1193,11 @@ void CommandBufferHelper::pauseTransformFeedbackIfStarted()
mTransformFeedbackCounterBuffers.data());
}
void CommandBufferHelper::updateRenderPassColorClear(size_t colorIndex,
void CommandBufferHelper::updateRenderPassColorClear(PackedAttachmentIndex colorIndexVk,
const VkClearValue &clearValue)
{
mAttachmentOps.setClearOp(colorIndex);
mClearValues.store(static_cast<uint32_t>(colorIndex), VK_IMAGE_ASPECT_COLOR_BIT, clearValue);
mAttachmentOps.setClearOp(colorIndexVk);
mClearValues.store(colorIndexVk, VK_IMAGE_ASPECT_COLOR_BIT, clearValue);
}
void CommandBufferHelper::updateRenderPassDepthStencilClear(VkImageAspectFlags aspectFlags,
......
......@@ -875,6 +875,29 @@ enum class AliasingMode
Disallowed,
};
// Stores clear value In packed attachment index
class PackedClearValuesArray final
{
public:
PackedClearValuesArray();
~PackedClearValuesArray();
PackedClearValuesArray(const PackedClearValuesArray &other);
PackedClearValuesArray &operator=(const PackedClearValuesArray &rhs);
void store(PackedAttachmentIndex index,
VkImageAspectFlags aspectFlags,
const VkClearValue &clearValue);
void storeNoDepthStencil(PackedAttachmentIndex index, const VkClearValue &clearValue);
const VkClearValue &operator[](PackedAttachmentIndex index) const
{
return mValues[index.get()];
}
const VkClearValue *data() const { return mValues.data(); }
private:
gl::AttachmentArray<VkClearValue> mValues;
};
// The following are used to help track the state of an invalidated attachment.
// This value indicates an "infinite" CmdSize that is not valid for comparing
......@@ -946,8 +969,8 @@ class CommandBufferHelper : angle::NonCopyable
const gl::Rectangle &renderArea,
const RenderPassDesc &renderPassDesc,
const AttachmentOpsArray &renderPassAttachmentOps,
const uint32_t depthStencilAttachmentIndex,
const ClearValuesArray &clearValues,
const PackedAttachmentIndex depthStencilAttachmentIndex,
const PackedClearValuesArray &clearValues,
CommandBuffer **commandBufferOut);
void endRenderPass(ContextVk *contextVk);
......@@ -961,7 +984,7 @@ class CommandBufferHelper : angle::NonCopyable
void endTransformFeedback();
void invalidateRenderPassColorAttachment(size_t attachmentIndex)
void invalidateRenderPassColorAttachment(PackedAttachmentIndex attachmentIndex)
{
ASSERT(mIsRenderPassCommandBuffer);
SetBitField(mAttachmentOps[attachmentIndex].storeOp, VK_ATTACHMENT_STORE_OP_DONT_CARE);
......@@ -1005,13 +1028,15 @@ class CommandBufferHelper : angle::NonCopyable
cmdCountInvalidated;
}
void updateRenderPassAttachmentFinalLayout(size_t attachmentIndex, ImageLayout finalLayout)
void updateRenderPassAttachmentFinalLayout(PackedAttachmentIndex attachmentIndex,
ImageLayout finalLayout)
{
ASSERT(mIsRenderPassCommandBuffer);
SetBitField(mAttachmentOps[attachmentIndex].finalLayout, finalLayout);
}
void updateRenderPassColorClear(size_t colorIndex, const VkClearValue &colorClearValue);
void updateRenderPassColorClear(PackedAttachmentIndex colorIndex,
const VkClearValue &colorClearValue);
void updateRenderPassDepthStencilClear(VkImageAspectFlags aspectFlags,
const VkClearValue &clearValue);
......@@ -1081,7 +1106,7 @@ class CommandBufferHelper : angle::NonCopyable
AttachmentOpsArray mAttachmentOps;
Framebuffer mFramebuffer;
gl::Rectangle mRenderArea;
ClearValuesArray mClearValues;
PackedClearValuesArray mClearValues;
bool mRenderPassStarted;
bool mForceIndividualBarriers;
......@@ -1103,7 +1128,7 @@ class CommandBufferHelper : angle::NonCopyable
uint32_t mStencilCmdSizeDisabled;
// Keep track of the depth/stencil attachment index
uint32_t mDepthStencilAttachmentIndex;
PackedAttachmentIndex mDepthStencilAttachmentIndex;
// Tracks resources used in the command buffer.
// For Buffers, we track the read/write access type so we can enable simuntaneous reads.
......@@ -1112,8 +1137,6 @@ class CommandBufferHelper : angle::NonCopyable
angle::FastIntegerSet mRenderPassUsedImages;
};
static constexpr uint32_t kInvalidAttachmentIndex = -1;
// Imagine an image going through a few layout transitions:
//
// srcStage 1 dstStage 2 srcStage 2 dstStage 3
......
......@@ -107,6 +107,35 @@ namespace vk
{
struct Format;
// A packed attachment index interface with vulkan API
class PackedAttachmentIndex final
{
public:
explicit constexpr PackedAttachmentIndex(uint32_t index) : mAttachmentIndex(index) {}
constexpr PackedAttachmentIndex(const PackedAttachmentIndex &other) = default;
constexpr PackedAttachmentIndex &operator=(const PackedAttachmentIndex &other) = default;
constexpr uint32_t get() const { return mAttachmentIndex; }
PackedAttachmentIndex &operator++()
{
++mAttachmentIndex;
return *this;
}
constexpr bool operator==(const PackedAttachmentIndex &other) const
{
return mAttachmentIndex == other.mAttachmentIndex;
}
constexpr bool operator!=(const PackedAttachmentIndex &other) const
{
return mAttachmentIndex != other.mAttachmentIndex;
}
private:
uint32_t mAttachmentIndex;
};
static constexpr PackedAttachmentIndex kAttachmentIndexInvalid = PackedAttachmentIndex(-1);
static constexpr PackedAttachmentIndex kAttachmentIndexZero = PackedAttachmentIndex(0);
// Prepend ptr to the pNext chain at chainStart
template <typename VulkanStruct1, typename VulkanStruct2>
void AddToPNextChain(VulkanStruct1 *chainStart, VulkanStruct2 *ptr)
......@@ -683,11 +712,6 @@ class ClearValuesArray final
bool empty() const { return mEnabled.none(); }
bool any() const { return mEnabled.any(); }
gl::DrawBufferMask getEnabledColorAttachmentsMask() const
{
return gl::DrawBufferMask(static_cast<gl::DrawBufferMask::value_type>(mEnabled.to_ulong()));
}
private:
gl::AttachmentArray<VkClearValue> mValues;
gl::AttachmentsMask mEnabled;
......
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