mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Ring buffered the path tracer.
This commit is contained in:
+437
-92
@@ -332,22 +332,51 @@ static D3D12_GPU_DESCRIPTOR_HANDLE glRaytracingOffsetGpu(D3D12_GPU_DESCRIPTOR_HA
|
|||||||
// Shared command context
|
// Shared command context
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
|
#ifndef GL_RAYTRACING_CMD_RING_SIZE
|
||||||
|
#define GL_RAYTRACING_CMD_RING_SIZE 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GL_RAYTRACING_CMD_RING_SIZE < 2
|
||||||
|
#error GL_RAYTRACING_CMD_RING_SIZE must be at least 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL_RAYTRACING_FORCE_CPU_SYNC
|
||||||
|
#define GL_RAYTRACING_FORCE_CPU_SYNC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
struct glRaytracingCmdContext_t
|
struct glRaytracingCmdContext_t
|
||||||
{
|
{
|
||||||
ComPtr<ID3D12Device5> device;
|
ComPtr<ID3D12Device5> device;
|
||||||
ComPtr<ID3D12CommandQueue> queue;
|
ComPtr<ID3D12CommandQueue> queue;
|
||||||
|
|
||||||
|
// Active command allocator/list for the command currently being recorded.
|
||||||
|
// The ring below avoids the old every-frame CPU/GPU fence wait.
|
||||||
ComPtr<ID3D12CommandAllocator> cmdAlloc;
|
ComPtr<ID3D12CommandAllocator> cmdAlloc;
|
||||||
ComPtr<ID3D12GraphicsCommandList4> cmdList;
|
ComPtr<ID3D12GraphicsCommandList4> cmdList;
|
||||||
UINT64 cmdLastFenceValue;
|
UINT64 cmdLastFenceValue;
|
||||||
|
ComPtr<ID3D12CommandAllocator> cmdAllocRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
ComPtr<ID3D12GraphicsCommandList4> cmdListRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT64 cmdFenceValueRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT cmdRingIndex;
|
||||||
|
UINT cmdCurrentSlot;
|
||||||
|
|
||||||
ComPtr<ID3D12CommandAllocator> blasCmdAlloc;
|
ComPtr<ID3D12CommandAllocator> blasCmdAlloc;
|
||||||
ComPtr<ID3D12GraphicsCommandList4> blasCmdList;
|
ComPtr<ID3D12GraphicsCommandList4> blasCmdList;
|
||||||
UINT64 blasLastFenceValue;
|
UINT64 blasLastFenceValue;
|
||||||
|
ComPtr<ID3D12CommandAllocator> blasCmdAllocRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
ComPtr<ID3D12GraphicsCommandList4> blasCmdListRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT64 blasFenceValueRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT blasRingIndex;
|
||||||
|
UINT blasCurrentSlot;
|
||||||
|
|
||||||
ComPtr<ID3D12CommandAllocator> tlasCmdAlloc;
|
ComPtr<ID3D12CommandAllocator> tlasCmdAlloc;
|
||||||
ComPtr<ID3D12GraphicsCommandList4> tlasCmdList;
|
ComPtr<ID3D12GraphicsCommandList4> tlasCmdList;
|
||||||
UINT64 tlasLastFenceValue;
|
UINT64 tlasLastFenceValue;
|
||||||
|
ComPtr<ID3D12CommandAllocator> tlasCmdAllocRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
ComPtr<ID3D12GraphicsCommandList4> tlasCmdListRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT64 tlasFenceValueRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
UINT tlasRingIndex;
|
||||||
|
UINT tlasCurrentSlot;
|
||||||
|
|
||||||
ComPtr<ID3D12Fence> fence;
|
ComPtr<ID3D12Fence> fence;
|
||||||
HANDLE fenceEvent;
|
HANDLE fenceEvent;
|
||||||
@@ -359,6 +388,18 @@ struct glRaytracingCmdContext_t
|
|||||||
cmdLastFenceValue = 0;
|
cmdLastFenceValue = 0;
|
||||||
blasLastFenceValue = 0;
|
blasLastFenceValue = 0;
|
||||||
tlasLastFenceValue = 0;
|
tlasLastFenceValue = 0;
|
||||||
|
cmdRingIndex = GL_RAYTRACING_CMD_RING_SIZE - 1;
|
||||||
|
blasRingIndex = GL_RAYTRACING_CMD_RING_SIZE - 1;
|
||||||
|
tlasRingIndex = GL_RAYTRACING_CMD_RING_SIZE - 1;
|
||||||
|
cmdCurrentSlot = 0;
|
||||||
|
blasCurrentSlot = 0;
|
||||||
|
tlasCurrentSlot = 0;
|
||||||
|
for (UINT i = 0; i < GL_RAYTRACING_CMD_RING_SIZE; ++i)
|
||||||
|
{
|
||||||
|
cmdFenceValueRing[i] = 0;
|
||||||
|
blasFenceValueRing[i] = 0;
|
||||||
|
tlasFenceValueRing[i] = 0;
|
||||||
|
}
|
||||||
fenceEvent = nullptr;
|
fenceEvent = nullptr;
|
||||||
nextFenceValue = 0;
|
nextFenceValue = 0;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
@@ -396,6 +437,26 @@ static void glRaytracingWaitIdle(void)
|
|||||||
glRaytracingWaitFenceValue(value);
|
glRaytracingWaitFenceValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int glRaytracingCreateDirectCommandListPair(
|
||||||
|
ID3D12Device5* device,
|
||||||
|
ComPtr<ID3D12CommandAllocator>& allocator,
|
||||||
|
ComPtr<ID3D12GraphicsCommandList4>& list)
|
||||||
|
{
|
||||||
|
GLR_CHECK(device->CreateCommandAllocator(
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
IID_PPV_ARGS(&allocator)));
|
||||||
|
|
||||||
|
GLR_CHECK(device->CreateCommandList(
|
||||||
|
0,
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
allocator.Get(),
|
||||||
|
nullptr,
|
||||||
|
IID_PPV_ARGS(&list)));
|
||||||
|
|
||||||
|
GLR_CHECK(list->Close());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int glRaytracingInitCmdContext(void)
|
static int glRaytracingInitCmdContext(void)
|
||||||
{
|
{
|
||||||
ID3D12Device* baseDevice = QD3D12_GetDevice();
|
ID3D12Device* baseDevice = QD3D12_GetDevice();
|
||||||
@@ -429,44 +490,39 @@ static int glRaytracingInitCmdContext(void)
|
|||||||
GLR_CHECK(baseDevice->QueryInterface(IID_PPV_ARGS(&g_glRaytracingCmd.device)));
|
GLR_CHECK(baseDevice->QueryInterface(IID_PPV_ARGS(&g_glRaytracingCmd.device)));
|
||||||
g_glRaytracingCmd.queue = baseQueue;
|
g_glRaytracingCmd.queue = baseQueue;
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandAllocator(
|
for (UINT i = 0; i < GL_RAYTRACING_CMD_RING_SIZE; ++i)
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
{
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.cmdAlloc)));
|
if (!glRaytracingCreateDirectCommandListPair(
|
||||||
|
g_glRaytracingCmd.device.Get(),
|
||||||
|
g_glRaytracingCmd.cmdAllocRing[i],
|
||||||
|
g_glRaytracingCmd.cmdListRing[i]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandList(
|
if (!glRaytracingCreateDirectCommandListPair(
|
||||||
0,
|
g_glRaytracingCmd.device.Get(),
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
g_glRaytracingCmd.blasCmdAllocRing[i],
|
||||||
g_glRaytracingCmd.cmdAlloc.Get(),
|
g_glRaytracingCmd.blasCmdListRing[i]))
|
||||||
nullptr,
|
{
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.cmdList)));
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.cmdList->Close());
|
if (!glRaytracingCreateDirectCommandListPair(
|
||||||
|
g_glRaytracingCmd.device.Get(),
|
||||||
|
g_glRaytracingCmd.tlasCmdAllocRing[i],
|
||||||
|
g_glRaytracingCmd.tlasCmdListRing[i]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandAllocator(
|
g_glRaytracingCmd.cmdAlloc = g_glRaytracingCmd.cmdAllocRing[0];
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
g_glRaytracingCmd.cmdList = g_glRaytracingCmd.cmdListRing[0];
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.blasCmdAlloc)));
|
g_glRaytracingCmd.blasCmdAlloc = g_glRaytracingCmd.blasCmdAllocRing[0];
|
||||||
|
g_glRaytracingCmd.blasCmdList = g_glRaytracingCmd.blasCmdListRing[0];
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandList(
|
g_glRaytracingCmd.tlasCmdAlloc = g_glRaytracingCmd.tlasCmdAllocRing[0];
|
||||||
0,
|
g_glRaytracingCmd.tlasCmdList = g_glRaytracingCmd.tlasCmdListRing[0];
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
g_glRaytracingCmd.blasCmdAlloc.Get(),
|
|
||||||
nullptr,
|
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.blasCmdList)));
|
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.blasCmdList->Close());
|
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandAllocator(
|
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.tlasCmdAlloc)));
|
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateCommandList(
|
|
||||||
0,
|
|
||||||
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
|
||||||
g_glRaytracingCmd.tlasCmdAlloc.Get(),
|
|
||||||
nullptr,
|
|
||||||
IID_PPV_ARGS(&g_glRaytracingCmd.tlasCmdList)));
|
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.tlasCmdList->Close());
|
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateFence(
|
GLR_CHECK(g_glRaytracingCmd.device->CreateFence(
|
||||||
0,
|
0,
|
||||||
@@ -502,7 +558,13 @@ static void glRaytracingShutdownCmdContext(void)
|
|||||||
|
|
||||||
static int glRaytracingBeginCmd(void)
|
static int glRaytracingBeginCmd(void)
|
||||||
{
|
{
|
||||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.cmdLastFenceValue);
|
const UINT slot = (g_glRaytracingCmd.cmdRingIndex + 1u) % GL_RAYTRACING_CMD_RING_SIZE;
|
||||||
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.cmdFenceValueRing[slot]);
|
||||||
|
|
||||||
|
g_glRaytracingCmd.cmdRingIndex = slot;
|
||||||
|
g_glRaytracingCmd.cmdCurrentSlot = slot;
|
||||||
|
g_glRaytracingCmd.cmdAlloc = g_glRaytracingCmd.cmdAllocRing[slot];
|
||||||
|
g_glRaytracingCmd.cmdList = g_glRaytracingCmd.cmdListRing[slot];
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.cmdAlloc->Reset());
|
GLR_CHECK(g_glRaytracingCmd.cmdAlloc->Reset());
|
||||||
GLR_CHECK(g_glRaytracingCmd.cmdList->Reset(g_glRaytracingCmd.cmdAlloc.Get(), nullptr));
|
GLR_CHECK(g_glRaytracingCmd.cmdList->Reset(g_glRaytracingCmd.cmdAlloc.Get(), nullptr));
|
||||||
@@ -517,13 +579,24 @@ static int glRaytracingEndCmd(void)
|
|||||||
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
||||||
|
|
||||||
g_glRaytracingCmd.cmdLastFenceValue = glRaytracingSignalQueue();
|
g_glRaytracingCmd.cmdLastFenceValue = glRaytracingSignalQueue();
|
||||||
|
g_glRaytracingCmd.cmdFenceValueRing[g_glRaytracingCmd.cmdCurrentSlot] = g_glRaytracingCmd.cmdLastFenceValue;
|
||||||
|
|
||||||
|
#if GL_RAYTRACING_FORCE_CPU_SYNC
|
||||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.cmdLastFenceValue);
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.cmdLastFenceValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int glRaytracingBeginBlasCmd(void)
|
static int glRaytracingBeginBlasCmd(void)
|
||||||
{
|
{
|
||||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.blasLastFenceValue);
|
const UINT slot = (g_glRaytracingCmd.blasRingIndex + 1u) % GL_RAYTRACING_CMD_RING_SIZE;
|
||||||
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.blasFenceValueRing[slot]);
|
||||||
|
|
||||||
|
g_glRaytracingCmd.blasRingIndex = slot;
|
||||||
|
g_glRaytracingCmd.blasCurrentSlot = slot;
|
||||||
|
g_glRaytracingCmd.blasCmdAlloc = g_glRaytracingCmd.blasCmdAllocRing[slot];
|
||||||
|
g_glRaytracingCmd.blasCmdList = g_glRaytracingCmd.blasCmdListRing[slot];
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.blasCmdAlloc->Reset());
|
GLR_CHECK(g_glRaytracingCmd.blasCmdAlloc->Reset());
|
||||||
GLR_CHECK(g_glRaytracingCmd.blasCmdList->Reset(g_glRaytracingCmd.blasCmdAlloc.Get(), nullptr));
|
GLR_CHECK(g_glRaytracingCmd.blasCmdList->Reset(g_glRaytracingCmd.blasCmdAlloc.Get(), nullptr));
|
||||||
@@ -538,12 +611,24 @@ static UINT64 glRaytracingEndBlasCmd(void)
|
|||||||
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
||||||
|
|
||||||
g_glRaytracingCmd.blasLastFenceValue = glRaytracingSignalQueue();
|
g_glRaytracingCmd.blasLastFenceValue = glRaytracingSignalQueue();
|
||||||
|
g_glRaytracingCmd.blasFenceValueRing[g_glRaytracingCmd.blasCurrentSlot] = g_glRaytracingCmd.blasLastFenceValue;
|
||||||
|
|
||||||
|
#if GL_RAYTRACING_FORCE_CPU_SYNC
|
||||||
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.blasLastFenceValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
return g_glRaytracingCmd.blasLastFenceValue;
|
return g_glRaytracingCmd.blasLastFenceValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int glRaytracingBeginTlasCmd(void)
|
static int glRaytracingBeginTlasCmd(void)
|
||||||
{
|
{
|
||||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.tlasLastFenceValue);
|
const UINT slot = (g_glRaytracingCmd.tlasRingIndex + 1u) % GL_RAYTRACING_CMD_RING_SIZE;
|
||||||
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.tlasFenceValueRing[slot]);
|
||||||
|
|
||||||
|
g_glRaytracingCmd.tlasRingIndex = slot;
|
||||||
|
g_glRaytracingCmd.tlasCurrentSlot = slot;
|
||||||
|
g_glRaytracingCmd.tlasCmdAlloc = g_glRaytracingCmd.tlasCmdAllocRing[slot];
|
||||||
|
g_glRaytracingCmd.tlasCmdList = g_glRaytracingCmd.tlasCmdListRing[slot];
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.tlasCmdAlloc->Reset());
|
GLR_CHECK(g_glRaytracingCmd.tlasCmdAlloc->Reset());
|
||||||
GLR_CHECK(g_glRaytracingCmd.tlasCmdList->Reset(g_glRaytracingCmd.tlasCmdAlloc.Get(), nullptr));
|
GLR_CHECK(g_glRaytracingCmd.tlasCmdList->Reset(g_glRaytracingCmd.tlasCmdAlloc.Get(), nullptr));
|
||||||
@@ -558,6 +643,12 @@ static UINT64 glRaytracingEndTlasCmd(void)
|
|||||||
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
g_glRaytracingCmd.queue->ExecuteCommandLists(1, lists);
|
||||||
|
|
||||||
g_glRaytracingCmd.tlasLastFenceValue = glRaytracingSignalQueue();
|
g_glRaytracingCmd.tlasLastFenceValue = glRaytracingSignalQueue();
|
||||||
|
g_glRaytracingCmd.tlasFenceValueRing[g_glRaytracingCmd.tlasCurrentSlot] = g_glRaytracingCmd.tlasLastFenceValue;
|
||||||
|
|
||||||
|
#if GL_RAYTRACING_FORCE_CPU_SYNC
|
||||||
|
glRaytracingWaitFenceValue(g_glRaytracingCmd.tlasLastFenceValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
return g_glRaytracingCmd.tlasLastFenceValue;
|
return g_glRaytracingCmd.tlasLastFenceValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,6 +693,7 @@ struct glRaytracingMeshRecord_t
|
|||||||
|
|
||||||
int blasBuilt;
|
int blasBuilt;
|
||||||
int dirty;
|
int dirty;
|
||||||
|
UINT64 blasBuildFenceValue;
|
||||||
int currentBlasIndex;
|
int currentBlasIndex;
|
||||||
uint32_t materialFlags;
|
uint32_t materialFlags;
|
||||||
|
|
||||||
@@ -614,6 +706,7 @@ struct glRaytracingMeshRecord_t
|
|||||||
blasResultSize = 0;
|
blasResultSize = 0;
|
||||||
blasBuilt = 0;
|
blasBuilt = 0;
|
||||||
dirty = 0;
|
dirty = 0;
|
||||||
|
blasBuildFenceValue = 0;
|
||||||
currentBlasIndex = 0;
|
currentBlasIndex = 0;
|
||||||
materialFlags = 0;
|
materialFlags = 0;
|
||||||
}
|
}
|
||||||
@@ -669,6 +762,7 @@ struct glRaytracingRenderWorld_t
|
|||||||
uint32_t nextInstanceHandle;
|
uint32_t nextInstanceHandle;
|
||||||
|
|
||||||
glRaytracingSceneUploadBuffer_t instanceDescUpload[2];
|
glRaytracingSceneUploadBuffer_t instanceDescUpload[2];
|
||||||
|
UINT64 instanceDescUploadFenceValue[2];
|
||||||
glRaytracingBuffer_t tlasScratch;
|
glRaytracingBuffer_t tlasScratch;
|
||||||
glRaytracingBuffer_t tlasResult[2];
|
glRaytracingBuffer_t tlasResult[2];
|
||||||
|
|
||||||
@@ -688,6 +782,8 @@ struct glRaytracingRenderWorld_t
|
|||||||
handle = 0;
|
handle = 0;
|
||||||
alive = 0;
|
alive = 0;
|
||||||
nextInstanceHandle = 1;
|
nextInstanceHandle = 1;
|
||||||
|
instanceDescUploadFenceValue[0] = 0;
|
||||||
|
instanceDescUploadFenceValue[1] = 0;
|
||||||
tlasScratchSize = 0;
|
tlasScratchSize = 0;
|
||||||
tlasResultSize = 0;
|
tlasResultSize = 0;
|
||||||
activeInstanceCount = 0;
|
activeInstanceCount = 0;
|
||||||
@@ -736,6 +832,8 @@ static void glRaytracingReleaseWorldResources(glRaytracingRenderWorld_t* world)
|
|||||||
world->tlasResult[i].resource.Reset();
|
world->tlasResult[i].resource.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
world->instanceDescUploadFenceValue[0] = 0;
|
||||||
|
world->instanceDescUploadFenceValue[1] = 0;
|
||||||
world->tlasScratch.resource.Reset();
|
world->tlasScratch.resource.Reset();
|
||||||
world->tlasScratchSize = 0;
|
world->tlasScratchSize = 0;
|
||||||
world->tlasResultSize = 0;
|
world->tlasResultSize = 0;
|
||||||
@@ -804,6 +902,8 @@ static void glRaytracingClearWorldContents(glRaytracingRenderWorld_t* world)
|
|||||||
world->handle = handle;
|
world->handle = handle;
|
||||||
world->alive = alive;
|
world->alive = alive;
|
||||||
world->nextInstanceHandle = 1;
|
world->nextInstanceHandle = 1;
|
||||||
|
world->instanceDescUploadFenceValue[0] = 0;
|
||||||
|
world->instanceDescUploadFenceValue[1] = 0;
|
||||||
world->tlasScratchSize = 0;
|
world->tlasScratchSize = 0;
|
||||||
world->tlasResultSize = 0;
|
world->tlasResultSize = 0;
|
||||||
world->activeInstanceCount = 0;
|
world->activeInstanceCount = 0;
|
||||||
@@ -949,6 +1049,18 @@ static int glRaytracingEnsureTLASBuffers(
|
|||||||
prebuild.ResultDataMaxSizeInBytes,
|
prebuild.ResultDataMaxSizeInBytes,
|
||||||
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT);
|
D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BYTE_ALIGNMENT);
|
||||||
|
|
||||||
|
const bool resizingScratch = world->tlasScratch.resource &&
|
||||||
|
world->tlasScratchSize < requiredScratch;
|
||||||
|
const bool resizingResult = (world->tlasResult[0].resource || world->tlasResult[1].resource) &&
|
||||||
|
world->tlasResultSize < requiredResult;
|
||||||
|
if (resizingScratch || resizingResult)
|
||||||
|
{
|
||||||
|
// Releasing/reallocating a TLAS resource can invalidate an in-flight ray
|
||||||
|
// dispatch that still references the old resource. This resize path is rare,
|
||||||
|
// so prefer correctness over complex deferred destruction.
|
||||||
|
glRaytracingWaitIdle();
|
||||||
|
}
|
||||||
|
|
||||||
if (!world->tlasScratch.resource ||
|
if (!world->tlasScratch.resource ||
|
||||||
world->tlasScratchSize < requiredScratch)
|
world->tlasScratchSize < requiredScratch)
|
||||||
{
|
{
|
||||||
@@ -1061,6 +1173,7 @@ static int glRaytracingEnsureMeshScratch(glRaytracingMeshRecord_t* mesh, UINT64
|
|||||||
|
|
||||||
if (!mesh->blasScratch.resource || mesh->blasScratchSize < requiredScratch)
|
if (!mesh->blasScratch.resource || mesh->blasScratchSize < requiredScratch)
|
||||||
{
|
{
|
||||||
|
glRaytracingWaitFenceValue(mesh->blasBuildFenceValue);
|
||||||
mesh->blasScratch.resource.Reset();
|
mesh->blasScratch.resource.Reset();
|
||||||
mesh->blasScratch = glRaytracingCreateBuffer(
|
mesh->blasScratch = glRaytracingCreateBuffer(
|
||||||
g_glRaytracingCmd.device.Get(),
|
g_glRaytracingCmd.device.Get(),
|
||||||
@@ -1090,6 +1203,7 @@ static int glRaytracingEnsureMeshResultBuffers(glRaytracingMeshRecord_t* mesh, U
|
|||||||
{
|
{
|
||||||
if (!mesh->blasResult[i].resource || mesh->blasResultSize < requiredResult)
|
if (!mesh->blasResult[i].resource || mesh->blasResultSize < requiredResult)
|
||||||
{
|
{
|
||||||
|
glRaytracingWaitFenceValue(mesh->blasBuildFenceValue);
|
||||||
mesh->blasResult[i].resource.Reset();
|
mesh->blasResult[i].resource.Reset();
|
||||||
mesh->blasResult[i] = glRaytracingCreateBuffer(
|
mesh->blasResult[i] = glRaytracingCreateBuffer(
|
||||||
g_glRaytracingCmd.device.Get(),
|
g_glRaytracingCmd.device.Get(),
|
||||||
@@ -1103,8 +1217,11 @@ static int glRaytracingEnsureMeshResultBuffers(glRaytracingMeshRecord_t* mesh, U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mesh->descCpu.allowUpdate)
|
if (!mesh->descCpu.allowUpdate && mesh->blasResult[1].resource)
|
||||||
|
{
|
||||||
|
glRaytracingWaitFenceValue(mesh->blasBuildFenceValue);
|
||||||
mesh->blasResult[1].resource.Reset();
|
mesh->blasResult[1].resource.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
mesh->blasResultSize = requiredResult;
|
mesh->blasResultSize = requiredResult;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1254,6 +1371,9 @@ static int glRaytracingUploadCachedInstanceDescs(glRaytracingRenderWorld_t* worl
|
|||||||
(UINT64)activeCount * (UINT64)sizeof(D3D12_RAYTRACING_INSTANCE_DESC),
|
(UINT64)activeCount * (UINT64)sizeof(D3D12_RAYTRACING_INSTANCE_DESC),
|
||||||
D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT);
|
D3D12_RAYTRACING_INSTANCE_DESCS_BYTE_ALIGNMENT);
|
||||||
|
|
||||||
|
const int uploadIndex = glRaytracingGetInactiveTLASIndex(world);
|
||||||
|
glRaytracingWaitFenceValue(world->instanceDescUploadFenceValue[uploadIndex]);
|
||||||
|
|
||||||
if (!glRaytracingEnsureSceneUploadBuffer(world, instBytes))
|
if (!glRaytracingEnsureSceneUploadBuffer(world, instBytes))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1384,12 +1504,15 @@ static int glRaytracingBuildDirtyMeshesInternal(void)
|
|||||||
if (!blasFenceValue)
|
if (!blasFenceValue)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glRaytracingWaitFenceValue(blasFenceValue);
|
// Do not block the CPU here. The BLAS build was submitted before any TLAS
|
||||||
|
// build/lighting work that consumes it, and the shared D3D12 queue preserves
|
||||||
|
// that order. Command allocator reuse is protected by the ring fence in
|
||||||
|
// glRaytracingBeginBlasCmd().
|
||||||
for (size_t i = 0; i < builds.size(); ++i)
|
for (size_t i = 0; i < builds.size(); ++i)
|
||||||
{
|
{
|
||||||
glRaytracingMeshRecord_t* mesh = builds[i].mesh;
|
glRaytracingMeshRecord_t* mesh = builds[i].mesh;
|
||||||
mesh->currentBlasIndex = builds[i].newBlasIndex;
|
mesh->currentBlasIndex = builds[i].newBlasIndex;
|
||||||
|
mesh->blasBuildFenceValue = blasFenceValue;
|
||||||
mesh->blasBuilt = 1;
|
mesh->blasBuilt = 1;
|
||||||
mesh->dirty = 0;
|
mesh->dirty = 0;
|
||||||
}
|
}
|
||||||
@@ -1588,11 +1711,12 @@ static int glRaytracingBuildSceneInternal(glRaytracingRenderWorld_t* world)
|
|||||||
if (!glRaytracingEnsureTLASBuffers(world, &inputs))
|
if (!glRaytracingEnsureTLASBuffers(world, &inputs))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
const int buildTLASIndex = glRaytracingGetInactiveTLASIndex(world);
|
||||||
glRaytracingBuffer_t* dstTLAS = glRaytracingGetBuildTLASBuffer(world);
|
glRaytracingBuffer_t* dstTLAS = glRaytracingGetBuildTLASBuffer(world);
|
||||||
const glRaytracingBuffer_t* srcTLAS = glRaytracingGetCurrentTLASBufferConst(world);
|
const glRaytracingBuffer_t* srcTLAS = glRaytracingGetCurrentTLASBufferConst(world);
|
||||||
|
|
||||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.blasLastFenceValue);
|
// The TLAS build is queued after any pending BLAS builds on the same D3D12
|
||||||
|
// queue, so GPU ordering is sufficient and a CPU wait would stall the frame.
|
||||||
if (!glRaytracingBeginTlasCmd())
|
if (!glRaytracingBeginTlasCmd())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -1619,9 +1743,13 @@ static int glRaytracingBuildSceneInternal(glRaytracingRenderWorld_t* world)
|
|||||||
if (!tlasFenceValue)
|
if (!tlasFenceValue)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glRaytracingWaitFenceValue(tlasFenceValue);
|
// Keep TLAS builds asynchronous. Later ray dispatches are submitted to the
|
||||||
|
// same queue after this command list, so the GPU sees a complete TLAS before
|
||||||
world->currentTLASIndex = glRaytracingGetInactiveTLASIndex(world);
|
// tracing without forcing the CPU to wait every update. The upload buffer is
|
||||||
|
// fence-tagged so the CPU does not overwrite instance descriptors still being
|
||||||
|
// consumed by an in-flight TLAS build.
|
||||||
|
world->instanceDescUploadFenceValue[buildTLASIndex] = tlasFenceValue;
|
||||||
|
world->currentTLASIndex = buildTLASIndex;
|
||||||
world->activeInstanceCount = activeCount;
|
world->activeInstanceCount = activeCount;
|
||||||
world->builtInstanceCount = activeCount;
|
world->builtInstanceCount = activeCount;
|
||||||
world->tlasBuilt = 1;
|
world->tlasBuilt = 1;
|
||||||
@@ -1696,6 +1824,7 @@ void glRaytracingShutdown(void)
|
|||||||
if (!g_glRaytracingScene.initialized)
|
if (!g_glRaytracingScene.initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
glRaytracingClearAllSceneStateInternal();
|
glRaytracingClearAllSceneStateInternal();
|
||||||
g_glRaytracingScene = glRaytracingSceneState_t();
|
g_glRaytracingScene = glRaytracingSceneState_t();
|
||||||
glRaytracingShutdownCmdContext();
|
glRaytracingShutdownCmdContext();
|
||||||
@@ -1705,6 +1834,7 @@ void glRaytracingClear(void)
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
std::lock_guard<std::mutex> lock(g_glRaytracingMutex);
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
glRaytracingClearAllSceneStateInternal();
|
glRaytracingClearAllSceneStateInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1737,6 +1867,7 @@ void glRaytracingClearScene(glRaytracingSceneHandle_t worldHandle)
|
|||||||
if (!world)
|
if (!world)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
glRaytracingClearWorldContents(world);
|
glRaytracingClearWorldContents(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1748,6 +1879,7 @@ void glRaytracingDeleteScene(glRaytracingSceneHandle_t worldHandle)
|
|||||||
if (!world)
|
if (!world)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
glRaytracingReleaseWorldResources(world);
|
glRaytracingReleaseWorldResources(world);
|
||||||
*world = glRaytracingRenderWorld_t();
|
*world = glRaytracingRenderWorld_t();
|
||||||
}
|
}
|
||||||
@@ -1813,6 +1945,11 @@ int glRaytracingUpdateMesh(glRaytracingMeshHandle_t meshHandle, const glRaytraci
|
|||||||
mesh->descCpu.vertices = nullptr;
|
mesh->descCpu.vertices = nullptr;
|
||||||
mesh->descCpu.indices = nullptr;
|
mesh->descCpu.indices = nullptr;
|
||||||
|
|
||||||
|
// Updating a mesh destroys/replaces resources that an already submitted frame
|
||||||
|
// may still reference. Wait only for this destructive path; steady-state
|
||||||
|
// rendering remains asynchronous.
|
||||||
|
glRaytracingWaitIdle();
|
||||||
|
|
||||||
mesh->vertexBuffer.resource.Reset();
|
mesh->vertexBuffer.resource.Reset();
|
||||||
mesh->indexBuffer.resource.Reset();
|
mesh->indexBuffer.resource.Reset();
|
||||||
mesh->blasScratch.resource.Reset();
|
mesh->blasScratch.resource.Reset();
|
||||||
@@ -1820,6 +1957,7 @@ int glRaytracingUpdateMesh(glRaytracingMeshHandle_t meshHandle, const glRaytraci
|
|||||||
mesh->blasResult[1].resource.Reset();
|
mesh->blasResult[1].resource.Reset();
|
||||||
mesh->blasScratchSize = 0;
|
mesh->blasScratchSize = 0;
|
||||||
mesh->blasResultSize = 0;
|
mesh->blasResultSize = 0;
|
||||||
|
mesh->blasBuildFenceValue = 0;
|
||||||
mesh->blasBuilt = 0;
|
mesh->blasBuilt = 0;
|
||||||
mesh->dirty = 1;
|
mesh->dirty = 1;
|
||||||
mesh->currentBlasIndex = 0;
|
mesh->currentBlasIndex = 0;
|
||||||
@@ -1881,6 +2019,7 @@ void glRaytracingDeleteMesh(glRaytracingMeshHandle_t meshHandle)
|
|||||||
if (!mesh)
|
if (!mesh)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
glRaytracingInvalidateInstancesForMesh(meshHandle, 1);
|
glRaytracingInvalidateInstancesForMesh(meshHandle, 1);
|
||||||
|
|
||||||
mesh->alive = 0;
|
mesh->alive = 0;
|
||||||
@@ -1891,6 +2030,7 @@ void glRaytracingDeleteMesh(glRaytracingMeshHandle_t meshHandle)
|
|||||||
mesh->blasResult[1].resource.Reset();
|
mesh->blasResult[1].resource.Reset();
|
||||||
mesh->blasScratchSize = 0;
|
mesh->blasScratchSize = 0;
|
||||||
mesh->blasResultSize = 0;
|
mesh->blasResultSize = 0;
|
||||||
|
mesh->blasBuildFenceValue = 0;
|
||||||
mesh->blasBuilt = 0;
|
mesh->blasBuilt = 0;
|
||||||
mesh->dirty = 0;
|
mesh->dirty = 0;
|
||||||
|
|
||||||
@@ -2109,10 +2249,17 @@ struct glRaytracingLightingState_t
|
|||||||
glRaytracingLightingConstants_t constants;
|
glRaytracingLightingConstants_t constants;
|
||||||
|
|
||||||
ComPtr<ID3D12DescriptorHeap> descriptorHeap;
|
ComPtr<ID3D12DescriptorHeap> descriptorHeap;
|
||||||
|
ComPtr<ID3D12DescriptorHeap> descriptorHeapRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
UINT descriptorStride;
|
UINT descriptorStride;
|
||||||
|
|
||||||
glRaytracingBuffer_t constantBuffer;
|
glRaytracingBuffer_t constantBuffer;
|
||||||
glRaytracingBuffer_t lightBuffer;
|
glRaytracingBuffer_t lightBuffer;
|
||||||
|
void* constantBufferMapped;
|
||||||
|
void* lightBufferMapped;
|
||||||
|
glRaytracingBuffer_t constantBufferRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
glRaytracingBuffer_t lightBufferRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
void* constantBufferMappedRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
void* lightBufferMappedRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||||
|
|
||||||
ComPtr<ID3D12RootSignature> globalRootSig;
|
ComPtr<ID3D12RootSignature> globalRootSig;
|
||||||
ComPtr<ID3D12RootSignature> localRootSig;
|
ComPtr<ID3D12RootSignature> localRootSig;
|
||||||
@@ -2132,23 +2279,39 @@ struct glRaytracingLightingState_t
|
|||||||
glRaytracingTexture_t denoiseTemp[2];
|
glRaytracingTexture_t denoiseTemp[2];
|
||||||
uint32_t currentHistoryIndex;
|
uint32_t currentHistoryIndex;
|
||||||
glRaytracingBuffer_t denoiseConstantBuffer[3];
|
glRaytracingBuffer_t denoiseConstantBuffer[3];
|
||||||
|
glRaytracingBuffer_t denoiseConstantBufferRing[GL_RAYTRACING_CMD_RING_SIZE][3];
|
||||||
|
void* denoiseConstantBufferMapped[3];
|
||||||
|
void* denoiseConstantBufferMappedRing[GL_RAYTRACING_CMD_RING_SIZE][3];
|
||||||
UINT denoiseWidth;
|
UINT denoiseWidth;
|
||||||
UINT denoiseHeight;
|
UINT denoiseHeight;
|
||||||
DXGI_FORMAT denoiseFormat;
|
DXGI_FORMAT denoiseFormat;
|
||||||
uint32_t frameCounter;
|
uint32_t frameCounter;
|
||||||
bool externalDenoiser;
|
bool externalDenoiser;
|
||||||
|
bool uploadToCurrentFrameResource;
|
||||||
bool initialized;
|
bool initialized;
|
||||||
|
|
||||||
glRaytracingLightingState_t()
|
glRaytracingLightingState_t()
|
||||||
{
|
{
|
||||||
memset(&constants, 0, sizeof(constants));
|
memset(&constants, 0, sizeof(constants));
|
||||||
descriptorStride = 0;
|
descriptorStride = 0;
|
||||||
|
constantBufferMapped = nullptr;
|
||||||
|
lightBufferMapped = nullptr;
|
||||||
|
for (UINT frame = 0; frame < GL_RAYTRACING_CMD_RING_SIZE; ++frame)
|
||||||
|
{
|
||||||
|
constantBufferMappedRing[frame] = nullptr;
|
||||||
|
lightBufferMappedRing[frame] = nullptr;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
denoiseConstantBufferMappedRing[frame][i] = nullptr;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
denoiseConstantBufferMapped[i] = nullptr;
|
||||||
denoiseWidth = 0;
|
denoiseWidth = 0;
|
||||||
denoiseHeight = 0;
|
denoiseHeight = 0;
|
||||||
denoiseFormat = DXGI_FORMAT_UNKNOWN;
|
denoiseFormat = DXGI_FORMAT_UNKNOWN;
|
||||||
currentHistoryIndex = 0;
|
currentHistoryIndex = 0;
|
||||||
frameCounter = 0;
|
frameCounter = 0;
|
||||||
externalDenoiser = false;
|
externalDenoiser = false;
|
||||||
|
uploadToCurrentFrameResource = false;
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2769,7 +2932,7 @@ float TraceSpotShadow(float3 worldPos, float3 N, float3 toLight, float dist)
|
|||||||
|
|
||||||
float TraceSoftShadow(float3 worldPos, float3 N, Light Lgt, float3 toLight, float dist)
|
float TraceSoftShadow(float3 worldPos, float3 N, Light Lgt, float3 toLight, float dist)
|
||||||
{
|
{
|
||||||
const uint SHADOW_SAMPLES = 12;
|
const uint SHADOW_SAMPLES = 4;
|
||||||
|
|
||||||
float3 L = toLight / max(dist, 1e-6);
|
float3 L = toLight / max(dist, 1e-6);
|
||||||
|
|
||||||
@@ -2815,7 +2978,7 @@ R"(
|
|||||||
float RectLightShadow(float3 worldPos, float3 N, Light Lgt, uint2 pixel)
|
float RectLightShadow(float3 worldPos, float3 N, Light Lgt, uint2 pixel)
|
||||||
{
|
{
|
||||||
uint sampleCount = max(Lgt.samples, 1u);
|
uint sampleCount = max(Lgt.samples, 1u);
|
||||||
sampleCount = min(sampleCount, 16u);
|
sampleCount = min(sampleCount, 4u);
|
||||||
|
|
||||||
float visibility = 0.0;
|
float visibility = 0.0;
|
||||||
|
|
||||||
@@ -2873,7 +3036,7 @@ float RectLightShadow(float3 worldPos, float3 N, Light Lgt, uint2 pixel)
|
|||||||
|
|
||||||
float ComputeAmbientOcclusion(float3 worldPos, float3 N, uint2 pixel)
|
float ComputeAmbientOcclusion(float3 worldPos, float3 N, uint2 pixel)
|
||||||
{
|
{
|
||||||
const uint AO_SAMPLES = 24;
|
const uint AO_SAMPLES = 8;
|
||||||
const float AO_RADIUS = 32.0;
|
const float AO_RADIUS = 32.0;
|
||||||
|
|
||||||
float3 tangent, bitangent;
|
float3 tangent, bitangent;
|
||||||
@@ -2919,7 +3082,7 @@ float3 GetSkyLightDirection10AM()
|
|||||||
R"(
|
R"(
|
||||||
float ComputeSkyVisibility(float3 worldPos, float3 N, uint2 pixel)
|
float ComputeSkyVisibility(float3 worldPos, float3 N, uint2 pixel)
|
||||||
{
|
{
|
||||||
const uint SKY_SAMPLES = 12;
|
const uint SKY_SAMPLES = 4;
|
||||||
const float SKY_TMAX = 1000000.0;
|
const float SKY_TMAX = 1000000.0;
|
||||||
|
|
||||||
// Soft angular size of the sky/sun shadow cone.
|
// Soft angular size of the sky/sun shadow cone.
|
||||||
@@ -3465,7 +3628,7 @@ float3 PathTraceDirectRectLight(uint2 pixel, float3 worldPos, float3 N, float3 V
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
uint sampleCount = max(Lgt.samples, 1u);
|
uint sampleCount = max(Lgt.samples, 1u);
|
||||||
sampleCount = min(sampleCount, 8u);
|
sampleCount = min(sampleCount, 4u);
|
||||||
float rand = Hash12((float2)pixel + worldPos.xy + float2(centerDist, worldPos.z));
|
float rand = Hash12((float2)pixel + worldPos.xy + float2(centerDist, worldPos.z));
|
||||||
|
|
||||||
float3 diffuseAccum = 0.0;
|
float3 diffuseAccum = 0.0;
|
||||||
@@ -3570,7 +3733,7 @@ float3 EstimateSingleLightVolumetricScattering(uint2 pixel, float3 cameraPos, fl
|
|||||||
|
|
||||||
float3 viewDir = cameraToSurface / viewDist;
|
float3 viewDir = cameraToSurface / viewDist;
|
||||||
|
|
||||||
uint stepCount = min(max(Lgt.samples, 4u), 12u);
|
uint stepCount = min(max(Lgt.samples, 3u), 6u);
|
||||||
float stepLen = viewDist / (float)stepCount;
|
float stepLen = viewDist / (float)stepCount;
|
||||||
|
|
||||||
// Do not frame-jitter the march. This renderer has no temporal GI history,
|
// Do not frame-jitter the march. This renderer has no temporal GI history,
|
||||||
@@ -3818,7 +3981,7 @@ float3 EstimateDirectLightingForBounceHit(uint2 hitPixel, float3 hitPos, float3
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if (hitIsSkeletal)
|
//if (hitIsSkeletal)
|
||||||
// lighting *= 1.10;
|
// lighting *= 1.10;
|
||||||
|
|
||||||
// Outgoing diffuse radiance from the bounce surface. The primary surface's
|
// Outgoing diffuse radiance from the bounce surface. The primary surface's
|
||||||
// albedo is applied later in RayGen, so only the secondary hit albedo belongs
|
// albedo is applied later in RayGen, so only the secondary hit albedo belongs
|
||||||
@@ -3843,19 +4006,19 @@ float3 EstimateReactiveScreenSpaceFinalGather(uint2 pixel, float3 worldPos, floa
|
|||||||
int2( 29, 18)
|
int2( 29, 18)
|
||||||
};
|
};
|
||||||
|
|
||||||
uint sampleBudget = 5u;
|
uint sampleBudget = 3u;
|
||||||
|
|
||||||
// Keep the pass cheap when many lights or high SPP are active. This path
|
// Keep the pass cheap when many lights or high SPP are active. This path
|
||||||
// evaluates bounce lighting against the light list and traces short
|
// evaluates bounce lighting against the light list and traces short
|
||||||
// visibility rays, so adapt the sample count instead of raising ray count.
|
// visibility rays, so adapt the sample count instead of raising ray count.
|
||||||
if (gLightCount > 4u)
|
if (gLightCount > 4u)
|
||||||
sampleBudget = 4u;
|
sampleBudget = 2u;
|
||||||
if (gLightCount > 10u)
|
if (gLightCount > 10u)
|
||||||
sampleBudget = 3u;
|
sampleBudget = 1u;
|
||||||
if (gSamplesPerPixel >= 4u)
|
if (gSamplesPerPixel >= 4u)
|
||||||
sampleBudget = min(sampleBudget, 3u);
|
|
||||||
if (gSamplesPerPixel >= 6u)
|
|
||||||
sampleBudget = min(sampleBudget, 2u);
|
sampleBudget = min(sampleBudget, 2u);
|
||||||
|
if (gSamplesPerPixel >= 6u)
|
||||||
|
sampleBudget = min(sampleBudget, 1u);
|
||||||
|
|
||||||
int2 maxPixel = int2((int)gScreenSize.x - 1, (int)gScreenSize.y - 1);
|
int2 maxPixel = int2((int)gScreenSize.x - 1, (int)gScreenSize.y - 1);
|
||||||
float pixelScale = max(1.0, round(min(gScreenSize.x, gScreenSize.y) / 720.0));
|
float pixelScale = max(1.0, round(min(gScreenSize.x, gScreenSize.y) / 720.0));
|
||||||
@@ -4092,7 +4255,7 @@ float3 ApplyPrimaryDiffusePost(float3 lightingAccum, float ao, float microShadow
|
|||||||
lightingAccum *= ao;
|
lightingAccum *= ao;
|
||||||
lightingAccum *= microShadow;
|
lightingAccum *= microShadow;
|
||||||
|
|
||||||
// if (isSkeletal)
|
//if (isSkeletal)
|
||||||
// lightingAccum *= 1.2;
|
// lightingAccum *= 1.2;
|
||||||
|
|
||||||
return max(lightingAccum, 0.0);
|
return max(lightingAccum, 0.0);
|
||||||
@@ -4137,7 +4300,7 @@ float3 PathTraceDeterministicLighting(
|
|||||||
lightingAccum += ambientSkyVis * (skyColorRGB * 0.15);
|
lightingAccum += ambientSkyVis * (skyColorRGB * 0.15);
|
||||||
|
|
||||||
//if (isSkeletal)
|
//if (isSkeletal)
|
||||||
// lightingAccum += 0.1;
|
// lightingAccum += 0.1;
|
||||||
|
|
||||||
// The current direct-light evaluators are deterministic. Keep the inout RNG
|
// The current direct-light evaluators are deterministic. Keep the inout RNG
|
||||||
// argument only because the functions share the same signature as stochastic
|
// argument only because the functions share the same signature as stochastic
|
||||||
@@ -4700,8 +4863,10 @@ static ComPtr<IDxcBlob> glRaytracingLightingCompileLibrary(const char* src)
|
|||||||
const wchar_t* args[] =
|
const wchar_t* args[] =
|
||||||
{
|
{
|
||||||
L"-T", L"lib_6_3",
|
L"-T", L"lib_6_3",
|
||||||
|
#if defined(_DEBUG)
|
||||||
L"-Zi",
|
L"-Zi",
|
||||||
L"-Qembed_debug",
|
L"-Qembed_debug",
|
||||||
|
#endif
|
||||||
L"-O3",
|
L"-O3",
|
||||||
L"-all_resources_bound"
|
L"-all_resources_bound"
|
||||||
};
|
};
|
||||||
@@ -4771,8 +4936,10 @@ static ComPtr<IDxcBlob> glRaytracingLightingCompileCompute(const char* src, cons
|
|||||||
{
|
{
|
||||||
L"-E", entryPoint,
|
L"-E", entryPoint,
|
||||||
L"-T", L"cs_6_0",
|
L"-T", L"cs_6_0",
|
||||||
|
#if defined(_DEBUG)
|
||||||
L"-Zi",
|
L"-Zi",
|
||||||
L"-Qembed_debug",
|
L"-Qembed_debug",
|
||||||
|
#endif
|
||||||
L"-O3",
|
L"-O3",
|
||||||
L"-all_resources_bound"
|
L"-all_resources_bound"
|
||||||
};
|
};
|
||||||
@@ -4813,7 +4980,14 @@ static int glRaytracingLightingCreateDescriptorHeap(void)
|
|||||||
hd.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
hd.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||||
hd.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
hd.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
|
||||||
|
|
||||||
GLR_CHECK(g_glRaytracingCmd.device->CreateDescriptorHeap(&hd, IID_PPV_ARGS(&g_glRaytracingLighting.descriptorHeap)));
|
for (UINT frame = 0; frame < GL_RAYTRACING_CMD_RING_SIZE; ++frame)
|
||||||
|
{
|
||||||
|
GLR_CHECK(g_glRaytracingCmd.device->CreateDescriptorHeap(
|
||||||
|
&hd,
|
||||||
|
IID_PPV_ARGS(&g_glRaytracingLighting.descriptorHeapRing[frame])));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_glRaytracingLighting.descriptorHeap = g_glRaytracingLighting.descriptorHeapRing[0];
|
||||||
g_glRaytracingLighting.descriptorStride =
|
g_glRaytracingLighting.descriptorStride =
|
||||||
g_glRaytracingCmd.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
g_glRaytracingCmd.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
|
||||||
|
|
||||||
@@ -4882,39 +5056,110 @@ static int glRaytracingLightingCreateRootSignatures(void)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int glRaytracingMapUploadBufferPersistent(const glRaytracingBuffer_t& buffer, void** mapped)
|
||||||
|
{
|
||||||
|
if (!buffer.resource || !mapped)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
*mapped = nullptr;
|
||||||
|
D3D12_RANGE readRange = {};
|
||||||
|
HRESULT hr = buffer.resource->Map(0, &readRange, mapped);
|
||||||
|
if (FAILED(hr) || !*mapped)
|
||||||
|
{
|
||||||
|
glRaytracingFatal("Persistent upload Map failed 0x%08X", (unsigned)hr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glRaytracingLightingSelectFrameResources(UINT frameSlot)
|
||||||
|
{
|
||||||
|
frameSlot %= GL_RAYTRACING_CMD_RING_SIZE;
|
||||||
|
|
||||||
|
g_glRaytracingLighting.descriptorHeap = g_glRaytracingLighting.descriptorHeapRing[frameSlot];
|
||||||
|
g_glRaytracingLighting.constantBuffer = g_glRaytracingLighting.constantBufferRing[frameSlot];
|
||||||
|
g_glRaytracingLighting.lightBuffer = g_glRaytracingLighting.lightBufferRing[frameSlot];
|
||||||
|
g_glRaytracingLighting.constantBufferMapped = g_glRaytracingLighting.constantBufferMappedRing[frameSlot];
|
||||||
|
g_glRaytracingLighting.lightBufferMapped = g_glRaytracingLighting.lightBufferMappedRing[frameSlot];
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
g_glRaytracingLighting.denoiseConstantBuffer[i] = g_glRaytracingLighting.denoiseConstantBufferRing[frameSlot][i];
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferMapped[i] = g_glRaytracingLighting.denoiseConstantBufferMappedRing[frameSlot][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int glRaytracingLightingCreateBuffers(void)
|
static int glRaytracingLightingCreateBuffers(void)
|
||||||
{
|
{
|
||||||
const UINT64 constantsBytes = glRaytracingAlignUp(sizeof(glRaytracingLightingConstants_t), 256);
|
const UINT64 constantsBytes = glRaytracingAlignUp(sizeof(glRaytracingLightingConstants_t), 256);
|
||||||
|
|
||||||
g_glRaytracingLighting.constantBuffer = glRaytracingCreateBuffer(
|
for (UINT frame = 0; frame < GL_RAYTRACING_CMD_RING_SIZE; ++frame)
|
||||||
g_glRaytracingCmd.device.Get(),
|
|
||||||
constantsBytes,
|
|
||||||
D3D12_HEAP_TYPE_UPLOAD,
|
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
|
||||||
D3D12_RESOURCE_FLAG_NONE);
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
|
||||||
{
|
{
|
||||||
g_glRaytracingLighting.denoiseConstantBuffer[i] = glRaytracingCreateBuffer(
|
g_glRaytracingLighting.constantBufferRing[frame] = glRaytracingCreateBuffer(
|
||||||
g_glRaytracingCmd.device.Get(),
|
g_glRaytracingCmd.device.Get(),
|
||||||
constantsBytes,
|
constantsBytes,
|
||||||
D3D12_HEAP_TYPE_UPLOAD,
|
D3D12_HEAP_TYPE_UPLOAD,
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
D3D12_RESOURCE_FLAG_NONE);
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
|
|
||||||
|
g_glRaytracingLighting.lightBufferRing[frame] = glRaytracingCreateBuffer(
|
||||||
|
g_glRaytracingCmd.device.Get(),
|
||||||
|
sizeof(glRaytracingLight_t) * GL_RAYTRACING_MAX_LIGHTS,
|
||||||
|
D3D12_HEAP_TYPE_UPLOAD,
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
|
|
||||||
|
if (!g_glRaytracingLighting.constantBufferRing[frame].resource ||
|
||||||
|
!g_glRaytracingLighting.lightBufferRing[frame].resource)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferRing[frame][i] = glRaytracingCreateBuffer(
|
||||||
|
g_glRaytracingCmd.device.Get(),
|
||||||
|
constantsBytes,
|
||||||
|
D3D12_HEAP_TYPE_UPLOAD,
|
||||||
|
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||||
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
|
|
||||||
|
if (!g_glRaytracingLighting.denoiseConstantBufferRing[frame][i].resource)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are small UPLOAD-heap buffers updated every pass. Keeping every
|
||||||
|
// per-frame copy persistently mapped avoids Map/Unmap overhead and makes
|
||||||
|
// the async command-ring safe: the CPU never overwrites constants that an
|
||||||
|
// older in-flight command list still reads.
|
||||||
|
if (!glRaytracingMapUploadBufferPersistent(
|
||||||
|
g_glRaytracingLighting.constantBufferRing[frame],
|
||||||
|
&g_glRaytracingLighting.constantBufferMappedRing[frame]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!glRaytracingMapUploadBufferPersistent(
|
||||||
|
g_glRaytracingLighting.lightBufferRing[frame],
|
||||||
|
&g_glRaytracingLighting.lightBufferMappedRing[frame]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (!glRaytracingMapUploadBufferPersistent(
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferRing[frame][i],
|
||||||
|
&g_glRaytracingLighting.denoiseConstantBufferMappedRing[frame][i]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_glRaytracingLighting.lightBuffer = glRaytracingCreateBuffer(
|
glRaytracingLightingSelectFrameResources(0);
|
||||||
g_glRaytracingCmd.device.Get(),
|
return 1;
|
||||||
sizeof(glRaytracingLight_t) * GL_RAYTRACING_MAX_LIGHTS,
|
|
||||||
D3D12_HEAP_TYPE_UPLOAD,
|
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
|
||||||
D3D12_RESOURCE_FLAG_NONE);
|
|
||||||
|
|
||||||
return g_glRaytracingLighting.constantBuffer.resource &&
|
|
||||||
g_glRaytracingLighting.lightBuffer.resource &&
|
|
||||||
g_glRaytracingLighting.denoiseConstantBuffer[0].resource &&
|
|
||||||
g_glRaytracingLighting.denoiseConstantBuffer[1].resource &&
|
|
||||||
g_glRaytracingLighting.denoiseConstantBuffer[2].resource;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glRaytracingLightingUploadConstantsTo(
|
static void glRaytracingLightingUploadConstantsTo(
|
||||||
@@ -4924,11 +5169,37 @@ static void glRaytracingLightingUploadConstantsTo(
|
|||||||
if (!dst.resource)
|
if (!dst.resource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
void* mapped = nullptr;
|
||||||
|
if (dst.resource.Get() == g_glRaytracingLighting.constantBuffer.resource.Get())
|
||||||
|
{
|
||||||
|
mapped = g_glRaytracingLighting.constantBufferMapped;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (dst.resource.Get() == g_glRaytracingLighting.denoiseConstantBuffer[i].resource.Get())
|
||||||
|
{
|
||||||
|
mapped = g_glRaytracingLighting.denoiseConstantBufferMapped[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapped)
|
||||||
|
{
|
||||||
|
memcpy(mapped, &constants, sizeof(constants));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glRaytracingMapCopy(dst.resource.Get(), &constants, sizeof(constants));
|
glRaytracingMapCopy(dst.resource.Get(), &constants, sizeof(constants));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glRaytracingLightingUpdateConstants(void)
|
static void glRaytracingLightingUpdateConstants(void)
|
||||||
{
|
{
|
||||||
|
if (!g_glRaytracingLighting.uploadToCurrentFrameResource)
|
||||||
|
return;
|
||||||
|
|
||||||
glRaytracingLightingUploadConstantsTo(
|
glRaytracingLightingUploadConstantsTo(
|
||||||
g_glRaytracingLighting.constantBuffer,
|
g_glRaytracingLighting.constantBuffer,
|
||||||
g_glRaytracingLighting.constants);
|
g_glRaytracingLighting.constants);
|
||||||
@@ -4936,13 +5207,61 @@ static void glRaytracingLightingUpdateConstants(void)
|
|||||||
|
|
||||||
static void glRaytracingLightingUpdateLights(void)
|
static void glRaytracingLightingUpdateLights(void)
|
||||||
{
|
{
|
||||||
|
if (!g_glRaytracingLighting.uploadToCurrentFrameResource)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!g_glRaytracingLighting.lightBuffer.resource)
|
||||||
|
return;
|
||||||
|
|
||||||
if (g_glRaytracingLighting.cpuLights.empty())
|
if (g_glRaytracingLighting.cpuLights.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const size_t bytes = g_glRaytracingLighting.cpuLights.size() * sizeof(glRaytracingLight_t);
|
||||||
|
if (g_glRaytracingLighting.lightBufferMapped)
|
||||||
|
{
|
||||||
|
memcpy(g_glRaytracingLighting.lightBufferMapped, g_glRaytracingLighting.cpuLights.data(), bytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
glRaytracingMapCopy(
|
glRaytracingMapCopy(
|
||||||
g_glRaytracingLighting.lightBuffer.resource.Get(),
|
g_glRaytracingLighting.lightBuffer.resource.Get(),
|
||||||
g_glRaytracingLighting.cpuLights.data(),
|
g_glRaytracingLighting.cpuLights.data(),
|
||||||
g_glRaytracingLighting.cpuLights.size() * sizeof(glRaytracingLight_t));
|
bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glRaytracingLightingUnmapUploadBuffers(void)
|
||||||
|
{
|
||||||
|
for (UINT frame = 0; frame < GL_RAYTRACING_CMD_RING_SIZE; ++frame)
|
||||||
|
{
|
||||||
|
if (g_glRaytracingLighting.constantBufferRing[frame].resource &&
|
||||||
|
g_glRaytracingLighting.constantBufferMappedRing[frame])
|
||||||
|
{
|
||||||
|
g_glRaytracingLighting.constantBufferRing[frame].resource->Unmap(0, nullptr);
|
||||||
|
g_glRaytracingLighting.constantBufferMappedRing[frame] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_glRaytracingLighting.lightBufferRing[frame].resource &&
|
||||||
|
g_glRaytracingLighting.lightBufferMappedRing[frame])
|
||||||
|
{
|
||||||
|
g_glRaytracingLighting.lightBufferRing[frame].resource->Unmap(0, nullptr);
|
||||||
|
g_glRaytracingLighting.lightBufferMappedRing[frame] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
{
|
||||||
|
if (g_glRaytracingLighting.denoiseConstantBufferRing[frame][i].resource &&
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferMappedRing[frame][i])
|
||||||
|
{
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferRing[frame][i].resource->Unmap(0, nullptr);
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferMappedRing[frame][i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_glRaytracingLighting.constantBufferMapped = nullptr;
|
||||||
|
g_glRaytracingLighting.lightBufferMapped = nullptr;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
g_glRaytracingLighting.denoiseConstantBufferMapped[i] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glRaytracingLightingCreatePersistentLightSRV(void)
|
static void glRaytracingLightingCreatePersistentLightSRV(void)
|
||||||
@@ -4956,11 +5275,21 @@ static void glRaytracingLightingCreatePersistentLightSRV(void)
|
|||||||
srv.Buffer.StructureByteStride = sizeof(glRaytracingLight_t);
|
srv.Buffer.StructureByteStride = sizeof(glRaytracingLight_t);
|
||||||
srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
||||||
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE base = g_glRaytracingLighting.descriptorHeap->GetCPUDescriptorHandleForHeapStart();
|
for (UINT frame = 0; frame < GL_RAYTRACING_CMD_RING_SIZE; ++frame)
|
||||||
g_glRaytracingCmd.device->CreateShaderResourceView(
|
{
|
||||||
g_glRaytracingLighting.lightBuffer.resource.Get(),
|
if (!g_glRaytracingLighting.descriptorHeapRing[frame] ||
|
||||||
&srv,
|
!g_glRaytracingLighting.lightBufferRing[frame].resource)
|
||||||
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, 0));
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE base =
|
||||||
|
g_glRaytracingLighting.descriptorHeapRing[frame]->GetCPUDescriptorHandleForHeapStart();
|
||||||
|
g_glRaytracingCmd.device->CreateShaderResourceView(
|
||||||
|
g_glRaytracingLighting.lightBufferRing[frame].resource.Get(),
|
||||||
|
&srv,
|
||||||
|
glRaytracingOffsetCpu(base, g_glRaytracingLighting.descriptorStride, GLR_DESC_LIGHTS_SRV));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int glRaytracingLightingCreateStateObject(void)
|
static int glRaytracingLightingCreateStateObject(void)
|
||||||
@@ -5191,6 +5520,16 @@ static int glRaytracingLightingEnsureDenoiseResources(UINT width, UINT height)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_glRaytracingLighting.pathTraceTexture.resource ||
|
||||||
|
g_glRaytracingLighting.temporalTexture.resource ||
|
||||||
|
g_glRaytracingLighting.historyTexture[0].resource ||
|
||||||
|
g_glRaytracingLighting.historyTexture[1].resource ||
|
||||||
|
g_glRaytracingLighting.denoiseTemp[0].resource ||
|
||||||
|
g_glRaytracingLighting.denoiseTemp[1].resource)
|
||||||
|
{
|
||||||
|
glRaytracingWaitIdle();
|
||||||
|
}
|
||||||
|
|
||||||
g_glRaytracingLighting.pathTraceTexture = glRaytracingTexture_t();
|
g_glRaytracingLighting.pathTraceTexture = glRaytracingTexture_t();
|
||||||
g_glRaytracingLighting.temporalTexture = glRaytracingTexture_t();
|
g_glRaytracingLighting.temporalTexture = glRaytracingTexture_t();
|
||||||
g_glRaytracingLighting.historyTexture[0] = glRaytracingTexture_t();
|
g_glRaytracingLighting.historyTexture[0] = glRaytracingTexture_t();
|
||||||
@@ -5382,6 +5721,11 @@ static bool glRaytracingLightingExecuteInternal(
|
|||||||
? g_glRaytracingLighting.pathTraceTexture.resource.Get()
|
? g_glRaytracingLighting.pathTraceTexture.resource.Get()
|
||||||
: pass->outputTexture;
|
: pass->outputTexture;
|
||||||
|
|
||||||
|
if (!glRaytracingBeginCmd())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glRaytracingLightingSelectFrameResources(g_glRaytracingCmd.cmdCurrentSlot);
|
||||||
|
|
||||||
g_glRaytracingLighting.constants.screenSize[0] = (float)pass->width;
|
g_glRaytracingLighting.constants.screenSize[0] = (float)pass->width;
|
||||||
g_glRaytracingLighting.constants.screenSize[1] = (float)pass->height;
|
g_glRaytracingLighting.constants.screenSize[1] = (float)pass->height;
|
||||||
g_glRaytracingLighting.constants.screenSize[2] = 1.0f / (float)pass->width;
|
g_glRaytracingLighting.constants.screenSize[2] = 1.0f / (float)pass->width;
|
||||||
@@ -5390,6 +5734,7 @@ static bool glRaytracingLightingExecuteInternal(
|
|||||||
g_glRaytracingLighting.constants.lightCount =
|
g_glRaytracingLighting.constants.lightCount =
|
||||||
(uint32_t)glRaytracingClamp<size_t>(g_glRaytracingLighting.cpuLights.size(), 0, GL_RAYTRACING_MAX_LIGHTS);
|
(uint32_t)glRaytracingClamp<size_t>(g_glRaytracingLighting.cpuLights.size(), 0, GL_RAYTRACING_MAX_LIGHTS);
|
||||||
|
|
||||||
|
g_glRaytracingLighting.uploadToCurrentFrameResource = true;
|
||||||
glRaytracingLightingUpdateLights();
|
glRaytracingLightingUpdateLights();
|
||||||
glRaytracingLightingUpdateConstants();
|
glRaytracingLightingUpdateConstants();
|
||||||
|
|
||||||
@@ -5400,6 +5745,7 @@ static bool glRaytracingLightingExecuteInternal(
|
|||||||
denoiseConstants.denoiseStepWidth = (float)(1u << passIndex);
|
denoiseConstants.denoiseStepWidth = (float)(1u << passIndex);
|
||||||
glRaytracingLightingUploadConstantsTo(g_glRaytracingLighting.denoiseConstantBuffer[passIndex], denoiseConstants);
|
glRaytracingLightingUploadConstantsTo(g_glRaytracingLighting.denoiseConstantBuffer[passIndex], denoiseConstants);
|
||||||
}
|
}
|
||||||
|
g_glRaytracingLighting.uploadToCurrentFrameResource = false;
|
||||||
|
|
||||||
const uint32_t historyReadIndex = g_glRaytracingLighting.currentHistoryIndex & 1u;
|
const uint32_t historyReadIndex = g_glRaytracingLighting.currentHistoryIndex & 1u;
|
||||||
const uint32_t historyWriteIndex = (g_glRaytracingLighting.currentHistoryIndex ^ 1u) & 1u;
|
const uint32_t historyWriteIndex = (g_glRaytracingLighting.currentHistoryIndex ^ 1u) & 1u;
|
||||||
@@ -5415,9 +5761,6 @@ static bool glRaytracingLightingExecuteInternal(
|
|||||||
g_glRaytracingLighting.historyTexture[historyWriteIndex].resource.Get(),
|
g_glRaytracingLighting.historyTexture[historyWriteIndex].resource.Get(),
|
||||||
g_glRaytracingLighting.temporalTexture.resource.Get());
|
g_glRaytracingLighting.temporalTexture.resource.Get());
|
||||||
|
|
||||||
if (!glRaytracingBeginCmd())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (useInternalDenoiser)
|
if (useInternalDenoiser)
|
||||||
{
|
{
|
||||||
glRaytracingTransition(g_glRaytracingCmd.cmdList.Get(),
|
glRaytracingTransition(g_glRaytracingCmd.cmdList.Get(),
|
||||||
@@ -5666,7 +6009,7 @@ bool glRaytracingLightingInit(void)
|
|||||||
g_glRaytracingLighting.constants.normalReconstructZ = 1.0f;
|
g_glRaytracingLighting.constants.normalReconstructZ = 1.0f;
|
||||||
g_glRaytracingLighting.constants.shadowBias = 1.5f;
|
g_glRaytracingLighting.constants.shadowBias = 1.5f;
|
||||||
g_glRaytracingLighting.constants.frameIndex = 0;
|
g_glRaytracingLighting.constants.frameIndex = 0;
|
||||||
g_glRaytracingLighting.constants.samplesPerPixel = 2;
|
g_glRaytracingLighting.constants.samplesPerPixel = 1;
|
||||||
g_glRaytracingLighting.constants.maxBounces = 2;
|
g_glRaytracingLighting.constants.maxBounces = 2;
|
||||||
g_glRaytracingLighting.constants.enableDenoiser = 1;
|
g_glRaytracingLighting.constants.enableDenoiser = 1;
|
||||||
g_glRaytracingLighting.constants.denoisePassIndex = 0;
|
g_glRaytracingLighting.constants.denoisePassIndex = 0;
|
||||||
@@ -5692,6 +6035,8 @@ void glRaytracingLightingShutdown(void)
|
|||||||
if (!g_glRaytracingLighting.initialized)
|
if (!g_glRaytracingLighting.initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
glRaytracingWaitIdle();
|
||||||
|
glRaytracingLightingUnmapUploadBuffers();
|
||||||
g_glRaytracingLighting = glRaytracingLightingState_t();
|
g_glRaytracingLighting = glRaytracingLightingState_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user