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 ...@@ -2033,7 +2033,7 @@ RenderTargetVk *FramebufferVk::getFirstRenderTarget() const
GLint FramebufferVk::getSamples() const GLint FramebufferVk::getSamples() const
{ {
RenderTargetVk *firstRT = getFirstRenderTarget(); RenderTargetVk *firstRT = getFirstRenderTarget();
return firstRT ? firstRT->getImage().getSamples() : 0; return firstRT ? firstRT->getImage().getSamples() : 1;
} }
angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk, angle::Result FramebufferVk::flushDeferredClears(ContextVk *contextVk,
......
...@@ -212,15 +212,17 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context, ...@@ -212,15 +212,17 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
const AttachmentOpsArray &ops, const AttachmentOpsArray &ops,
RenderPass *renderPass) RenderPass *renderPass)
{ {
constexpr VkAttachmentReference kUnusedAttachment = {VK_ATTACHMENT_UNUSED,
VK_IMAGE_LAYOUT_UNDEFINED};
// Unpack the packed and split representation into the format required by Vulkan. // Unpack the packed and split representation into the format required by Vulkan.
gl::DrawBuffersVector<VkAttachmentReference> colorAttachmentRefs; gl::DrawBuffersVector<VkAttachmentReference> colorAttachmentRefs;
VkAttachmentReference depthStencilAttachmentRef = {VK_ATTACHMENT_UNUSED, VkAttachmentReference depthStencilAttachmentRef = kUnusedAttachment;
VK_IMAGE_LAYOUT_UNDEFINED};
gl::AttachmentArray<VkAttachmentDescription> attachmentDescs; gl::AttachmentArray<VkAttachmentDescription> attachmentDescs;
uint32_t colorAttachmentCount = 0; uint32_t colorAttachmentCount = 0;
uint32_t attachmentCount = 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: // Vulkan says:
// //
...@@ -233,11 +235,7 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context, ...@@ -233,11 +235,7 @@ angle::Result InitializeRenderPassFromDesc(vk::Context *context,
if (!desc.isColorAttachmentEnabled(colorIndexGL)) if (!desc.isColorAttachmentEnabled(colorIndexGL))
{ {
VkAttachmentReference colorRef; colorAttachmentRefs.push_back(kUnusedAttachment);
colorRef.attachment = VK_ATTACHMENT_UNUSED;
colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachmentRefs.push_back(colorRef);
continue; continue;
} }
...@@ -406,7 +404,8 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other) ...@@ -406,7 +404,8 @@ RenderPassDesc::RenderPassDesc(const RenderPassDesc &other)
void RenderPassDesc::setSamples(GLint samples) void RenderPassDesc::setSamples(GLint samples)
{ {
ASSERT(samples < std::numeric_limits<uint8_t>::max()); 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) void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID formatID)
...@@ -416,16 +415,15 @@ void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID fo ...@@ -416,16 +415,15 @@ void RenderPassDesc::packColorAttachment(size_t colorIndexGL, angle::FormatID fo
"Too many ANGLE formats to fit in uint8_t"); "Too many ANGLE formats to fit in uint8_t");
// Force the user to pack the depth/stencil attachment last. // Force the user to pack the depth/stencil attachment last.
ASSERT(mHasDepthStencilAttachment == false); 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); ASSERT(formatID != angle::FormatID::NONE);
uint8_t &packedFormat = mAttachmentFormats[colorIndexGL]; uint8_t &packedFormat = mAttachmentFormats[colorIndexGL];
SetBitField(packedFormat, formatID); SetBitField(packedFormat, formatID);
// Set color attachment range such that it covers the range from index 0 through last // 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. // active index inclusive. This is the reason why we need depth/stencil to be packed last.
mColorAttachmentRange = SetBitField(mColorAttachmentRange, std::max<size_t>(mColorAttachmentRange, colorIndexGL));
std::max<uint8_t>(mColorAttachmentRange, static_cast<uint8_t>(colorIndexGL) + 1);
} }
void RenderPassDesc::packColorAttachmentGap(size_t colorIndexGL) void RenderPassDesc::packColorAttachmentGap(size_t colorIndexGL)
...@@ -475,7 +473,7 @@ bool RenderPassDesc::isColorAttachmentEnabled(size_t colorIndexGL) const ...@@ -475,7 +473,7 @@ bool RenderPassDesc::isColorAttachmentEnabled(size_t colorIndexGL) const
size_t RenderPassDesc::attachmentCount() const size_t RenderPassDesc::attachmentCount() const
{ {
size_t colorAttachmentCount = 0; size_t colorAttachmentCount = 0;
for (size_t i = 0; i < mColorAttachmentRange; ++i) for (size_t i = 0; i <= mColorAttachmentRange; ++i)
{ {
colorAttachmentCount += isColorAttachmentEnabled(i); colorAttachmentCount += isColorAttachmentEnabled(i);
} }
...@@ -898,7 +896,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -898,7 +896,7 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
blendState.flags = 0; blendState.flags = 0;
blendState.logicOpEnable = static_cast<VkBool32>(inputAndBlend.logic.opEnable); blendState.logicOpEnable = static_cast<VkBool32>(inputAndBlend.logic.opEnable);
blendState.logicOp = static_cast<VkLogicOp>(inputAndBlend.logic.op); 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(); blendState.pAttachments = blendAttachmentState.data();
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
...@@ -1981,7 +1979,7 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk, ...@@ -1981,7 +1979,7 @@ angle::Result RenderPassCache::addRenderPass(ContextVk *contextVk,
vk::AttachmentOpsArray ops; vk::AttachmentOpsArray ops;
uint32_t colorAttachmentCount = 0; 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)) if (!desc.isColorAttachmentEnabled(colorIndexGL))
{ {
......
...@@ -32,9 +32,13 @@ using RefCountedSampler = RefCounted<Sampler>; ...@@ -32,9 +32,13 @@ using RefCountedSampler = RefCounted<Sampler>;
using RefCountedSamplerYcbcrConversion = RefCounted<SamplerYcbcrConversion>; using RefCountedSamplerYcbcrConversion = RefCounted<SamplerYcbcrConversion>;
// Helper macro that casts to a bitfield type then verifies no bits were dropped. // Helper macro that casts to a bitfield type then verifies no bits were dropped.
#define SetBitField(lhs, rhs) \ #define SetBitField(lhs, rhs) \
lhs = static_cast<typename std::decay<decltype(lhs)>::type>(rhs); \ do \
ASSERT(static_cast<decltype(rhs)>(lhs) == (rhs)) { \
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. // Packed Vk resource descriptions.
// Most Vk types use many more bits than required to represent the underlying data. // Most Vk types use many more bits than required to represent the underlying data.
...@@ -69,14 +73,14 @@ class alignas(4) RenderPassDesc final ...@@ -69,14 +73,14 @@ class alignas(4) RenderPassDesc final
// Mark a GL color attachment index as disabled. // Mark a GL color attachment index as disabled.
void packColorAttachmentGap(size_t colorIndexGL); void packColorAttachmentGap(size_t colorIndexGL);
// The caller must pack the depth/stencil attachment last, which is packed right after the color // 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); void packDepthStencilAttachment(angle::FormatID angleFormatID);
size_t hash() const; 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 colorAttachmentRange() const { return mColorAttachmentRange; }
size_t depthStencilAttachmentIndex() const { return colorAttachmentRange(); } size_t depthStencilAttachmentIndex() const { return colorAttachmentRange() + 1; }
bool isColorAttachmentEnabled(size_t colorIndexGL) const; bool isColorAttachmentEnabled(size_t colorIndexGL) const;
bool hasDepthStencilAttachment() const { return mHasDepthStencilAttachment; } bool hasDepthStencilAttachment() const { return mHasDepthStencilAttachment; }
...@@ -87,7 +91,7 @@ class alignas(4) RenderPassDesc final ...@@ -87,7 +91,7 @@ class alignas(4) RenderPassDesc final
void setSamples(GLint samples); void setSamples(GLint samples);
uint8_t samples() const { return mSamples; } uint8_t samples() const { return 1u << mLogSamples; }
angle::FormatID operator[](size_t index) const angle::FormatID operator[](size_t index) const
{ {
...@@ -96,9 +100,13 @@ class alignas(4) RenderPassDesc final ...@@ -96,9 +100,13 @@ class alignas(4) RenderPassDesc final
} }
private: private:
uint8_t mSamples; // Store log(samples), to be able to store it in 3 bits.
uint8_t mColorAttachmentRange : 7; uint8_t mLogSamples : 3;
uint8_t mColorAttachmentRange : 3;
uint8_t mHasDepthStencilAttachment : 1; 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 // 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, // attachment formats follow the last enabled color attachment. When creating a render pass,
// the disabled attachments are removed and the resulting attachments are packed. // the disabled attachments are removed and the resulting attachments are packed.
......
...@@ -2600,7 +2600,7 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -2600,7 +2600,7 @@ angle::Result ImageHelper::initExternal(Context *context,
mImageType = gl_vk::GetImageType(textureType); mImageType = gl_vk::GetImageType(textureType);
mExtents = extents; mExtents = extents;
mFormat = &format; mFormat = &format;
mSamples = samples; mSamples = std::max(samples, 1);
mBaseLevel = baseLevel; mBaseLevel = baseLevel;
mMaxLevel = maxLevel; mMaxLevel = maxLevel;
mLevelCount = mipLevels; mLevelCount = mipLevels;
...@@ -2623,7 +2623,7 @@ angle::Result ImageHelper::initExternal(Context *context, ...@@ -2623,7 +2623,7 @@ angle::Result ImageHelper::initExternal(Context *context,
imageInfo.extent = mExtents; imageInfo.extent = mExtents;
imageInfo.mipLevels = mipLevels; imageInfo.mipLevels = mipLevels;
imageInfo.arrayLayers = mLayerCount; imageInfo.arrayLayers = mLayerCount;
imageInfo.samples = gl_vk::GetSamples(samples); imageInfo.samples = gl_vk::GetSamples(mSamples);
imageInfo.tiling = mTilingMode; imageInfo.tiling = mTilingMode;
imageInfo.usage = mUsage; imageInfo.usage = mUsage;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
...@@ -2949,7 +2949,7 @@ void ImageHelper::init2DWeakReference(Context *context, ...@@ -2949,7 +2949,7 @@ void ImageHelper::init2DWeakReference(Context *context,
gl_vk::GetExtent(glExtents, &mExtents); gl_vk::GetExtent(glExtents, &mExtents);
mFormat = &format; mFormat = &format;
mSamples = samples; mSamples = std::max(samples, 1);
mCurrentLayout = ImageLayout::Undefined; mCurrentLayout = ImageLayout::Undefined;
mLayerCount = 1; mLayerCount = 1;
mLevelCount = 1; mLevelCount = 1;
......
...@@ -1030,6 +1030,8 @@ VkSampleCountFlagBits GetSamples(GLint sampleCount) ...@@ -1030,6 +1030,8 @@ VkSampleCountFlagBits GetSamples(GLint sampleCount)
switch (sampleCount) switch (sampleCount)
{ {
case 0: case 0:
UNREACHABLE();
return VK_SAMPLE_COUNT_1_BIT;
case 1: case 1:
return VK_SAMPLE_COUNT_1_BIT; return VK_SAMPLE_COUNT_1_BIT;
case 2: 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