Skip to content

Commit 20afc5b

Browse files
committed
WIP: occlusion culling + MASSIVE memory leak (30GB after 30 minutes)
1 parent 56885f8 commit 20afc5b

9 files changed

Lines changed: 207 additions & 59 deletions

File tree

Core/Source/Lux/Project/Project.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ namespace Lux
5353
struct ProjectSceneRendererSettings
5454
{
5555
bool EnableFrustumCulling = true;
56+
bool EnableOcclusionCulling = true;
5657
bool EnableGPUDrivenRendering = true;
5758
bool EnableGTAO = true;
5859
bool GTAOBentNormals = false;
@@ -62,6 +63,7 @@ namespace Lux
6263
bool EnableJumpFlood = true;
6364

6465
bool SoftShadows = true;
66+
bool EnableShadowCulling = true;
6567
float MaxShadowDistance = 200.0f;
6668
float ShadowFade = 25.0f;
6769
float ShadowCascadeSplitLambda = 0.92f;

Core/Source/Lux/Project/ProjectRuntimeFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Lux
1111
struct FileHeader
1212
{
1313
char Header[4] = { 'L', 'P', 'R', 'J' };
14-
uint32_t Version = 2;
14+
uint32_t Version = 3;
1515
};
1616

1717
struct Audio

Core/Source/Lux/Project/ProjectSerializer.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ namespace Lux
118118
out << YAML::Key << "Rendering" << YAML::Value;
119119
out << YAML::BeginMap;
120120
out << YAML::Key << "FrustumCulling" << YAML::Value << settings.EnableFrustumCulling;
121+
out << YAML::Key << "OcclusionCulling" << YAML::Value << settings.EnableOcclusionCulling;
121122
out << YAML::Key << "GPUDrivenRendering" << YAML::Value << settings.EnableGPUDrivenRendering;
122123
out << YAML::Key << "GTAO" << YAML::Value << settings.EnableGTAO;
123124
out << YAML::Key << "GTAOBentNormals" << YAML::Value << settings.GTAOBentNormals;
@@ -130,6 +131,7 @@ namespace Lux
130131
out << YAML::Key << "Shadows" << YAML::Value;
131132
out << YAML::BeginMap;
132133
out << YAML::Key << "SoftShadows" << YAML::Value << settings.SoftShadows;
134+
out << YAML::Key << "ShadowCulling" << YAML::Value << settings.EnableShadowCulling;
133135
out << YAML::Key << "MaxDistance" << YAML::Value << settings.MaxShadowDistance;
134136
out << YAML::Key << "DistanceFade" << YAML::Value << settings.ShadowFade;
135137
out << YAML::Key << "SplitLambda" << YAML::Value << settings.ShadowCascadeSplitLambda;
@@ -177,6 +179,7 @@ namespace Lux
177179
if (auto rendering = node["Rendering"])
178180
{
179181
settings.EnableFrustumCulling = rendering["FrustumCulling"].as<bool>(settings.EnableFrustumCulling);
182+
settings.EnableOcclusionCulling = rendering["OcclusionCulling"].as<bool>(settings.EnableOcclusionCulling);
180183
settings.EnableGPUDrivenRendering = rendering["GPUDrivenRendering"].as<bool>(settings.EnableGPUDrivenRendering);
181184
settings.EnableGTAO = rendering["GTAO"].as<bool>(settings.EnableGTAO);
182185
settings.GTAOBentNormals = rendering["GTAOBentNormals"].as<bool>(settings.GTAOBentNormals);
@@ -189,6 +192,7 @@ namespace Lux
189192
if (auto shadows = node["Shadows"])
190193
{
191194
settings.SoftShadows = shadows["SoftShadows"].as<bool>(settings.SoftShadows);
195+
settings.EnableShadowCulling = shadows["ShadowCulling"].as<bool>(settings.EnableShadowCulling);
192196
settings.MaxShadowDistance = shadows["MaxDistance"].as<float>(settings.MaxShadowDistance);
193197
settings.ShadowFade = shadows["DistanceFade"].as<float>(settings.ShadowFade);
194198
settings.ShadowCascadeSplitLambda = shadows["SplitLambda"].as<float>(settings.ShadowCascadeSplitLambda);
@@ -229,6 +233,7 @@ namespace Lux
229233
void WriteSceneRendererRuntimeSettings(FileStreamWriter& serializer, const ProjectSceneRendererSettings& settings)
230234
{
231235
serializer.WriteRaw(settings.EnableFrustumCulling);
236+
serializer.WriteRaw(settings.EnableOcclusionCulling);
232237
serializer.WriteRaw(settings.EnableGPUDrivenRendering);
233238
serializer.WriteRaw(settings.EnableGTAO);
234239
serializer.WriteRaw(settings.GTAOBentNormals);
@@ -238,6 +243,7 @@ namespace Lux
238243
serializer.WriteRaw(settings.EnableJumpFlood);
239244

240245
serializer.WriteRaw(settings.SoftShadows);
246+
serializer.WriteRaw(settings.EnableShadowCulling);
241247
serializer.WriteRaw(settings.MaxShadowDistance);
242248
serializer.WriteRaw(settings.ShadowFade);
243249
serializer.WriteRaw(settings.ShadowCascadeSplitLambda);
@@ -262,9 +268,11 @@ namespace Lux
262268
serializer.WriteRaw(settings.SSRDepthTolerance);
263269
}
264270

265-
void ReadSceneRendererRuntimeSettings(FileStreamReader& stream, ProjectSceneRendererSettings& settings)
271+
void ReadSceneRendererRuntimeSettings(FileStreamReader& stream, ProjectSceneRendererSettings& settings, uint32_t version)
266272
{
267273
stream.ReadRaw(settings.EnableFrustumCulling);
274+
if (version >= 3)
275+
stream.ReadRaw(settings.EnableOcclusionCulling);
268276
stream.ReadRaw(settings.EnableGPUDrivenRendering);
269277
stream.ReadRaw(settings.EnableGTAO);
270278
stream.ReadRaw(settings.GTAOBentNormals);
@@ -274,6 +282,8 @@ namespace Lux
274282
stream.ReadRaw(settings.EnableJumpFlood);
275283

276284
stream.ReadRaw(settings.SoftShadows);
285+
if (version >= 3)
286+
stream.ReadRaw(settings.EnableShadowCulling);
277287
stream.ReadRaw(settings.MaxShadowDistance);
278288
stream.ReadRaw(settings.ShadowFade);
279289
stream.ReadRaw(settings.ShadowCascadeSplitLambda);
@@ -663,7 +673,7 @@ namespace Lux
663673
}
664674

665675
if (projectInfo.HeaderData.Version >= 2)
666-
ReadSceneRendererRuntimeSettings(stream, config.SceneRenderer);
676+
ReadSceneRendererRuntimeSettings(stream, config.SceneRenderer, projectInfo.HeaderData.Version);
667677

668678
const std::filesystem::path overridesFile = filepath.parent_path() / "Project.yaml";
669679
if (std::filesystem::exists(overridesFile))

Core/Source/Lux/Renderer/Renderer.cpp

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include <glm/gtc/type_ptr.hpp>
3131

32+
#include <algorithm>
3233
#include <filesystem>
3334
#include <format>
3435
#include <shared_mutex>
@@ -199,13 +200,21 @@ namespace Lux {
199200

200201
struct ShaderDependencies
201202
{
202-
std::vector<Ref<PipelineCompute>> ComputePipelines;
203-
std::vector<Ref<Pipeline>> Pipelines;
204-
std::vector<Ref<Material>> Materials;
203+
std::vector<WeakRef<PipelineCompute>> ComputePipelines;
204+
std::vector<WeakRef<Pipeline>> Pipelines;
205+
std::vector<WeakRef<Material>> Materials;
205206
};
206207
static std::unordered_map<size_t, ShaderDependencies> s_ShaderDependencies;
207208
static std::shared_mutex s_ShaderDependenciesMutex; // ShaderDependencies can be accessed (and modified) from multiple threads, hence require synchronization
208209

210+
template<typename T>
211+
static void PruneDeadDependencies(std::vector<WeakRef<T>>& dependencies)
212+
{
213+
dependencies.erase(
214+
std::remove_if(dependencies.begin(), dependencies.end(), [](const WeakRef<T>& dependency) { return !dependency; }),
215+
dependencies.end());
216+
}
217+
209218

210219
struct GlobalShaderInfo
211220
{
@@ -260,19 +269,19 @@ namespace Lux {
260269

261270
static RendererData* s_RendererData = nullptr;
262271

263-
void Renderer::RegisterShaderDependency(Ref<Shader> shader, Ref<PipelineCompute> computePipeline)
272+
void Renderer::RegisterShaderDependency(Ref<Shader> shader, PipelineCompute* computePipeline)
264273
{
265274
std::scoped_lock lock(s_ShaderDependenciesMutex);
266275
s_ShaderDependencies[shader->GetHash()].ComputePipelines.push_back(computePipeline);
267276
}
268277

269-
void Renderer::RegisterShaderDependency(Ref<Shader> shader, Ref<Pipeline> pipeline)
278+
void Renderer::RegisterShaderDependency(Ref<Shader> shader, Pipeline* pipeline)
270279
{
271280
std::scoped_lock lock(s_ShaderDependenciesMutex);
272281
s_ShaderDependencies[shader->GetHash()].Pipelines.push_back(pipeline);
273282
}
274283

275-
void Renderer::RegisterShaderDependency(Ref<Shader> shader, Ref<Material> material)
284+
void Renderer::RegisterShaderDependency(Ref<Shader> shader, Material* material)
276285
{
277286
std::scoped_lock lock(s_ShaderDependenciesMutex);
278287
s_ShaderDependencies[shader->GetHash()].Materials.push_back(material);
@@ -282,25 +291,31 @@ namespace Lux {
282291
{
283292
ShaderDependencies dependencies;
284293
{
285-
std::shared_lock lock(s_ShaderDependenciesMutex);
294+
std::scoped_lock lock(s_ShaderDependenciesMutex);
286295
if (auto it = s_ShaderDependencies.find(hash); it != s_ShaderDependencies.end())
287296
{
288-
dependencies = it->second; // expensive to copy, but we need to release the lock (in particular to avoid potential deadlock if things like material->OnShaderReloaded() happen to ask for the lock)
297+
PruneDeadDependencies(it->second.Pipelines);
298+
PruneDeadDependencies(it->second.ComputePipelines);
299+
PruneDeadDependencies(it->second.Materials);
300+
dependencies = it->second; // Copy weak refs so callbacks run outside the registry lock.
289301
}
290302
}
291303
for (auto& pipeline : dependencies.Pipelines)
292304
{
293-
pipeline->Invalidate();
305+
if (pipeline)
306+
pipeline->Invalidate();
294307
}
295308

296309
for (auto& computePipeline : dependencies.ComputePipelines)
297310
{
298-
computePipeline->CreatePipeline();
311+
if (computePipeline)
312+
computePipeline->CreatePipeline();
299313
}
300314

301315
for (auto& material : dependencies.Materials)
302316
{
303-
material->OnShaderReloaded();
317+
if (material)
318+
material->OnShaderReloaded();
304319
}
305320
}
306321

Core/Source/Lux/Renderer/Renderer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ namespace Lux {
180180
static Ref<Environment> GetEmptyEnvironment();
181181
static Ref<Environment> GetDefaultEnvironment();
182182

183-
static void RegisterShaderDependency(Ref<Shader> shader, Ref<PipelineCompute> computePipeline);
184-
static void RegisterShaderDependency(Ref<Shader> shader, Ref<Pipeline> pipeline);
185-
static void RegisterShaderDependency(Ref<Shader> shader, Ref<Material> material);
183+
static void RegisterShaderDependency(Ref<Shader> shader, PipelineCompute* computePipeline);
184+
static void RegisterShaderDependency(Ref<Shader> shader, Pipeline* pipeline);
185+
static void RegisterShaderDependency(Ref<Shader> shader, Material* material);
186186
static void OnShaderReloaded(size_t hash);
187187

188188
static uint32_t GetCurrentFrameIndex();

Core/Source/Lux/Renderer/Renderer2D.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,12 @@ namespace Lux {
305305
ldelete[] buffer;
306306
}
307307

308+
for (auto buffers : m_LineOnTopVertexBufferBases)
309+
{
310+
for (auto buffer : buffers)
311+
ldelete[] buffer;
312+
}
313+
308314
for (auto buffers : m_CircleVertexBufferBases)
309315
{
310316
for (auto buffer : buffers)

0 commit comments

Comments
 (0)