Commit cd5489ad by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Faster FramebufferDesc compare

Objects of this class are used as keys to a hash map and contain 10 serials. Prior to this change, operator== would compare all 10 serials. This change tracks the maximum index set and only compares up to that many serials. To make sure this maximum index stays low in the presence of depth/stencil attachment, this class stores the depth/stencil attachment's serial before the color attachments. The update API of the class is improved so this implementation detail is not leaked. This is in preparation for supporting resolve attachments, which would add another 8 serials to the class. With this change, the performance of cases that don't use resolve attachments won't be affected. Bug: angleproject:4836 Change-Id: Ia4874ab79163901fb86f5bee4120e9f19babdc09 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2306514 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 234be194
...@@ -1338,12 +1338,12 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context, ...@@ -1338,12 +1338,12 @@ angle::Result FramebufferVk::updateColorAttachment(const gl::Context *context,
if (renderTarget && mState.getEnabledDrawBuffers()[colorIndexGL]) if (renderTarget && mState.getEnabledDrawBuffers()[colorIndexGL])
{ {
mCurrentFramebufferDesc.update(colorIndexGL, mCurrentFramebufferDesc.updateColor(colorIndexGL,
renderTarget->getAssignImageViewSerial(contextVk)); renderTarget->getAssignImageViewSerial(contextVk));
} }
else else
{ {
mCurrentFramebufferDesc.update(colorIndexGL, kInvalidImageViewSerial); mCurrentFramebufferDesc.updateColor(colorIndexGL, kInvalidImageViewSerial);
} }
return angle::Result::Continue; return angle::Result::Continue;
...@@ -1380,13 +1380,12 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk) ...@@ -1380,13 +1380,12 @@ void FramebufferVk::updateDepthStencilAttachmentSerial(ContextVk *contextVk)
if (depthStencilRT != nullptr) if (depthStencilRT != nullptr)
{ {
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex, mCurrentFramebufferDesc.updateDepthStencil(
depthStencilRT->getAssignImageViewSerial(contextVk)); depthStencilRT->getAssignImageViewSerial(contextVk));
} }
else else
{ {
mCurrentFramebufferDesc.update(vk::kFramebufferDescDepthStencilIndex, mCurrentFramebufferDesc.updateDepthStencil(kInvalidImageViewSerial);
kInvalidImageViewSerial);
} }
} }
...@@ -1424,10 +1423,10 @@ angle::Result FramebufferVk::syncState(const gl::Context *context, ...@@ -1424,10 +1423,10 @@ angle::Result FramebufferVk::syncState(const gl::Context *context,
mCurrentFramebufferDesc.reset(); mCurrentFramebufferDesc.reset();
for (size_t colorIndexGL : mState.getEnabledDrawBuffers()) for (size_t colorIndexGL : mState.getEnabledDrawBuffers())
{ {
mCurrentFramebufferDesc.update( RenderTargetVk *renderTarget = mRenderTargetCache.getColors()[colorIndexGL];
mCurrentFramebufferDesc.updateColor(
static_cast<uint32_t>(colorIndexGL), static_cast<uint32_t>(colorIndexGL),
mRenderTargetCache.getColors()[colorIndexGL]->getAssignImageViewSerial( renderTarget->getAssignImageViewSerial(contextVk));
contextVk));
} }
updateDepthStencilAttachmentSerial(contextVk); updateDepthStencilAttachmentSerial(contextVk);
break; break;
......
...@@ -32,6 +32,12 @@ namespace vk ...@@ -32,6 +32,12 @@ namespace vk
namespace namespace
{ {
// In the FramebufferDesc object:
// - Depth/stencil serial is at index 0
// - Color serials are at indices [1:gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]
constexpr size_t kFramebufferDescDepthStencilIndex = 0;
constexpr size_t kFramebufferDescColorIndexOffset = 1;
uint8_t PackGLBlendOp(GLenum blendOp) uint8_t PackGLBlendOp(GLenum blendOp)
{ {
switch (blendOp) switch (blendOp)
...@@ -1733,23 +1739,42 @@ void FramebufferDesc::update(uint32_t index, ImageViewSerial serial) ...@@ -1733,23 +1739,42 @@ void FramebufferDesc::update(uint32_t index, ImageViewSerial serial)
{ {
ASSERT(index < kMaxFramebufferAttachments); ASSERT(index < kMaxFramebufferAttachments);
mSerials[index] = serial; mSerials[index] = serial;
if (serial.valid())
{
mMaxValidSerialIndex = std::max(mMaxValidSerialIndex, index);
}
}
void FramebufferDesc::updateColor(uint32_t index, ImageViewSerial serial)
{
update(kFramebufferDescColorIndexOffset + index, serial);
}
void FramebufferDesc::updateDepthStencil(ImageViewSerial serial)
{
update(kFramebufferDescDepthStencilIndex, serial);
} }
size_t FramebufferDesc::hash() const size_t FramebufferDesc::hash() const
{ {
return angle::ComputeGenericHash(&mSerials, return angle::ComputeGenericHash(&mSerials, sizeof(mSerials[0]) * (mMaxValidSerialIndex + 1));
sizeof(ImageViewSerial) * kMaxFramebufferAttachments);
} }
void FramebufferDesc::reset() void FramebufferDesc::reset()
{ {
memset(&mSerials, 0, sizeof(ImageViewSerial) * kMaxFramebufferAttachments); memset(&mSerials, 0, sizeof(mSerials));
mMaxValidSerialIndex = 0;
} }
bool FramebufferDesc::operator==(const FramebufferDesc &other) const bool FramebufferDesc::operator==(const FramebufferDesc &other) const
{ {
return memcmp(&mSerials, &other.mSerials, if (mMaxValidSerialIndex != other.mMaxValidSerialIndex)
sizeof(ImageViewSerial) * kMaxFramebufferAttachments) == 0; {
return false;
}
return memcmp(&mSerials, &other.mSerials, sizeof(mSerials[0]) * (mMaxValidSerialIndex + 1)) ==
0;
} }
uint32_t FramebufferDesc::attachmentCount() const uint32_t FramebufferDesc::attachmentCount() const
......
...@@ -828,9 +828,6 @@ class UniformsAndXfbDesc ...@@ -828,9 +828,6 @@ class UniformsAndXfbDesc
// This is IMPLEMENTATION_MAX_DRAW_BUFFERS + 1 for DS attachment // This is IMPLEMENTATION_MAX_DRAW_BUFFERS + 1 for DS attachment
constexpr size_t kMaxFramebufferAttachments = gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS; constexpr size_t kMaxFramebufferAttachments = gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS;
// Color serials are at index [0:gl::IMPLEMENTATION_MAX_DRAW_BUFFERS-1]
// Depth/stencil index is at gl::IMPLEMENTATION_MAX_DRAW_BUFFERS
constexpr size_t kFramebufferDescDepthStencilIndex = gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
class FramebufferDesc class FramebufferDesc
{ {
...@@ -841,7 +838,8 @@ class FramebufferDesc ...@@ -841,7 +838,8 @@ class FramebufferDesc
FramebufferDesc(const FramebufferDesc &other); FramebufferDesc(const FramebufferDesc &other);
FramebufferDesc &operator=(const FramebufferDesc &other); FramebufferDesc &operator=(const FramebufferDesc &other);
void update(uint32_t index, ImageViewSerial serial); void updateColor(uint32_t index, ImageViewSerial serial);
void updateDepthStencil(ImageViewSerial serial);
size_t hash() const; size_t hash() const;
void reset(); void reset();
...@@ -850,7 +848,10 @@ class FramebufferDesc ...@@ -850,7 +848,10 @@ class FramebufferDesc
uint32_t attachmentCount() const; uint32_t attachmentCount() const;
private: private:
void update(uint32_t index, ImageViewSerial serial);
gl::AttachmentArray<ImageViewSerial> mSerials; gl::AttachmentArray<ImageViewSerial> mSerials;
uint32_t mMaxValidSerialIndex;
}; };
// Layer/level pair type used to index into Serial Cache in ImageViewHelper // Layer/level pair type used to index into Serial Cache in ImageViewHelper
...@@ -867,7 +868,7 @@ struct LayerLevel ...@@ -867,7 +868,7 @@ struct LayerLevel
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
// Introduce a std::hash for a RenderPassDesc // Introduce std::hash for the above classes.
namespace std namespace std
{ {
template <> template <>
......
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