Commit d8ce865b by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Make room in RenderPassDesc for resolve attachments

Data in RenderPassDesc is packed better to make room for resolve attachments (9 bits made available; 8 for color and 1 for depth/stencil). mColorAttachmentRange contains values in [0, 8). The right side of the range is made inclusive (i.e. [0, 7]) so it will fit in 3 bits. The number of samples is always a power of 2, and below 128 (for the foreseeable future), so its log is stored instead in 3 bits. This change doesn't add support for resolve attachments yet, but is split off the one that does to simplify it. Bug: angleproject:4836 Change-Id: I2856286d5239499d0ab0c78b8154881c003309bc Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2306515 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 7e2a9820
......@@ -2033,7 +2033,7 @@ RenderTargetVk *FramebufferVk::getFirstRenderTarget() const
GLint FramebufferVk::getSamples() const
{
RenderTargetVk *firstRT = getFirstRenderTarget();
return firstRT ? firstRT->getImage().getSamples() : 0;
return firstRT ? firstRT->getImage().getSamples() : 1;
}
angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk,
......
......@@ -212,15 +212,17 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
const AttachmentOpsArray &ops,
RenderPass *renderPass)
{
constexpr VkAttachmentReference kUnusedAttachment = {VK_ATTACHMENT_UNUSED,
VK_IMAGE_LAYOUT_UNDEFINED};
// Unpack the packed and split representation into the format required by Vulkan.
gl::DrawBuffersVector<VkAttachmentReference> colorAttachmentRefs;
VkAttachmentReference depthStencilAttachmentRef = {VK_ATTACHMENT_UNUSED,
VK_IMAGE_LAYOUT_UNDEFINED};
VkAttachmentReference depthStencilAttachmentRef = kUnusedAttachment;
gl::AttachmentArray<VkAttachmentDescription> attachmentDescs;
uint32_t colorAttachmentCount = 0;
uint32_t attachmentCount = 0;
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
for (uint32_t colorIndexGL = 0; colorIndexGL <= desc.colorAttachmentRange(); ++colorIndexGL)
{
// Vulkan says:
//
......@@ -233,11 +235,7 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
if (!desc.isColorAttachmentEnabled(colorIndexGL))
{
VkAttachmentReference colorRef;
colorRef.attachment = VK_ATTACHMENT_UNUSED;
colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachmentRefs.push_back(colorRef);
colorAttachmentRefs.push_back(kUnusedAttachment);
continue;
}
......@@ -406,7 +404,8 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
void RenderPassDesc::setSamples(GLint samples)
{
ASSERT(samples < std::numeric_limits<uint8_t>::max());
mSamples = static_cast<uint8_t>(samples);
ASSERT(gl::isPow2(samples));
SetBitField(mLogSamples, gl::ScanForward(static_cast<uint8_t>(samples)));
}
void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID formatID)
......@@ -416,16 +415,15 @@ void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID fo
"Too many ANGLE formats to fit in uint8_t");
// Force the user to pack the depth/stencil attachment last.
ASSERT(mHasDepthStencilAttachment == false);
// This function should only be called for enabled GL color attachments.`
// This function should only be called for enabled GL color attachments.
ASSERT(formatID != angle::FormatID::NONE);
uint8_t &packedFormat = mAttachmentFormats[colorIndexGL];
SetBitField(packedFormat, formatID);
// Set color attachment range such that it covers the range from index 0 through last
// active index. This is the reason why we need depth/stencil to be packed last.
mColorAttachmentRange =
std::max<uint8_t>(mColorAttachmentRange, static_cast<uint8_t>(colorIndexGL) + 1);
// active index inclusive. This is the reason why we need depth/stencil to be packed last.
SetBitField(mColorAttachmentRange, std::max<size_t>(mColorAttachmentRange, colorIndexGL));
}
void RenderPassDesc::packColorAttachmentGap(size_t colorIndexGL)
......@@ -475,7 +473,7 @@ bool RenderPassDesc::isColorAttachmentEnabled(size_t colorIndexGL) const
size_t RenderPassDesc::attachmentCount() const
{
size_t colorAttachmentCount = 0;
for (size_t i = 0; i < mColorAttachmentRange; ++i)
for (size_t i = 0; i <= mColorAttachmentRange; ++i)
{
colorAttachmentCount += isColorAttachmentEnabled(i);
}
......@@ -898,7 +896,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
blendState.flags = 0;
blendState.logicOpEnable = static_cast<VkBool32>(inputAndBlend.logic.opEnable);
blendState.logicOp = static_cast<VkLogicOp>(inputAndBlend.logic.op);
blendState.attachmentCount = static_cast<uint32_t>(mRenderPassDesc.colorAttachmentRange());
blendState.attachmentCount = static_cast<uint32_t>(mRenderPassDesc.colorAttachmentRange() + 1);
blendState.pAttachments = blendAttachmentState.data();
for (int i = 0; i < 4; i++)
......@@ -1981,7 +1979,7 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk,
vk::AttachmentOpsArray ops;
uint32_t colorAttachmentCount = 0;
for (uint32_t colorIndexGL = 0; colorIndexGL < desc.colorAttachmentRange(); ++colorIndexGL)
for (uint32_t colorIndexGL = 0; colorIndexGL <= desc.colorAttachmentRange(); ++colorIndexGL)
{
if (!desc.isColorAttachmentEnabled(colorIndexGL))
{
......
......@@ -33,8 +33,12 @@ using RefCountedSamplerYcbcrConversion = RefCounted<SamplerYcbcrConversion>;
// Helper macro that casts to a bitfield type then verifies no bits were dropped.
#define SetBitField(lhs, rhs) \
lhs = static_cast<typename std::decay<decltype(lhs)>::type>(rhs); \
ASSERT(static_cast<decltype(rhs)>(lhs) == (rhs))
do \
{ \
auto ANGLE_LOCAL_VAR = rhs; \
lhs = static_cast<typename std::decay<decltype(lhs)>::type>(ANGLE_LOCAL_VAR); \
ASSERT(static_cast<decltype(ANGLE_LOCAL_VAR)>(lhs) == ANGLE_LOCAL_VAR); \
} while (0)
// Packed Vk resource descriptions.
// Most Vk types use many more bits than required to represent the underlying data.
......@@ -69,14 +73,14 @@ class alignas(4) RenderPassDesc final
// Mark a GL color attachment index as disabled.
void packColorAttachmentGap(size_t colorIndexGL);
// The caller must pack the depth/stencil attachment last, which is packed right after the color
// attachments (including gaps), i.e. with an index starting from |colorAttachmentRange()|.
// attachments (including gaps), i.e. with an index starting from |colorAttachmentRange() + 1|.
void packDepthStencilAttachment(angle::FormatID angleFormatID);
size_t hash() const;
// Color attachments are in [0, colorAttachmentRange()), with possible gaps.
// Color attachments are in [0, colorAttachmentRange()], with possible gaps.
size_t colorAttachmentRange() const { return mColorAttachmentRange; }
size_t depthStencilAttachmentIndex() const { return colorAttachmentRange(); }
size_t depthStencilAttachmentIndex() const { return colorAttachmentRange() + 1; }
bool isColorAttachmentEnabled(size_t colorIndexGL) const;
bool hasDepthStencilAttachment() const { return mHasDepthStencilAttachment; }
......@@ -87,7 +91,7 @@ class alignas(4) RenderPassDesc final
void setSamples(GLint samples);
uint8_t samples() const { return mSamples; }
uint8_t samples() const { return 1u << mLogSamples; }
angle::FormatID operator[](size_t index) const
{
......@@ -96,9 +100,13 @@ class alignas(4) RenderPassDesc final
}
private:
uint8_t mSamples;
uint8_t mColorAttachmentRange : 7;
// Store log(samples), to be able to store it in 3 bits.
uint8_t mLogSamples : 3;
uint8_t mColorAttachmentRange : 3;
uint8_t mHasDepthStencilAttachment : 1;
// Temporary padding for upcoming support for resolve attachments.
ANGLE_MAYBE_UNUSED uint8_t pad : 1;
ANGLE_MAYBE_UNUSED uint8_t pad2;
// Color attachment formats are stored with their GL attachment indices. The depth/stencil
// attachment formats follow the last enabled color attachment. When creating a render pass,
// the disabled attachments are removed and the resulting attachments are packed.
......
......@@ -2600,7 +2600,7 @@ angle::Result ImageHelper::initExternal(Context *context,
mImageType = gl_vk::GetImageType(textureType);
mExtents = extents;
mFormat = &format;
mSamples = samples;
mSamples = std::max(samples, 1);
mBaseLevel = baseLevel;
mMaxLevel = maxLevel;
mLevelCount = mipLevels;
......@@ -2623,7 +2623,7 @@ angle::Result ImageHelper::initExternal(Context *context,
imageInfo.extent = mExtents;
imageInfo.mipLevels = mipLevels;
imageInfo.arrayLayers = mLayerCount;
imageInfo.samples = gl_vk::GetSamples(samples);
imageInfo.samples = gl_vk::GetSamples(mSamples);
imageInfo.tiling = mTilingMode;
imageInfo.usage = mUsage;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
......@@ -2949,7 +2949,7 @@ void ImageHelper::init2DWeakReference(Context *context,
gl_vk::GetExtent(glExtents, &mExtents);
mFormat = &format;
mSamples = samples;
mSamples = std::max(samples, 1);
mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1;
mLevelCount = 1;
......
......@@ -1030,6 +1030,8 @@ VkSampleCountFlagBits GetSamples(GLint sampleCount)
switch (sampleCount)
{
case 0:
UNREACHABLE();
return VK_SAMPLE_COUNT_1_BIT;
case 1:
return VK_SAMPLE_COUNT_1_BIT;
case 2:
......
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