Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit b156a75

Browse files
courtney-gCommit Bot
authored andcommitted
Move LayoutCaches to ShareGroup
Testing with TSN found a race condition with RefCounted objects (DescriptorSetLayout and PipelineLayout). Rather than add more lock calls to protect accesses to mRefCount and mObject recommendation was to put these caches in the ShareGroup (basically part of the context). Locking at the GL level will ensure that two threads that share the same context will not access the ShareGroup at the same time. The ShareGroup also works because these layouts are not destroyed until the context is destroyed so don't have to worry about other threads (e.g. command processor thread) accessing them. Bug: b/168744561 Change-Id: Icc0aa07bf4787a69572d6ec62da2f21d286232c3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2437509 Commit-Queue: Courtney Goeltzenleuchter <[email protected]> Reviewed-by: Jamie Madill <[email protected]> Reviewed-by: Charlie Lao <[email protected]>
1 parent b3859a3 commit b156a75

File tree

12 files changed

+58
-60
lines changed

12 files changed

+58
-60
lines changed

src/libANGLE/Context.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,14 @@ egl::Error Context::onDestroy(const egl::Display *display)
619619
mState.mFramebufferManager->release(this);
620620
mState.mMemoryObjectManager->release(this);
621621
mState.mSemaphoreManager->release(this);
622-
mState.mShareGroup->release(this);
623622

624623
mThreadPool.reset();
625624

626625
mImplementation->onDestroy(this);
627626

627+
// Backend requires implementation to be destroyed first to close down all the objects
628+
mState.mShareGroup->release(display);
629+
628630
mOverlay.destroy(this);
629631

630632
return egl::NoError();

src/libANGLE/Display.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,10 +471,14 @@ void ShareGroup::addRef()
471471
mRefCount++;
472472
}
473473

474-
void ShareGroup::release(const gl::Context *context)
474+
void ShareGroup::release(const Display *display)
475475
{
476476
if (--mRefCount == 0)
477477
{
478+
if (mImplementation)
479+
{
480+
mImplementation->onDestroy(display);
481+
}
478482
delete this;
479483
}
480484
}

src/libANGLE/Display.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class ShareGroup final : angle::NonCopyable
7373

7474
void addRef();
7575

76-
void release(const gl::Context *context);
76+
void release(const egl::Display *display);
7777

7878
rx::ShareGroupImpl *getImplementation() const { return mImplementation; }
7979

src/libANGLE/renderer/DisplayImpl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class ShareGroupImpl : angle::NonCopyable
5757
public:
5858
ShareGroupImpl() {}
5959
virtual ~ShareGroupImpl() {}
60+
virtual void onDestroy(const egl::Display *display) {}
6061
};
6162

6263
class DisplayImpl : public EGLImplFactory, public angle::Subject

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ angle::Result ContextVk::initialize()
852852

853853
vk::DescriptorSetLayoutDesc desc =
854854
getDriverUniformsDescriptorSetDesc(kPipelineStages[pipeline]);
855-
ANGLE_TRY(mRenderer->getDescriptorSetLayout(
855+
ANGLE_TRY(getDescriptorSetLayoutCache().getDescriptorSetLayout(
856856
this, desc, &mDriverUniforms[pipeline].descriptorSetLayout));
857857

858858
vk::DescriptorSetLayoutBindingVector bindingVector;

src/libANGLE/renderer/vulkan/ContextVk.h

Lines changed: 12 additions & 0 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"
@@ -230,6 +231,17 @@ class ContextVk : public ContextImpl, public vk::Context
230231
const GLuint *baseInstances,
231232
GLsizei drawcount) override;
232233

234+
// ShareGroup
235+
ShareGroupVk *getShareGroupVk() { return mShareGroupVk; }
236+
PipelineLayoutCache &getPipelineLayoutCache()
237+
{
238+
return mShareGroupVk->getPipelineLayoutCache();
239+
}
240+
DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
241+
{
242+
return mShareGroupVk->getDescriptorSetLayoutCache();
243+
}
244+
233245
// Device loss
234246
gl::GraphicsResetStatus getResetStatus() override;
235247

src/libANGLE/renderer/vulkan/DisplayVk.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,12 @@ bool DisplayVk::isRobustResourceInitEnabled() const
289289
// We return true if any surface was created with robust resource init enabled.
290290
return mHasSurfaceWithRobustInit;
291291
}
292+
293+
void ShareGroupVk::onDestroy(const egl::Display *display)
294+
{
295+
DisplayVk *displayVk = vk::GetImpl(display);
296+
297+
mPipelineLayoutCache.destroy(displayVk->getDevice());
298+
mDescriptorSetLayoutCache.destroy(displayVk->getDevice());
299+
}
292300
} // namespace rx

src/libANGLE/renderer/vulkan/DisplayVk.h

Lines changed: 15 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/vk_cache_utils.h"
1516
#include "libANGLE/renderer/vulkan/vk_utils.h"
1617

1718
namespace rx
@@ -22,6 +23,20 @@ class ShareGroupVk : public ShareGroupImpl
2223
{
2324
public:
2425
ShareGroupVk() {}
26+
void onDestroy(const egl::Display *display) override;
27+
28+
// PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads
29+
// accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring
30+
// synchronous update to the caches.
31+
PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
32+
DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
33+
34+
private:
35+
// ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
36+
PipelineLayoutCache mPipelineLayoutCache;
37+
38+
// DescriptorSetLayouts are also managed in a cache.
39+
DescriptorSetLayoutCache mDescriptorSetLayoutCache;
2540
};
2641

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

src/libANGLE/renderer/vulkan/ProgramExecutableVk.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "libANGLE/renderer/glslang_wrapper_utils.h"
1212
#include "libANGLE/renderer/vulkan/BufferVk.h"
13+
#include "libANGLE/renderer/vulkan/DisplayVk.h"
1314
#include "libANGLE/renderer/vulkan/GlslangWrapperVk.h"
1415
#include "libANGLE/renderer/vulkan/ProgramPipelineVk.h"
1516
#include "libANGLE/renderer/vulkan/ProgramVk.h"
@@ -736,7 +737,6 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
736737
{
737738
const gl::State &glState = glContext->getState();
738739
ContextVk *contextVk = vk::GetImpl(glContext);
739-
RendererVk *renderer = contextVk->getRenderer();
740740
gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
741741
const gl::ProgramExecutable &glExecutable = getGlExecutable();
742742
const gl::ShaderBitSet &linkedShaderStages = glExecutable.getLinkedShaderStages();
@@ -786,7 +786,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
786786
xfbBufferCount, &uniformsAndXfbSetDesc);
787787
}
788788

789-
ANGLE_TRY(renderer->getDescriptorSetLayout(
789+
ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
790790
contextVk, uniformsAndXfbSetDesc,
791791
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::UniformsAndXfb)]));
792792

@@ -814,7 +814,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
814814
contextVk->useOldRewriteStructSamplers(), &resourcesSetDesc);
815815
}
816816

817-
ANGLE_TRY(renderer->getDescriptorSetLayout(
817+
ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
818818
contextVk, resourcesSetDesc,
819819
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::ShaderResource)]));
820820

@@ -829,7 +829,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
829829
activeTextures, &texturesSetDesc);
830830
}
831831

832-
ANGLE_TRY(renderer->getDescriptorSetLayout(
832+
ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
833833
contextVk, texturesSetDesc,
834834
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::Texture)]));
835835

@@ -838,7 +838,7 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
838838
glExecutable.isCompute() ? VK_SHADER_STAGE_COMPUTE_BIT : VK_SHADER_STAGE_ALL_GRAPHICS;
839839
vk::DescriptorSetLayoutDesc driverUniformsSetDesc =
840840
contextVk->getDriverUniformsDescriptorSetDesc(driverUniformsStages);
841-
ANGLE_TRY(renderer->getDescriptorSetLayout(
841+
ANGLE_TRY(contextVk->getDescriptorSetLayoutCache().getDescriptorSetLayout(
842842
contextVk, driverUniformsSetDesc,
843843
&mDescriptorSetLayouts[ToUnderlying(DescriptorSetIndex::DriverUniforms)]));
844844

@@ -852,8 +852,8 @@ angle::Result ProgramExecutableVk::createPipelineLayout(
852852
pipelineLayoutDesc.updateDescriptorSetLayout(DescriptorSetIndex::DriverUniforms,
853853
driverUniformsSetDesc);
854854

855-
ANGLE_TRY(renderer->getPipelineLayout(contextVk, pipelineLayoutDesc, mDescriptorSetLayouts,
856-
&mPipelineLayout));
855+
ANGLE_TRY(contextVk->getPipelineLayoutCache().getPipelineLayout(
856+
contextVk, pipelineLayoutDesc, mDescriptorSetLayouts, &mPipelineLayout));
857857

858858
// Initialize descriptor pools.
859859
ANGLE_TRY(initDynamicDescriptorPools(

src/libANGLE/renderer/vulkan/RendererVk.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -535,9 +535,6 @@ void RendererVk::onDestroy()
535535
mFenceRecycler.destroy(mDevice);
536536
}
537537

538-
mPipelineLayoutCache.destroy(mDevice);
539-
mDescriptorSetLayoutCache.destroy(mDevice);
540-
541538
mPipelineCache.destroy(mDevice);
542539
mSamplerCache.destroy(this);
543540
mYuvConversionCache.destroy(this);
@@ -2045,26 +2042,6 @@ const gl::Limitations &RendererVk::getNativeLimitations() const
20452042
return mNativeLimitations;
20462043
}
20472044

2048-
angle::Result RendererVk::getDescriptorSetLayout(
2049-
ContextVk *context,
2050-
const vk::DescriptorSetLayoutDesc &desc,
2051-
vk::BindingPointer<vk::DescriptorSetLayout> *descriptorSetLayoutOut)
2052-
{
2053-
std::lock_guard<decltype(mDescriptorSetLayoutCacheMutex)> lock(mDescriptorSetLayoutCacheMutex);
2054-
return mDescriptorSetLayoutCache.getDescriptorSetLayout(context, desc, descriptorSetLayoutOut);
2055-
}
2056-
2057-
angle::Result RendererVk::getPipelineLayout(
2058-
vk::Context *context,
2059-
const vk::PipelineLayoutDesc &desc,
2060-
const vk::DescriptorSetLayoutPointerArray &descriptorSetLayouts,
2061-
vk::BindingPointer<vk::PipelineLayout> *pipelineLayoutOut)
2062-
{
2063-
std::lock_guard<decltype(mPipelineLayoutCacheMutex)> lock(mPipelineLayoutCacheMutex);
2064-
return mPipelineLayoutCache.getPipelineLayout(context, desc, descriptorSetLayouts,
2065-
pipelineLayoutOut);
2066-
}
2067-
20682045
angle::Result RendererVk::getPipelineCacheSize(DisplayVk *displayVk, size_t *pipelineCacheSizeOut)
20692046
{
20702047
VkResult result = mPipelineCache.getCacheData(mDevice, pipelineCacheSizeOut, nullptr);

0 commit comments

Comments
 (0)