mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-12 23:44:29 +00:00
fixed RTAS build crash due to missing cross queue sync
This commit is contained in:
parent
4955060c9f
commit
16a51506c0
4 changed files with 101 additions and 72 deletions
|
@ -329,13 +329,27 @@ struct Raytracing
|
||||||
{
|
{
|
||||||
void Init();
|
void Init();
|
||||||
void ProcessWorld(world_t& world);
|
void ProcessWorld(world_t& world);
|
||||||
|
void BeforeFrame(bool wantUpdate);
|
||||||
void BeginFrame(bool wantUpdate);
|
void BeginFrame(bool wantUpdate);
|
||||||
uint32_t GetTLASBufferIndex();
|
uint32_t GetTLASBufferIndex();
|
||||||
uint32_t GetInstanceBufferIndex();
|
uint32_t GetInstanceBufferIndex();
|
||||||
bool CanRaytrace();
|
bool CanRaytrace();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct BLASBuildBuffers;
|
||||||
|
struct BLASBuffers;
|
||||||
|
struct ISurfaceList;
|
||||||
void TagMapSurfacesRecursively(mnode_t* node);
|
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
|
struct BLASBucket
|
||||||
{
|
{
|
||||||
|
@ -389,10 +403,6 @@ private:
|
||||||
bool GetSurface(Surface& surface, uint32_t index) override;
|
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
|
struct FrameData
|
||||||
{
|
{
|
||||||
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {};
|
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {};
|
||||||
|
@ -401,14 +411,15 @@ private:
|
||||||
HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
|
HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Constants { RTFrameCount = RHI::FrameCount + 1 };
|
|
||||||
|
|
||||||
uint32_t GetRTFrameIndex() { return tr.frameCount % RTFrameCount; }
|
|
||||||
|
|
||||||
FrameData frameData[RTFrameCount];
|
FrameData frameData[RTFrameCount];
|
||||||
BLASBuffers staticBLASBuffers[BLASBucket::Count] = {};
|
BLASBuffers staticBLASBuffers[BLASBucket::Count] = {};
|
||||||
StaticArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs;
|
StaticArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs;
|
||||||
uint32_t staticTLASInstanceCount = 0;
|
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
|
struct SunlightEditor
|
||||||
|
|
|
@ -630,9 +630,10 @@ void CRP::BeginFrame()
|
||||||
dynamicLights.WantRTASUpdate(tr.rtRefdef) ||
|
dynamicLights.WantRTASUpdate(tr.rtRefdef) ||
|
||||||
sunlight.WantRTASUpdate(tr.rtRefdef) ||
|
sunlight.WantRTASUpdate(tr.rtRefdef) ||
|
||||||
volumetricLight.WantRTASUpdate(tr.rtRefdef);
|
volumetricLight.WantRTASUpdate(tr.rtRefdef);
|
||||||
raytracing.BeginFrame(rtasUpdate);
|
raytracing.BeforeFrame(rtasUpdate); // uploads data
|
||||||
|
|
||||||
RHI::BeginFrame();
|
RHI::BeginFrame();
|
||||||
|
raytracing.BeginFrame(rtasUpdate); // does BLAS/TLAS builds
|
||||||
ui.BeginFrame();
|
ui.BeginFrame();
|
||||||
nuklear.BeginFrame();
|
nuklear.BeginFrame();
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,6 @@ struct BLASBuilder
|
||||||
BLASMesh* traceMeshes;
|
BLASMesh* traceMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
static world_t* s_world;
|
|
||||||
|
|
||||||
static bool IsStaticBLASSurface(const msurface_t* surf)
|
static bool IsStaticBLASSurface(const msurface_t* surf)
|
||||||
{
|
{
|
||||||
if(surf->shader->numStages == 0 ||
|
if(surf->shader->numStages == 0 ||
|
||||||
|
@ -205,23 +203,31 @@ void Raytracing::Init()
|
||||||
|
|
||||||
void Raytracing::ProcessWorld(world_t& world)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
pendingWorldProcess = false;
|
||||||
|
|
||||||
TagMapSurfacesRecursively(world.nodes);
|
TagMapSurfacesRecursively(tr.world->nodes);
|
||||||
|
|
||||||
BLASBuilder staticBLASes[BLASBucket::Count];
|
BLASBuilder staticBLASes[BLASBucket::Count];
|
||||||
WorldSurfaceList surfaceList;
|
WorldSurfaceList surfaceList;
|
||||||
s_world = &world;
|
|
||||||
BuildBLASes(staticBLASBuffers, staticBLASes, &surfaceList);
|
BuildBLASes(staticBLASBuffers, staticBLASes, &surfaceList);
|
||||||
s_world = NULL;
|
|
||||||
|
|
||||||
FrameData& fd = frameData[GetRTFrameIndex()];
|
FrameData& fd = frameData[GetRTFrameIndex()];
|
||||||
|
|
||||||
// create ASes
|
// create ASes
|
||||||
BeginTempCommandList();
|
|
||||||
for(uint32_t i = 0; i < BLASBucket::Count; i++)
|
for(uint32_t i = 0; i < BLASBucket::Count; i++)
|
||||||
{
|
{
|
||||||
BLASBuilder& bucket = staticBLASes[i];
|
BLASBuilder& bucket = staticBLASes[i];
|
||||||
|
@ -239,7 +245,6 @@ void Raytracing::ProcessWorld(world_t& world)
|
||||||
desc.meshCount = bucket.meshCount;
|
desc.meshCount = bucket.meshCount;
|
||||||
CmdCreateBLAS(&staticBLASBuffers[i].blasBuffer, desc);
|
CmdCreateBLAS(&staticBLASBuffers[i].blasBuffer, desc);
|
||||||
}
|
}
|
||||||
EndTempCommandList();
|
|
||||||
for(uint32_t i = 0; i < BLASBucket::Count; i++)
|
for(uint32_t i = 0; i < BLASBucket::Count; i++)
|
||||||
{
|
{
|
||||||
BLASBuilder& bucket = staticBLASes[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;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +362,6 @@ void Raytracing::BeginFrame(bool wantUpdate)
|
||||||
|
|
||||||
backEnd.refdef = tr.rtRefdef;
|
backEnd.refdef = tr.rtRefdef;
|
||||||
|
|
||||||
BeginTempCommandList();
|
|
||||||
const uint32_t renderPass = srp.BeginRenderPass("RTAS Build", 1.0f, 1.0f, 1.0f);
|
const uint32_t renderPass = srp.BeginRenderPass("RTAS Build", 1.0f, 1.0f, 1.0f);
|
||||||
BLASBuilder dynamicBLASes[BLASBucket::Count];
|
BLASBuilder dynamicBLASes[BLASBucket::Count];
|
||||||
DynamicSurfaceList surfaceList;
|
DynamicSurfaceList surfaceList;
|
||||||
|
@ -346,50 +411,6 @@ void Raytracing::BeginFrame(bool wantUpdate)
|
||||||
CmdCreateTLAS(&fd.tlasBuffer, desc);
|
CmdCreateTLAS(&fd.tlasBuffer, desc);
|
||||||
}
|
}
|
||||||
srp.EndRenderPass(renderPass);
|
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)
|
void Raytracing::TagMapSurfacesRecursively(mnode_t* node)
|
||||||
|
@ -636,14 +657,14 @@ void Raytracing::BuildBLASes(BLASBuffers* blasBuffers, BLASBuilder* blasBuilders
|
||||||
|
|
||||||
uint32_t Raytracing::WorldSurfaceList::GetSurfaceCount()
|
uint32_t Raytracing::WorldSurfaceList::GetSurfaceCount()
|
||||||
{
|
{
|
||||||
return s_world->numsurfaces;
|
return tr.world->numsurfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Raytracing::WorldSurfaceList::GetSurface(Surface& surface, uint32_t index)
|
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)
|
if(surf.rtSurfType != RTST_STATIC || surf.shader->numStages <= 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5745,8 +5745,6 @@ namespace RHI
|
||||||
void CmdCreateBLAS(HBuffer* blasBuffer, const BLASDesc& rhiDesc)
|
void CmdCreateBLAS(HBuffer* blasBuffer, const BLASDesc& rhiDesc)
|
||||||
{
|
{
|
||||||
ASSERT_DR_ENABLED();
|
ASSERT_DR_ENABLED();
|
||||||
Q_assert(rhi.commandList == rhi.tempCommandList);
|
|
||||||
Q_assert(rhi.tempCommandListOpen);
|
|
||||||
Q_assert(blasBuffer);
|
Q_assert(blasBuffer);
|
||||||
Q_assert(!IsNullHandle(rhiDesc.vertexBuffer));
|
Q_assert(!IsNullHandle(rhiDesc.vertexBuffer));
|
||||||
Q_assert(!IsNullHandle(rhiDesc.indexBuffer));
|
Q_assert(!IsNullHandle(rhiDesc.indexBuffer));
|
||||||
|
@ -5831,8 +5829,6 @@ namespace RHI
|
||||||
void CmdCreateTLAS(HBuffer* tlasBuffer, const TLASDesc& rhiDesc)
|
void CmdCreateTLAS(HBuffer* tlasBuffer, const TLASDesc& rhiDesc)
|
||||||
{
|
{
|
||||||
ASSERT_DR_ENABLED();
|
ASSERT_DR_ENABLED();
|
||||||
Q_assert(rhi.commandList == rhi.tempCommandList);
|
|
||||||
Q_assert(rhi.tempCommandListOpen);
|
|
||||||
Q_assert(tlasBuffer != NULL);
|
Q_assert(tlasBuffer != NULL);
|
||||||
Q_assert(rhiDesc.instances);
|
Q_assert(rhiDesc.instances);
|
||||||
Q_assert(rhiDesc.instanceCount > 0);
|
Q_assert(rhiDesc.instanceCount > 0);
|
||||||
|
|
Loading…
Reference in a new issue