Fix ConcurrentSystemLocker to have exclusive lock as an option

This commit is contained in:
Wojtek Figat
2025-06-29 19:16:41 +02:00
parent 43d11264f8
commit 78d519cb9a
4 changed files with 14 additions and 12 deletions

View File

@@ -127,7 +127,7 @@ void SceneRendering::CollectPostFxVolumes(RenderContext& renderContext)
void SceneRendering::Clear() void SceneRendering::Clear()
{ {
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
for (auto* listener : _listeners) for (auto* listener : _listeners)
{ {
listener->OnSceneRenderingClear(this); listener->OnSceneRenderingClear(this);
@@ -149,7 +149,7 @@ void SceneRendering::AddActor(Actor* a, int32& key)
return; return;
PROFILE_MEM(Graphics); PROFILE_MEM(Graphics);
const int32 category = a->_drawCategory; const int32 category = a->_drawCategory;
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
auto& list = Actors[category]; auto& list = Actors[category];
if (FreeActors[category].HasItems()) if (FreeActors[category].HasItems())
{ {
@@ -193,7 +193,7 @@ void SceneRendering::UpdateActor(Actor* a, int32& key, ISceneRenderingListener::
void SceneRendering::RemoveActor(Actor* a, int32& key) void SceneRendering::RemoveActor(Actor* a, int32& key)
{ {
const int32 category = a->_drawCategory; const int32 category = a->_drawCategory;
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
auto& list = Actors[category]; auto& list = Actors[category];
if (list.Count() > key) // Ignore invalid key softly (eg. list after batch clear during scene unload) if (list.Count() > key) // Ignore invalid key softly (eg. list after batch clear during scene unload)
{ {

View File

@@ -396,7 +396,7 @@ public:
{ {
if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle())) if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle()))
{ {
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
OnSceneRenderingDirty(a->GetBox()); OnSceneRenderingDirty(a->GetBox());
} }
} }
@@ -405,7 +405,7 @@ public:
{ {
if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle())) if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle()))
{ {
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
OnSceneRenderingDirty(BoundingBox::FromSphere(prevBounds)); OnSceneRenderingDirty(BoundingBox::FromSphere(prevBounds));
OnSceneRenderingDirty(a->GetBox()); OnSceneRenderingDirty(a->GetBox());
} }
@@ -415,13 +415,14 @@ public:
{ {
if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle())) if (GLOBAL_SDF_ACTOR_IS_STATIC(a) && ObjectTypes.Contains(a->GetTypeHandle()))
{ {
ConcurrentSystemLocker::WriteScope lock(Locker); ConcurrentSystemLocker::WriteScope lock(Locker, true);
OnSceneRenderingDirty(a->GetBox()); OnSceneRenderingDirty(a->GetBox());
} }
} }
void OnSceneRenderingClear(SceneRendering* scene) override void OnSceneRenderingClear(SceneRendering* scene) override
{ {
ConcurrentSystemLocker::WriteScope lock(Locker, true);
for (auto& cascade : Cascades) for (auto& cascade : Cascades)
cascade.StaticChunks.Clear(); cascade.StaticChunks.Clear();
} }
@@ -719,6 +720,7 @@ bool GlobalSignDistanceFieldPass::Render(RenderContext& renderContext, GPUContex
} }
sdfData.LastFrameUsed = currentFrame; sdfData.LastFrameUsed = currentFrame;
PROFILE_GPU_CPU("Global SDF"); PROFILE_GPU_CPU("Global SDF");
ConcurrentSystemLocker::WriteScope lock(sdfData.Locker);
// Setup options // Setup options
int32 resolution, cascadesCount, resolutionMip; int32 resolution, cascadesCount, resolutionMip;

View File

@@ -8,7 +8,7 @@ ConcurrentSystemLocker::ConcurrentSystemLocker()
_counters[0] = _counters[1] = 0; _counters[0] = _counters[1] = 0;
} }
void ConcurrentSystemLocker::Begin(bool write) void ConcurrentSystemLocker::Begin(bool write, bool exclusively)
{ {
volatile int64* thisCounter = &_counters[write]; volatile int64* thisCounter = &_counters[write];
volatile int64* otherCounter = &_counters[!write]; volatile int64* otherCounter = &_counters[!write];
@@ -22,8 +22,8 @@ RETRY:
goto RETRY; goto RETRY;
} }
// Writers have to check themselves to (one write at the same time - just like a mutex) // Writers might want to check themselves for a single writer at the same time - just like a mutex
if (write && Platform::AtomicRead(thisCounter) != 0) if (exclusively && Platform::AtomicRead(thisCounter) != 0)
{ {
// Someone else is doing opposite operation so wait for it's end // Someone else is doing opposite operation so wait for it's end
Platform::Sleep(0); Platform::Sleep(0);

View File

@@ -17,7 +17,7 @@ public:
NON_COPYABLE(ConcurrentSystemLocker); NON_COPYABLE(ConcurrentSystemLocker);
ConcurrentSystemLocker(); ConcurrentSystemLocker();
void Begin(bool write); void Begin(bool write, bool exclusively = false);
void End(bool write); void End(bool write);
public: public:
@@ -26,10 +26,10 @@ public:
{ {
NON_COPYABLE(Scope); NON_COPYABLE(Scope);
Scope(ConcurrentSystemLocker& locker) Scope(ConcurrentSystemLocker& locker, bool exclusively = false)
: _locker(locker) : _locker(locker)
{ {
_locker.Begin(Write); _locker.Begin(Write, exclusively);
} }
~Scope() ~Scope()