Skip to content

Commit de335c1

Browse files
Mohan MaiyaCommit Bot
authored andcommitted
Vulkan: Implement a SharedResourceUse pool
When adding a Resource to the ResourceUseList of ContextVk we constructed a new SharedResourceUse object for tracking and update of the Resource's Serial. We would then delete it after releasing the resource. This incurs repeated memory operation costs. Instead we now allocate a pool of SharedResourceUse objects and acquire and release from this pool as needed. VTune profile of the Manhattan 30 offscreen benchmark shows the CPU occupancy of bufferRead decrease from an average of 0.9% -> 0.6% and imageRead decreases from an average of 0.4% -> 0.3%. The bottleneck for both these methods is the retain() method that leverages the new SharedResourceUse pool. Bug: angleproject:4950 Change-Id: Ib4f67c6f101d4b2de118014546e6cc14ad108703 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2396597 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
1 parent 76e9094 commit de335c1

File tree

16 files changed

+177
-91
lines changed

16 files changed

+177
-91
lines changed

src/libANGLE/Context.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,15 @@ egl::Error Context::onDestroy(const egl::Display *display)
621621
mState.mFramebufferManager->release(this);
622622
mState.mMemoryObjectManager->release(this);
623623
mState.mSemaphoreManager->release(this);
624-
mState.mShareGroup->release(this);
625624

626625
mThreadPool.reset();
627626

628627
mImplementation->onDestroy(this);
629628

629+
// Some ShareGroup implementations contain resource pools that implementation contexts
630+
// can leverage thus enforcing an ordering during destroy.
631+
mState.mShareGroup->release(this);
632+
630633
mOverlay.destroy(this);
631634

632635
return egl::NoError();

src/libANGLE/renderer/vulkan/BufferVk.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ angle::Result BufferVk::acquireAndUpdate(ContextVk *contextVk,
536536

537537
if (updateRegionBeforeSubData || updateRegionAfterSubData)
538538
{
539-
src->retain(&contextVk->getResourceUseList());
539+
src->retain(&contextVk->getResourceUseList(), contextVk->getSharedResourceUsePool());
540540
}
541541

542542
ANGLE_TRY(acquireBufferHelper(contextVk, size, &mBuffer));

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ void ContextVk::onDestroy(const gl::Context *context)
795795

796796
mCommandQueue.destroy(device);
797797

798-
mResourceUseList.releaseResourceUses();
798+
mResourceUseList.releaseResourceUses(getSharedResourceUsePool());
799799

800800
mUtils.destroy(mRenderer);
801801

@@ -1143,7 +1143,7 @@ angle::Result ContextVk::setupIndirectDraw(const gl::Context *context,
11431143
mCurrentIndirectBuffer = indirectBuffer;
11441144
}
11451145

1146-
mRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
1146+
mRenderPassCommands->bufferRead(this, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
11471147
vk::PipelineStage::DrawIndirect, indirectBuffer);
11481148

11491149
ANGLE_TRY(setupDraw(context, mode, firstVertex, vertexCount, instanceCount,
@@ -1416,10 +1416,9 @@ ANGLE_INLINE angle::Result ContextVk::handleDirtyTexturesImpl(
14161416
}
14171417
}
14181418
// Ensure the image is in read-only layout
1419-
commandBufferHelper->imageRead(&mResourceUseList, image.getAspectFlags(), textureLayout,
1420-
&image);
1419+
commandBufferHelper->imageRead(this, image.getAspectFlags(), textureLayout, &image);
14211420

1422-
textureVk->retainImageViews(&mResourceUseList);
1421+
textureVk->retainImageViews(this);
14231422
}
14241423

14251424
if (executable->hasTextures())
@@ -1463,7 +1462,7 @@ angle::Result ContextVk::handleDirtyGraphicsVertexBuffers(const gl::Context *con
14631462
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
14641463
if (arrayBuffer)
14651464
{
1466-
mRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
1465+
mRenderPassCommands->bufferRead(this, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
14671466
vk::PipelineStage::VertexInput, arrayBuffer);
14681467
}
14691468
}
@@ -1481,8 +1480,8 @@ angle::Result ContextVk::handleDirtyGraphicsIndexBuffer(const gl::Context *conte
14811480
mVertexArray->getCurrentElementArrayBufferOffset(),
14821481
getVkIndexType(mCurrentDrawElementsType));
14831482

1484-
mRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_INDEX_READ_BIT,
1485-
vk::PipelineStage::VertexInput, elementArrayBuffer);
1483+
mRenderPassCommands->bufferRead(this, VK_ACCESS_INDEX_READ_BIT, vk::PipelineStage::VertexInput,
1484+
elementArrayBuffer);
14861485

14871486
return angle::Result::Continue;
14881487
}
@@ -1544,7 +1543,7 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersEmulation(
15441543
{
15451544
vk::BufferHelper *bufferHelper = bufferHelpers[bufferIndex];
15461545
ASSERT(bufferHelper);
1547-
mRenderPassCommands->bufferWrite(&mResourceUseList, VK_ACCESS_SHADER_WRITE_BIT,
1546+
mRenderPassCommands->bufferWrite(this, VK_ACCESS_SHADER_WRITE_BIT,
15481547
vk::PipelineStage::VertexShader,
15491548
vk::AliasingMode::Disallowed, bufferHelper);
15501549
}
@@ -1583,9 +1582,9 @@ angle::Result ContextVk::handleDirtyGraphicsTransformFeedbackBuffersExtension(
15831582
{
15841583
vk::BufferHelper *bufferHelper = bufferHelpers[bufferIndex];
15851584
ASSERT(bufferHelper);
1586-
mRenderPassCommands->bufferWrite(
1587-
&mResourceUseList, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
1588-
vk::PipelineStage::TransformFeedback, vk::AliasingMode::Disallowed, bufferHelper);
1585+
mRenderPassCommands->bufferWrite(this, VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
1586+
vk::PipelineStage::TransformFeedback,
1587+
vk::AliasingMode::Disallowed, bufferHelper);
15891588
}
15901589

15911590
const gl::TransformFeedbackBuffersArray<VkBuffer> &bufferHandles =
@@ -2282,7 +2281,7 @@ angle::Result ContextVk::drawArraysIndirect(const gl::Context *context,
22822281

22832282
if (mVertexArray->getStreamingVertexAttribsMask().any())
22842283
{
2285-
mRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
2284+
mRenderPassCommands->bufferRead(this, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
22862285
vk::PipelineStage::DrawIndirect, currentIndirectBuf);
22872286

22882287
// We have instanced vertex attributes that need to be emulated for Vulkan.
@@ -2336,7 +2335,7 @@ angle::Result ContextVk::drawElementsIndirect(const gl::Context *context,
23362335

23372336
if (mVertexArray->getStreamingVertexAttribsMask().any())
23382337
{
2339-
mRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
2338+
mRenderPassCommands->bufferRead(this, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
23402339
vk::PipelineStage::DrawIndirect, currentIndirectBuf);
23412340

23422341
// We have instanced vertex attributes that need to be emulated for Vulkan.
@@ -3561,7 +3560,7 @@ angle::Result ContextVk::dispatchComputeIndirect(const gl::Context *context, GLi
35613560

35623561
gl::Buffer *glBuffer = getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
35633562
vk::BufferHelper &buffer = vk::GetImpl(glBuffer)->getBuffer();
3564-
mOutsideRenderPassCommands->bufferRead(&mResourceUseList, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
3563+
mOutsideRenderPassCommands->bufferRead(this, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
35653564
vk::PipelineStage::DrawIndirect, &buffer);
35663565

35673566
commandBuffer->dispatchIndirect(buffer.getBuffer(), indirect);
@@ -4100,8 +4099,8 @@ angle::Result ContextVk::updateActiveImages(const gl::Context *context,
41004099
}
41014100
VkImageAspectFlags aspectFlags = image->getAspectFlags();
41024101

4103-
commandBufferHelper->imageWrite(&mResourceUseList, aspectFlags, imageLayout,
4104-
vk::AliasingMode::Allowed, image);
4102+
commandBufferHelper->imageWrite(this, aspectFlags, imageLayout, vk::AliasingMode::Allowed,
4103+
image);
41054104
}
41064105

41074106
return angle::Result::Continue;
@@ -4176,7 +4175,7 @@ angle::Result ContextVk::flushImpl(const vk::Semaphore *signalSemaphore)
41764175
ANGLE_VK_TRY(this, mPrimaryCommands.end());
41774176

41784177
Serial serial = getCurrentQueueSerial();
4179-
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial);
4178+
mResourceUseList.releaseResourceUsesAndUpdateSerials(serial, getSharedResourceUsePool());
41804179

41814180
waitForSwapchainImageIfNecessary();
41824181

@@ -4478,7 +4477,7 @@ angle::Result ContextVk::onBufferRead(VkAccessFlags readAccessType,
44784477
ANGLE_TRY(flushOutsideRenderPassCommands());
44794478
}
44804479

4481-
mOutsideRenderPassCommands->bufferRead(&mResourceUseList, readAccessType, readStage, buffer);
4480+
mOutsideRenderPassCommands->bufferRead(this, readAccessType, readStage, buffer);
44824481

44834482
return angle::Result::Continue;
44844483
}
@@ -4498,7 +4497,7 @@ angle::Result ContextVk::onBufferWrite(VkAccessFlags writeAccessType,
44984497
ANGLE_TRY(flushOutsideRenderPassCommands());
44994498
}
45004499

4501-
mOutsideRenderPassCommands->bufferWrite(&mResourceUseList, writeAccessType, writeStage,
4500+
mOutsideRenderPassCommands->bufferWrite(this, writeAccessType, writeStage,
45024501
vk::AliasingMode::Disallowed, buffer);
45034502

45044503
return angle::Result::Continue;
@@ -4538,7 +4537,7 @@ angle::Result ContextVk::onImageRead(VkImageAspectFlags aspectFlags,
45384537

45394538
image->recordReadBarrier(aspectFlags, imageLayout,
45404539
&mOutsideRenderPassCommands->getCommandBuffer());
4541-
image->retain(&mResourceUseList);
4540+
image->retain(&mResourceUseList, getSharedResourceUsePool());
45424541

45434542
return angle::Result::Continue;
45444543
}
@@ -4554,7 +4553,7 @@ angle::Result ContextVk::onImageWrite(VkImageAspectFlags aspectFlags,
45544553

45554554
image->recordWriteBarrier(aspectFlags, imageLayout,
45564555
&mOutsideRenderPassCommands->getCommandBuffer());
4557-
image->retain(&mResourceUseList);
4556+
image->retain(&mResourceUseList, getSharedResourceUsePool());
45584557
image->onWrite();
45594558

45604559
return angle::Result::Continue;

src/libANGLE/renderer/vulkan/ContextVk.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "common/vulkan/vk_headers.h"
1717
#include "libANGLE/renderer/ContextImpl.h"
1818
#include "libANGLE/renderer/renderer_utils.h"
19+
#include "libANGLE/renderer/vulkan/DisplayVk.h"
1920
#include "libANGLE/renderer/vulkan/OverlayVk.h"
2021
#include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
2122
#include "libANGLE/renderer/vulkan/RendererVk.h"
@@ -482,6 +483,11 @@ class ContextVk : public ContextImpl, public vk::Context
482483

483484
vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }
484485

486+
ANGLE_INLINE vk::SharedResourceUsePool *getSharedResourceUsePool()
487+
{
488+
return mShareGroupVk->getSharedResourceUsePool();
489+
}
490+
485491
angle::Result onBufferTransferRead(vk::BufferHelper *buffer)
486492
{
487493
return onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, vk::PipelineStage::Transfer, buffer);
@@ -526,16 +532,16 @@ class ContextVk : public ContextImpl, public vk::Context
526532
vk::ImageHelper *image)
527533
{
528534
ASSERT(mRenderPassCommands->started());
529-
mRenderPassCommands->imageRead(&mResourceUseList, aspectFlags, imageLayout, image);
535+
mRenderPassCommands->imageRead(this, aspectFlags, imageLayout, image);
530536
}
531537

532538
void onImageRenderPassWrite(VkImageAspectFlags aspectFlags,
533539
vk::ImageLayout imageLayout,
534540
vk::ImageHelper *image)
535541
{
536542
ASSERT(mRenderPassCommands->started());
537-
mRenderPassCommands->imageWrite(&mResourceUseList, aspectFlags, imageLayout,
538-
vk::AliasingMode::Allowed, image);
543+
mRenderPassCommands->imageWrite(this, aspectFlags, imageLayout, vk::AliasingMode::Allowed,
544+
image);
539545
}
540546

541547
vk::CommandBuffer &getOutsideRenderPassCommandBuffer()

src/libANGLE/renderer/vulkan/DisplayVk.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
namespace rx
2323
{
2424

25+
// DisplayVk implementation
2526
DisplayVk::DisplayVk(const egl::DisplayState &state)
2627
: DisplayImpl(state),
2728
vk::Context(new RendererVk()),

src/libANGLE/renderer/vulkan/DisplayVk.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include "common/MemoryBuffer.h"
1414
#include "libANGLE/renderer/DisplayImpl.h"
15+
#include "libANGLE/renderer/vulkan/ResourceVk.h"
1516
#include "libANGLE/renderer/vulkan/vk_utils.h"
1617

1718
namespace rx
@@ -22,6 +23,14 @@ class ShareGroupVk : public ShareGroupImpl
2223
{
2324
public:
2425
ShareGroupVk() {}
26+
27+
ANGLE_INLINE vk::SharedResourceUsePool *getSharedResourceUsePool()
28+
{
29+
return &mSharedResourceUsePool;
30+
}
31+
32+
private:
33+
vk::SharedResourceUsePool mSharedResourceUsePool;
2534
};
2635

2736
class DisplayVk : public DisplayImpl, public vk::Context

src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ void ProgramExecutableVk::updateDefaultUniformsDescriptorSet(
940940
else
941941
{
942942
vk::BufferHelper &emptyBuffer = contextVk->getEmptyBuffer();
943-
emptyBuffer.retain(&contextVk->getResourceUseList());
943+
emptyBuffer.retain(&contextVk->getResourceUseList(), contextVk->getSharedResourceUsePool());
944944
bufferInfo.buffer = emptyBuffer.getBuffer().getHandle();
945945
}
946946

@@ -1044,13 +1044,13 @@ angle::Result ProgramExecutableVk::updateBuffersDescriptorSet(
10441044
{
10451045
// We set the SHADER_READ_BIT to be conservative.
10461046
VkAccessFlags accessFlags = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
1047-
commandBufferHelper->bufferWrite(resourceUseList, accessFlags,
1047+
commandBufferHelper->bufferWrite(contextVk, accessFlags,
10481048
kPipelineStageShaderMap[shaderType],
10491049
vk::AliasingMode::Allowed, &bufferHelper);
10501050
}
10511051
else
10521052
{
1053-
commandBufferHelper->bufferRead(resourceUseList, VK_ACCESS_UNIFORM_READ_BIT,
1053+
commandBufferHelper->bufferRead(contextVk, VK_ACCESS_UNIFORM_READ_BIT,
10541054
kPipelineStageShaderMap[shaderType], &bufferHelper);
10551055
}
10561056
}
@@ -1126,7 +1126,7 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
11261126

11271127
// We set SHADER_READ_BIT to be conservative.
11281128
commandBufferHelper->bufferWrite(
1129-
resourceUseList, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
1129+
contextVk, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
11301130
kPipelineStageShaderMap[shaderType], vk::AliasingMode::Allowed, &bufferHelper);
11311131

11321132
writtenBindings.set(binding);
@@ -1136,7 +1136,7 @@ angle::Result ProgramExecutableVk::updateAtomicCounterBuffersDescriptorSet(
11361136

11371137
// Bind the empty buffer to every array slot that's unused.
11381138
vk::BufferHelper &emptyBuffer = contextVk->getEmptyBuffer();
1139-
emptyBuffer.retain(&contextVk->getResourceUseList());
1139+
emptyBuffer.retain(&contextVk->getResourceUseList(), contextVk->getSharedResourceUsePool());
11401140
size_t count = (~writtenBindings).count();
11411141
VkDescriptorBufferInfo *bufferInfos = contextVk->allocDescriptorBufferInfos(count);
11421142
VkWriteDescriptorSet *writeInfos = contextVk->allocWriteDescriptorSets(count);

src/libANGLE/renderer/vulkan/RenderTargetVk.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,11 @@ angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk,
293293

294294
void RenderTargetVk::retainImageViews(ContextVk *contextVk) const
295295
{
296-
mImageViews->retain(&contextVk->getResourceUseList());
296+
mImageViews->retain(&contextVk->getResourceUseList(), contextVk->getSharedResourceUsePool());
297297
if (mResolveImageViews)
298298
{
299-
mResolveImageViews->retain(&contextVk->getResourceUseList());
299+
mResolveImageViews->retain(&contextVk->getResourceUseList(),
300+
contextVk->getSharedResourceUsePool());
300301
}
301302
}
302303

src/libANGLE/renderer/vulkan/ResourceVk.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,33 @@ angle::Result Resource::waitForIdle(ContextVk *contextVk, const char *debugMessa
5959
return angle::Result::Continue;
6060
}
6161

62+
// SharedResourceUsePool implementation.
63+
SharedResourceUsePool::SharedResourceUsePool() {}
64+
65+
SharedResourceUsePool::~SharedResourceUsePool() = default;
66+
67+
void SharedResourceUsePool::ensureCapacity()
68+
{
69+
// Allocate a SharedResourceUse block
70+
constexpr size_t kSharedResourceUseBlockSize = 2048;
71+
size_t newSize = (mSharedResourceUsePool.empty())
72+
? kSharedResourceUseBlockSize
73+
: mSharedResourceUsePool.back().capacity() * 2;
74+
SharedResourceUseBlock sharedResourceUseBlock;
75+
sharedResourceUseBlock.resize(newSize);
76+
77+
// Append it to the SharedResourceUse pool
78+
mSharedResourceUsePool.emplace_back(std::move(sharedResourceUseBlock));
79+
80+
// Add the newly allocated SharedResourceUse to the free list
81+
mSharedResourceUseFreeList.reserve(newSize);
82+
SharedResourceUseBlock &newSharedResourceUseBlock = mSharedResourceUsePool.back();
83+
for (SharedResourceUse &use : newSharedResourceUseBlock)
84+
{
85+
mSharedResourceUseFreeList.push_back(&use);
86+
}
87+
}
88+
6289
// SharedGarbage implementation.
6390
SharedGarbage::SharedGarbage() = default;
6491

@@ -107,23 +134,25 @@ ResourceUseList::~ResourceUseList()
107134
ASSERT(mResourceUses.empty());
108135
}
109136

110-
void ResourceUseList::releaseResourceUses()
137+
void ResourceUseList::releaseResourceUses(SharedResourceUsePool *sharedResourceUsePool)
111138
{
112-
for (SharedResourceUse &use : mResourceUses)
139+
for (SharedResourceUse *use : mResourceUses)
113140
{
114-
use.release();
141+
use->release();
142+
sharedResourceUsePool->releaseSharedResouceUse(use);
115143
}
116-
117144
mResourceUses.clear();
118145
}
119146

120-
void ResourceUseList::releaseResourceUsesAndUpdateSerials(Serial serial)
147+
void ResourceUseList::releaseResourceUsesAndUpdateSerials(
148+
Serial serial,
149+
SharedResourceUsePool *sharedResourceUsePool)
121150
{
122-
for (SharedResourceUse &use : mResourceUses)
151+
for (SharedResourceUse *use : mResourceUses)
123152
{
124-
use.releaseAndUpdateSerial(serial);
153+
use->releaseAndUpdateSerial(serial);
154+
sharedResourceUsePool->releaseSharedResouceUse(use);
125155
}
126-
127156
mResourceUses.clear();
128157
}
129158
} // namespace vk

0 commit comments

Comments
 (0)