fixed RTAS build crashes, skipping the sky

This commit is contained in:
myT 2024-03-29 01:00:29 +01:00
parent aef3beb203
commit 14f9d18075
2 changed files with 67 additions and 30 deletions

View file

@ -397,14 +397,23 @@ private:
void EnsureBuffersAreLargeEnough(BLASBuildBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount); void EnsureBuffersAreLargeEnough(BLASBuildBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount);
void EnsureBuffersAreLargeEnough(BLASBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount, uint32_t maxMeshCount); void EnsureBuffersAreLargeEnough(BLASBuffers& buffers, uint32_t maxVertexCount, uint32_t maxIndexCount, uint32_t maxMeshCount);
void BuildBLASes(BLASBuffers* blasBuffers, struct BLASBuilder* blasBuilders, ISurfaceList* surfaceList); void BuildBLASes(BLASBuffers* blasBuffers, struct BLASBuilder* blasBuilders, ISurfaceList* surfaceList);
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {}; struct FrameData
{
BLASBuildBuffers blasBuildBuffers[BLASBucket::Count] = {};
BLASBuffers dynamicBLASBuffers[BLASBucket::Count] = {};
HBuffer tlasBuffer = 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];
BLASBuffers staticBLASBuffers[BLASBucket::Count] = {}; BLASBuffers staticBLASBuffers[BLASBucket::Count] = {};
BLASBuffers dynamicBLASBuffers[BLASBucket::Count] = {};
StaticUnorderedArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs; StaticUnorderedArray<TLASInstanceDesc, 2 * BLASBucket::Count> tlasInstanceDescs;
uint32_t staticTLASInstanceCount = 0; uint32_t staticTLASInstanceCount = 0;
HBuffer tlasBuffer = RHI_MAKE_NULL_HANDLE();
HBuffer tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
}; };
struct BaseBufferId struct BaseBufferId

View file

@ -167,25 +167,40 @@ static void CreateOrGrowBuffer(HBuffer& buffer, uint32_t& curByteCount, const Bu
void Raytracing::Init() void Raytracing::Init()
{ {
// make sure we're not trying to use deleted buffers after a video restart // make sure we're not trying to use deleted buffers after a video restart
for(uint32_t f = 0; f < RTFrameCount; f++)
{
FrameData& fd = frameData[f];
for(uint32_t i = 0; i < BLASBucket::Count; i++)
{
fd.blasBuildBuffers[i] = {};
fd.dynamicBLASBuffers[i] = {};
}
fd.tlasBuffer = RHI_MAKE_NULL_HANDLE();
}
for(uint32_t i = 0; i < BLASBucket::Count; i++) for(uint32_t i = 0; i < BLASBucket::Count; i++)
{ {
blasBuildBuffers[i] = {};
staticBLASBuffers[i] = {}; staticBLASBuffers[i] = {};
dynamicBLASBuffers[i] = {};
} }
tlasBuffer = RHI_MAKE_NULL_HANDLE();
if(!rhiInfo.hasInlineRaytracing) if(!rhiInfo.hasInlineRaytracing)
{ {
tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE(); for(uint32_t f = 0; f < RTFrameCount; f++)
{
FrameData& fd = frameData[f];
fd.tlasInstanceBuffer = RHI_MAKE_NULL_HANDLE();
}
return; return;
} }
const uint32_t structByteCount = sizeof(TLASInstance); for(uint32_t f = 0; f < RTFrameCount; f++)
BufferDesc desc("BLAS support instance", 2 * BLASBucket::Count * structByteCount, ResourceStates::ShaderAccessBits); {
desc.shortLifeTime = true; FrameData& fd = frameData[f];
desc.structureByteCount = structByteCount; const uint32_t structByteCount = sizeof(TLASInstance);
tlasInstanceBuffer = CreateBuffer(desc); BufferDesc desc("BLAS support instance", 2 * BLASBucket::Count * structByteCount, ResourceStates::ShaderAccessBits);
desc.shortLifeTime = true;
desc.structureByteCount = structByteCount;
fd.tlasInstanceBuffer = CreateBuffer(desc);
}
} }
void Raytracing::ProcessWorld(world_t& world) void Raytracing::ProcessWorld(world_t& world)
@ -203,6 +218,8 @@ void Raytracing::ProcessWorld(world_t& world)
BuildBLASes(staticBLASBuffers, staticBLASes, &surfaceList); BuildBLASes(staticBLASBuffers, staticBLASes, &surfaceList);
s_world = NULL; s_world = NULL;
FrameData& fd = frameData[GetRTFrameIndex()];
// create ASes // create ASes
BeginTempCommandList(); BeginTempCommandList();
for(uint32_t i = 0; i < BLASBucket::Count; i++) for(uint32_t i = 0; i < BLASBucket::Count; i++)
@ -213,7 +230,7 @@ void Raytracing::ProcessWorld(world_t& world)
continue; continue;
} }
BLASBuildBuffers& buffers = blasBuildBuffers[i]; BLASBuildBuffers& buffers = fd.blasBuildBuffers[i];
BLASDesc desc = {}; BLASDesc desc = {};
desc.name = va("static BLAS %s", GetBLASBucketName(i)); desc.name = va("static BLAS %s", GetBLASBucketName(i));
desc.vertexBuffer = buffers.vertexBuffer; desc.vertexBuffer = buffers.vertexBuffer;
@ -269,8 +286,10 @@ void Raytracing::BeginFrame(bool wantUpdate)
return; return;
} }
FrameData& fd = frameData[GetRTFrameIndex()];
if((crp_updateRTAS->integer == 0 || !wantUpdate) && if((crp_updateRTAS->integer == 0 || !wantUpdate) &&
!IsNullHandle(tlasBuffer)) !IsNullHandle(fd.tlasBuffer))
{ {
return; return;
} }
@ -281,7 +300,7 @@ void Raytracing::BeginFrame(bool wantUpdate)
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;
BuildBLASes(dynamicBLASBuffers, dynamicBLASes, &surfaceList); BuildBLASes(fd.dynamicBLASBuffers, dynamicBLASes, &surfaceList);
for(uint32_t i = 0; i < BLASBucket::Count; i++) for(uint32_t i = 0; i < BLASBucket::Count; i++)
{ {
BLASBuilder& bucket = dynamicBLASes[i]; BLASBuilder& bucket = dynamicBLASes[i];
@ -290,14 +309,14 @@ void Raytracing::BeginFrame(bool wantUpdate)
continue; continue;
} }
BLASBuildBuffers& buffers = blasBuildBuffers[i]; BLASBuildBuffers& buffers = fd.blasBuildBuffers[i];
BLASDesc desc = {}; BLASDesc desc = {};
desc.name = va("dynamic BLAS %s", GetBLASBucketName(i)); desc.name = va("dynamic BLAS %s", GetBLASBucketName(i));
desc.vertexBuffer = buffers.vertexBuffer; desc.vertexBuffer = buffers.vertexBuffer;
desc.indexBuffer = buffers.indexBuffer; desc.indexBuffer = buffers.indexBuffer;
desc.meshes = bucket.buildMeshes; desc.meshes = bucket.buildMeshes;
desc.meshCount = bucket.meshCount; desc.meshCount = bucket.meshCount;
CmdCreateBLAS(&dynamicBLASBuffers[i].blasBuffer, desc); CmdCreateBLAS(&fd.dynamicBLASBuffers[i].blasBuffer, desc);
} }
{ {
uint32_t instanceId = staticTLASInstanceCount; uint32_t instanceId = staticTLASInstanceCount;
@ -311,7 +330,7 @@ void Raytracing::BeginFrame(bool wantUpdate)
} }
TLASInstanceDesc inst = {}; TLASInstanceDesc inst = {};
inst.blasBuffer = dynamicBLASBuffers[i].blasBuffer; inst.blasBuffer = fd.dynamicBLASBuffers[i].blasBuffer;
inst.cullMode = (cullType_t)i; inst.cullMode = (cullType_t)i;
inst.instanceId = instanceId++; inst.instanceId = instanceId++;
inst.instanceMask = 0xFF; inst.instanceMask = 0xFF;
@ -324,12 +343,12 @@ void Raytracing::BeginFrame(bool wantUpdate)
TLASDesc desc = {}; TLASDesc desc = {};
desc.instanceCount = tlasInstanceDescs.count; desc.instanceCount = tlasInstanceDescs.count;
desc.instances = tlasInstanceDescs.items; desc.instances = tlasInstanceDescs.items;
CmdCreateTLAS(&tlasBuffer, desc); CmdCreateTLAS(&fd.tlasBuffer, desc);
} }
srp.EndRenderPass(renderPass); srp.EndRenderPass(renderPass);
EndTempCommandList(); EndTempCommandList();
TLASInstance* traceInstances = (TLASInstance*)BeginBufferUpload(tlasInstanceBuffer); TLASInstance* traceInstances = (TLASInstance*)BeginBufferUpload(fd.tlasInstanceBuffer);
uint32_t instanceId = 0; uint32_t instanceId = 0;
for(uint32_t i = 0; i < ARRAY_LEN(staticBLASBuffers); i++) for(uint32_t i = 0; i < ARRAY_LEN(staticBLASBuffers); i++)
{ {
@ -347,9 +366,9 @@ void Raytracing::BeginFrame(bool wantUpdate)
traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode;
*traceInstances++ = traceInst; *traceInstances++ = traceInst;
} }
for(uint32_t i = 0; i < ARRAY_LEN(dynamicBLASBuffers); i++) for(uint32_t i = 0; i < ARRAY_LEN(fd.dynamicBLASBuffers); i++)
{ {
const BLASBuffers& buffers = dynamicBLASBuffers[i]; const BLASBuffers& buffers = fd.dynamicBLASBuffers[i];
if(IsNullHandle(buffers.blasBuffer)) if(IsNullHandle(buffers.blasBuffer))
{ {
continue; continue;
@ -363,7 +382,7 @@ void Raytracing::BeginFrame(bool wantUpdate)
traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode; traceInst.cullMode = (uint32_t)tlasInstanceDescs[instanceId++].cullMode;
*traceInstances++ = traceInst; *traceInstances++ = traceInst;
} }
EndBufferUpload(tlasInstanceBuffer); EndBufferUpload(fd.tlasInstanceBuffer);
#if defined(_DEBUG) #if defined(_DEBUG)
for(uint32_t i = 0; i < tlasInstanceDescs.count; i++) for(uint32_t i = 0; i < tlasInstanceDescs.count; i++)
@ -396,6 +415,11 @@ void Raytracing::TagMapSurfacesRecursively(mnode_t* node)
while(c--) while(c--)
{ {
msurface_t* const surf = *mark++; msurface_t* const surf = *mark++;
if(surf->shader->isSky)
{
continue;
}
if(IsStaticBLASSurface(surf)) if(IsStaticBLASSurface(surf))
{ {
surf->rtSurfType = RTST_STATIC; surf->rtSurfType = RTST_STATIC;
@ -455,6 +479,8 @@ void Raytracing::BuildBLASes(BLASBuffers* blasBuffers, BLASBuilder* blasBuilders
const double originalTime = backEnd.refdef.floatTime; const double originalTime = backEnd.refdef.floatTime;
FrameData& fd = frameData[GetRTFrameIndex()];
// gather stats on all surfaces we can bake // gather stats on all surfaces we can bake
for(uint32_t i = 0, count = surfaceList->GetSurfaceCount(); i < count; i++) for(uint32_t i = 0, count = surfaceList->GetSurfaceCount(); i < count; i++)
{ {
@ -496,14 +522,14 @@ void Raytracing::BuildBLASes(BLASBuffers* blasBuffers, BLASBuilder* blasBuilders
continue; continue;
} }
EnsureBuffersAreLargeEnough(blasBuildBuffers[i], bucket.totalVertexCount, bucket.totalIndexCount); EnsureBuffersAreLargeEnough(fd.blasBuildBuffers[i], bucket.totalVertexCount, bucket.totalIndexCount);
bucket.buildMeshes = (BLASMeshDesc*)malloc(bucket.meshCount * sizeof(BLASMeshDesc)); bucket.buildMeshes = (BLASMeshDesc*)malloc(bucket.meshCount * sizeof(BLASMeshDesc));
if(bucket.buildMeshes == NULL) if(bucket.buildMeshes == NULL)
{ {
ri.Error(ERR_FATAL, "Failed to allocate %d BLASMeshDesc instances\n", (int)bucket.meshCount); ri.Error(ERR_FATAL, "Failed to allocate %d BLASMeshDesc instances\n", (int)bucket.meshCount);
} }
bucket.buildVertices = (float*)BeginBufferUpload(blasBuildBuffers[i].vertexBuffer); bucket.buildVertices = (float*)BeginBufferUpload(fd.blasBuildBuffers[i].vertexBuffer);
bucket.buildIndices = (uint32_t*)BeginBufferUpload(blasBuildBuffers[i].indexBuffer); bucket.buildIndices = (uint32_t*)BeginBufferUpload(fd.blasBuildBuffers[i].indexBuffer);
EnsureBuffersAreLargeEnough(blasBuffers[i], bucket.totalVertexCount, bucket.totalIndexCount, bucket.meshCount); EnsureBuffersAreLargeEnough(blasBuffers[i], bucket.totalVertexCount, bucket.totalIndexCount, bucket.meshCount);
bucket.traceVertices = (BLASVertex*)BeginBufferUpload(blasBuffers[i].vertexBuffer); bucket.traceVertices = (BLASVertex*)BeginBufferUpload(blasBuffers[i].vertexBuffer);
@ -591,8 +617,8 @@ void Raytracing::BuildBLASes(BLASBuffers* blasBuffers, BLASBuilder* blasBuilders
continue; continue;
} }
EndBufferUpload(blasBuildBuffers[i].vertexBuffer); EndBufferUpload(fd.blasBuildBuffers[i].vertexBuffer);
EndBufferUpload(blasBuildBuffers[i].indexBuffer); EndBufferUpload(fd.blasBuildBuffers[i].indexBuffer);
bucket.buildVertices = NULL; bucket.buildVertices = NULL;
bucket.buildIndices = NULL; bucket.buildIndices = NULL;
@ -670,6 +696,7 @@ bool Raytracing::DynamicSurfaceList::GetSurface(Surface& surface, uint32_t index
uint32_t Raytracing::GetTLASBufferIndex() uint32_t Raytracing::GetTLASBufferIndex()
{ {
const HBuffer tlasBuffer = frameData[GetRTFrameIndex()].tlasBuffer;
if(IsNullHandle(tlasBuffer)) if(IsNullHandle(tlasBuffer))
{ {
return 0; return 0;
@ -680,6 +707,7 @@ uint32_t Raytracing::GetTLASBufferIndex()
uint32_t Raytracing::GetInstanceBufferIndex() uint32_t Raytracing::GetInstanceBufferIndex()
{ {
const HBuffer tlasInstanceBuffer = frameData[GetRTFrameIndex()].tlasInstanceBuffer;
if(IsNullHandle(tlasInstanceBuffer)) if(IsNullHandle(tlasInstanceBuffer))
{ {
return 0; return 0;