From 9d9938cccc35e6c37d8ab2c1f712479c14fada29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 30 Dec 2024 17:24:05 -0300 Subject: [PATCH] Fix cache while trace isn't moved to GPU isn't the fastest or most memory efficient fix, but should hopefully only be temporary --- src/common/utility/tarray.h | 57 ++----------------- src/playsim/a_dynlight.cpp | 22 +++++++ src/playsim/a_dynlight.h | 3 + src/playsim/actor.h | 2 +- .../hwrenderer/scene/hw_spritelight.cpp | 30 ++++++---- 5 files changed, 50 insertions(+), 64 deletions(-) diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index 25d6e0e7f..bc359a28c 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -382,36 +382,14 @@ public: // exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does unsigned int SortedFind(const T& item, bool exact = true) const { - if(Count == 0) return 0; - if(Count == 1) return (item < Array[0]) ? 0 : 1; - - unsigned int lo = 0; - unsigned int hi = Count - 1; - - while(lo <= hi) - { - int mid = lo + ((hi - lo) / 2); - - if(Array[mid] < item) - { - lo = mid + 1; - } - else if(item < Array[mid]) - { - hi = mid - 1; - } - else - { - return mid; - } - } + unsigned int index = (std::lower_bound(begin(), end(), item) - begin()); if(exact) { - return Count; + return (index < Count && Array[index] == item) ? index : Count; } else { - return (lo == Count || (item < Array[lo])) ? lo : lo + 1; + return index; } } @@ -421,37 +399,14 @@ public: template unsigned int SortedFind(const T& item, Func &<, bool exact = true) const { - if(Count == 0) return 0; - if(Count == 1) return lt(item, Array[0]) ? 0 : 1; - - unsigned int lo = 0; - unsigned int hi = Count - 1; - - while(lo <= hi) - { - int mid = lo + ((hi - lo) / 2); - - if(std::invoke(lt, Array[mid], item)) - { - lo = mid + 1; - } - else if(std::invoke(lt, item, Array[mid])) - { - if(mid == 0) break; // prevent negative overflow due to unsigned numbers - hi = mid - 1; - } - else - { - return mid; - } - } + unsigned int index = (std::lower_bound(begin(), end(), item, lt) - begin()); if(exact) { - return Count; + return (index < Count && !std::invoke(lt, Array[index], item) && !std::invoke(lt, item, Array[index])) ? index : Count; } else { - return (lo == Count || std::invoke(lt, item, Array[lo])) ? lo : lo + 1; + return index; } } diff --git a/src/playsim/a_dynlight.cpp b/src/playsim/a_dynlight.cpp index e882268b6..4c278c0df 100644 --- a/src/playsim/a_dynlight.cpp +++ b/src/playsim/a_dynlight.cpp @@ -134,6 +134,7 @@ static FDynamicLight *GetLight(FLevelLocals *Level) ret->mShadowmapIndex = 1024; ret->Level = Level; ret->Pos.X = -10000000; // not a valid coordinate. + return ret; } @@ -437,6 +438,27 @@ void FDynamicLight::Tick() updated = true; } + if(TraceActors()) + { + if(updated) + { + ActorList.Clear(); + } + else if(ActorList.Size() > 0) + { + unsigned i = ActorList.Size() - 1; + while(i > 0) + { + if(ActorList[i]->ObjectFlags & OF_EuthanizeMe) + { + ActorList.Delete(i); + ActorResult.Delete(i); + } + i--; + } + } + } + wasactive = m_active; oldred = GetRed(); oldblue = GetBlue(); diff --git a/src/playsim/a_dynlight.h b/src/playsim/a_dynlight.h index 7aa834952..e1587cbbb 100644 --- a/src/playsim/a_dynlight.h +++ b/src/playsim/a_dynlight.h @@ -306,6 +306,9 @@ public: float lightStrength; + TArray ActorList; + TArray ActorResult; + // Locations in the level mesh light list. Ends with index = 0 or all entries used enum { max_levelmesh_entries = 4 }; struct diff --git a/src/playsim/actor.h b/src/playsim/actor.h index c4669afdd..049dc7dc7 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -1646,7 +1646,7 @@ public: struct { DVector3 Pos = DVector3(-12345678.0, -12345678.0, -12345678.0); - uint64_t Bits = 0; + bool SunResult = false; } StaticLightsTraceCache; void InvalidateLightTraceCache() diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index 7d16b2570..230cb5664 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -55,7 +55,7 @@ public: if (Actor && (Actor->Pos() != Actor->StaticLightsTraceCache.Pos || (Actor->Sector && (Actor->Sector->Flags & SECF_LM_DYNAMIC) && lm_dynamic))) { Actor->StaticLightsTraceCache.Pos = Actor->Pos(); - Actor->StaticLightsTraceCache.Bits = 0; + Actor->StaticLightsTraceCache.SunResult = false; ActorMoved = true; } } @@ -66,17 +66,26 @@ public: if (!light->TraceActors() || !level.levelMesh || !Actor) return true; - if (!ignoreCache && !ActorMoved && CurrentBit < 64) + unsigned index = light->ActorList.SortedFind(Actor, false); + + if (!ignoreCache && !ActorMoved && index < light->ActorList.Size() && light->ActorList[index] == Actor) { - bool traceResult = (Actor->StaticLightsTraceCache.Bits >> CurrentBit) & 1; - CurrentBit++; + bool traceResult = light->ActorResult[index]; return traceResult; } else { + bool traceResult = !level.levelMesh->Trace(FVector3((float)light->Pos.X, (float)light->Pos.Y, (float)light->Pos.Z), FVector3(-L.X, -L.Y, -L.Z), dist); - Actor->StaticLightsTraceCache.Bits |= ((uint64_t)traceResult) << CurrentBit; - CurrentBit++; + if(index == light->ActorList.Size() || light->ActorList[index] != Actor) + { + light->ActorList.Insert(index, Actor); + light->ActorResult.Insert(index, traceResult); + } + else + { + light->ActorResult[index] = traceResult; + } return traceResult; } } @@ -86,24 +95,21 @@ public: if (!level.lightmaps || !Actor) return false; - if (!ActorMoved && CurrentBit < 64) + if (!ActorMoved) { - bool traceResult = (Actor->StaticLightsTraceCache.Bits >> CurrentBit) & 1; - CurrentBit++; + bool traceResult = Actor->StaticLightsTraceCache.SunResult; return traceResult; } else { bool traceResult = level.levelMesh->TraceSky(FVector3(x, y, z), level.SunDirection, 65536.0f); - Actor->StaticLightsTraceCache.Bits |= ((uint64_t)traceResult) << CurrentBit; - CurrentBit++; + Actor->StaticLightsTraceCache.SunResult = traceResult; return traceResult; } } AActor* Actor; bool ActorMoved = false; - int CurrentBit = 0; }; //==========================================================================