From 16a51506c08ea0d44bda14b0a1fa290bd9d47b44 Mon Sep 17 00:00:00 2001 From: myT <> Date: Sun, 7 Jul 2024 18:20:26 +0200 Subject: [PATCH] fixed RTAS build crash due to missing cross queue sync --- code/renderer/crp_local.h | 27 ++++-- code/renderer/crp_main.cpp | 3 +- code/renderer/crp_raytracing.cpp | 139 ++++++++++++++++++------------- code/renderer/rhi_d3d12.cpp | 4 - 4 files changed, 101 insertions(+), 72 deletions(-) diff --git a/code/renderer/crp_local.h b/code/renderer/crp_local.h index a2dd22f..d2826ef 100644 --- a/code/renderer/crp_local.h +++ b/code/renderer/crp_local.h @@ -329,13 +329,27 @@ struct Raytracing { void Init(); void ProcessWorld(world_t& world); + void BeforeFrame(bool wantUpdate); void BeginFrame(bool wantUpdate); uint32_t GetTLASBufferIndex(); uint32_t GetInstanceBufferIndex(); bool CanRaytrace(); private: + struct BLASBuildBuffers; + struct BLASBuffers; + struct ISurfaceList; void TagMapSurfacesRecursively(mnode_t* node); + void ProcessStaticSurfaces(); + void EnsureBuffersAreLargeEnough(BLASBuildBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount); + void EnsureBuffersAreLargeEnough(BLASBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount, uint32_t maxMeshCount); + void BuildBLASes(BLASBuffers* blasBuffers, struct BLASBuilder* blasBuilders, ISurfaceList* surfaceList); + uint32_t GetRTFrameIndex() { return frameCount % RTFrameCount; } + + enum Constants + { + RTFrameCount = RHI::FrameCount + }; struct BLASBucket { @@ -389,10 +403,6 @@ private: bool GetSurface(Surface& surface, uint32_t index) override; }; - void EnsureBuffersAreLargeEnough(BLASBuildBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount); - void EnsureBuffersAreLargeEnough(BLASBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount, uint32_t maxMeshCount); - void BuildBLASes(BLASBuffers* blasBuffers, struct BLASBuilder* blasBuilders, ISurfaceList* surfaceList); - struct FrameData { BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {}; @@ -401,14 +411,15 @@ private: HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE(); }; - enum Constants { RTFrameCount = RHI::FrameCount + 1 }; - - uint32_t GetRTFrameIndex() { return tr.frameCount % RTFrameCount; } - FrameData frameData[RTFrameCount]; BLASBuffers staticBLASBuffers[BLASBucket::Count] = {}; StaticArray tlasInstanceDescs; uint32_t staticTLASInstanceCount = 0; + bool pendingWorldProcess = false; + uint32_t frameCount = 0; + // we have a local frame counter because (for now) + // RHI::GetFrameIndex() increments during RHI::BeginFrame() + // in a given frame, we need BeforeFrame and BeginFrame to use the same buffer index }; struct SunlightEditor diff --git a/code/renderer/crp_main.cpp b/code/renderer/crp_main.cpp index 849898a..800e7bc 100644 --- a/code/renderer/crp_main.cpp +++ b/code/renderer/crp_main.cpp @@ -630,9 +630,10 @@ void CRP::BeginFrame() dynamicLights.WantRTASUpdate(tr.rtRefdef) || sunlight.WantRTASUpdate(tr.rtRefdef) || volumetricLight.WantRTASUpdate(tr.rtRefdef); - raytracing.BeginFrame(rtasUpdate); + raytracing.BeforeFrame(rtasUpdate); // uploads data RHI::BeginFrame(); + raytracing.BeginFrame(rtasUpdate); // does BLAS/TLAS builds ui.BeginFrame(); nuklear.BeginFrame(); diff --git a/code/renderer/crp_raytracing.cpp b/code/renderer/crp_raytracing.cpp index aa76942..d448731 100644 --- a/code/renderer/crp_raytracing.cpp +++ b/code/renderer/crp_raytracing.cpp @@ -47,8 +47,6 @@ struct BLASBuilder BLASMesh* traceMeshes; }; -static world_t* s_world; - static bool IsStaticBLASSurface(const msurface_t* surf) { if(surf->shader->numStages == 0 || @@ -205,23 +203,31 @@ void Raytracing::Init() void Raytracing::ProcessWorld(world_t& world) { - if(!rhiInfo.hasInlineRaytracing) + if(rhiInfo.hasInlineRaytracing) + { + pendingWorldProcess = true; + } +} + +void Raytracing::ProcessStaticSurfaces() +{ + if(!rhiInfo.hasInlineRaytracing || + !pendingWorldProcess || + tr.world == NULL) { return; } + pendingWorldProcess = false; - TagMapSurfacesRecursively(world.nodes); + TagMapSurfacesRecursively(tr.world->nodes); BLASBuilder staticBLASes[BLASBucket::Count]; WorldSurfaceList surfaceList; - s_world = &world; BuildBLASes(staticBLASBuffers, staticBLASes, &surfaceList); - s_world = NULL; FrameData& fd = frameData[GetRTFrameIndex()]; // create ASes - BeginTempCommandList(); for(uint32_t i = 0; i < BLASBucket::Count; i++) { BLASBuilder& bucket = staticBLASes[i]; @@ -239,7 +245,6 @@ void Raytracing::ProcessWorld(world_t& world) desc.meshCount = bucket.meshCount; CmdCreateBLAS(&staticBLASBuffers[i].blasBuffer, desc); } - EndTempCommandList(); for(uint32_t i = 0; i < BLASBucket::Count; i++) { BLASBuilder& bucket = staticBLASes[i]; @@ -274,15 +279,76 @@ void Raytracing::ProcessWorld(world_t& world) } } -void Raytracing::BeginFrame(bool wantUpdate) +void Raytracing::BeforeFrame(bool wantUpdate) { - if(!rhiInfo.hasInlineRaytracing) + if(!rhiInfo.hasInlineRaytracing || + tr.world == NULL || + tr.sceneCounterRT == 0 || + pendingWorldProcess) { return; } - if(tr.world == NULL || tr.sceneCounterRT == 0) + frameCount++; + + FrameData& fd = frameData[GetRTFrameIndex()]; + + TLASInstance* traceInstances = (TLASInstance*)BeginBufferUpload(fd.tlasInstanceBuffer); + uint32_t instanceId = 0; + for(uint32_t i = 0; i < ARRAY_LEN(staticBLASBuffers); i++) { + const BLASBuffers& buffers = staticBLASBuffers[i]; + if(IsNullHandle(buffers.blasBuffer)) + { + continue; + } + + Q_assert(instanceId == tlasInstanceDescs[instanceId].instanceId); + TLASInstance traceInst = {}; + traceInst.meshBufferIndex = GetBufferIndexSRV(buffers.meshBuffer); + traceInst.vertexBufferIndex = GetBufferIndexSRV(buffers.vertexBuffer); + traceInst.indexBufferIndex = GetBufferIndexSRV(buffers.indexBuffer); + traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; + *traceInstances++ = traceInst; + } + for(uint32_t i = 0; i < ARRAY_LEN(fd.dynamicBLASBuffers); i++) + { + const BLASBuffers& buffers = fd.dynamicBLASBuffers[i]; + if(IsNullHandle(buffers.blasBuffer)) + { + continue; + } + + Q_assert(instanceId == tlasInstanceDescs[instanceId].instanceId); + TLASInstance traceInst = {}; + traceInst.meshBufferIndex = GetBufferIndexSRV(buffers.meshBuffer); + traceInst.vertexBufferIndex = GetBufferIndexSRV(buffers.vertexBuffer); + traceInst.indexBufferIndex = GetBufferIndexSRV(buffers.indexBuffer); + traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; + *traceInstances++ = traceInst; + } + EndBufferUpload(fd.tlasInstanceBuffer); + +#if defined(_DEBUG) + for(uint32_t i = 0; i < tlasInstanceDescs.count; i++) + { + Q_assert(tlasInstanceDescs[i].instanceId == i); + } +#endif +} + +void Raytracing::BeginFrame(bool wantUpdate) +{ + if(!rhiInfo.hasInlineRaytracing || + tr.world == NULL || + tr.sceneCounterRT == 0) + { + return; + } + + if(pendingWorldProcess) + { + ProcessStaticSurfaces(); return; } @@ -296,7 +362,6 @@ void Raytracing::BeginFrame(bool wantUpdate) backEnd.refdef = tr.rtRefdef; - BeginTempCommandList(); const uint32_t renderPass = srp.BeginRenderPass("RTAS Build", 1.0f, 1.0f, 1.0f); BLASBuilder dynamicBLASes[BLASBucket::Count]; DynamicSurfaceList surfaceList; @@ -346,50 +411,6 @@ void Raytracing::BeginFrame(bool wantUpdate) CmdCreateTLAS(&fd.tlasBuffer, desc); } srp.EndRenderPass(renderPass); - EndTempCommandList(); - - TLASInstance* traceInstances = (TLASInstance*)BeginBufferUpload(fd.tlasInstanceBuffer); - uint32_t instanceId = 0; - for(uint32_t i = 0; i < ARRAY_LEN(staticBLASBuffers); i++) - { - const BLASBuffers& buffers = staticBLASBuffers[i]; - if(IsNullHandle(buffers.blasBuffer)) - { - continue; - } - - Q_assert(instanceId == tlasInstanceDescs[instanceId].instanceId); - TLASInstance traceInst = {}; - traceInst.meshBufferIndex = GetBufferIndexSRV(buffers.meshBuffer); - traceInst.vertexBufferIndex = GetBufferIndexSRV(buffers.vertexBuffer); - traceInst.indexBufferIndex = GetBufferIndexSRV(buffers.indexBuffer); - traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; - *traceInstances++ = traceInst; - } - for(uint32_t i = 0; i < ARRAY_LEN(fd.dynamicBLASBuffers); i++) - { - const BLASBuffers& buffers = fd.dynamicBLASBuffers[i]; - if(IsNullHandle(buffers.blasBuffer)) - { - continue; - } - - Q_assert(instanceId == tlasInstanceDescs[instanceId].instanceId); - TLASInstance traceInst = {}; - traceInst.meshBufferIndex = GetBufferIndexSRV(buffers.meshBuffer); - traceInst.vertexBufferIndex = GetBufferIndexSRV(buffers.vertexBuffer); - traceInst.indexBufferIndex = GetBufferIndexSRV(buffers.indexBuffer); - traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; - *traceInstances++ = traceInst; - } - EndBufferUpload(fd.tlasInstanceBuffer); - -#if defined(_DEBUG) - for(uint32_t i = 0; i < tlasInstanceDescs.count; i++) - { - Q_assert(tlasInstanceDescs[i].instanceId == i); - } -#endif } void Raytracing::TagMapSurfacesRecursively(mnode_t* node) @@ -636,14 +657,14 @@ void Raytracing::BuildBLASes(BLASBuffers* blasBuffers, BLASBuilder* blasBuilders uint32_t Raytracing::WorldSurfaceList::GetSurfaceCount() { - return s_world->numsurfaces; + return tr.world->numsurfaces; } bool Raytracing::WorldSurfaceList::GetSurface(Surface& surface, uint32_t index) { - Q_assert(index < (uint32_t)s_world->numsurfaces); + Q_assert(index < (uint32_t)tr.world->numsurfaces); - const msurface_t& surf = s_world->surfaces[index]; + const msurface_t& surf = tr.world->surfaces[index]; if(surf.rtSurfType != RTST_STATIC || surf.shader->numStages <= 0) { return true; diff --git a/code/renderer/rhi_d3d12.cpp b/code/renderer/rhi_d3d12.cpp index b343939..22a5346 100644 --- a/code/renderer/rhi_d3d12.cpp +++ b/code/renderer/rhi_d3d12.cpp @@ -5745,8 +5745,6 @@ namespace RHI void CmdCreateBLAS(HBuffer* blasBuffer, const BLASDesc& rhiDesc) { ASSERT_DR_ENABLED(); - Q_assert(rhi.commandList == rhi.tempCommandList); - Q_assert(rhi.tempCommandListOpen); Q_assert(blasBuffer); Q_assert(!IsNullHandle(rhiDesc.vertexBuffer)); Q_assert(!IsNullHandle(rhiDesc.indexBuffer)); @@ -5831,8 +5829,6 @@ namespace RHI void CmdCreateTLAS(HBuffer* tlasBuffer, const TLASDesc& rhiDesc) { ASSERT_DR_ENABLED(); - Q_assert(rhi.commandList == rhi.tempCommandList); - Q_assert(rhi.tempCommandListOpen); Q_assert(tlasBuffer != NULL); Q_assert(rhiDesc.instances); Q_assert(rhiDesc.instanceCount > 0);