mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-17 19:23:51 +02:00
Numerous performance fixes.
This commit is contained in:
@@ -49,6 +49,8 @@ If you have questions concerning this license or the applicable additional terms
|
||||
|
||||
using Microsoft::WRL::ComPtr;
|
||||
|
||||
extern float com_pathTracingGpuMsec;
|
||||
|
||||
// ============================================================
|
||||
// Logging / checks
|
||||
// ============================================================
|
||||
@@ -407,6 +409,10 @@ struct glRaytracingCmdContext_t
|
||||
ComPtr<ID3D12Fence> fence;
|
||||
HANDLE fenceEvent;
|
||||
UINT64 nextFenceValue;
|
||||
ComPtr<ID3D12QueryHeap> pathTracingTimestampHeap;
|
||||
glRaytracingBuffer_t pathTracingTimestampReadback;
|
||||
UINT64 pathTracingTimestampFrequency;
|
||||
UINT64 pathTracingTimestampFenceRing[GL_RAYTRACING_CMD_RING_SIZE];
|
||||
bool initialized;
|
||||
|
||||
glRaytracingCmdContext_t()
|
||||
@@ -425,9 +431,11 @@ struct glRaytracingCmdContext_t
|
||||
cmdFenceValueRing[i] = 0;
|
||||
blasFenceValueRing[i] = 0;
|
||||
tlasFenceValueRing[i] = 0;
|
||||
pathTracingTimestampFenceRing[i] = 0;
|
||||
}
|
||||
fenceEvent = nullptr;
|
||||
nextFenceValue = 0;
|
||||
pathTracingTimestampFrequency = 0;
|
||||
initialized = false;
|
||||
}
|
||||
};
|
||||
@@ -463,6 +471,66 @@ static void glRaytracingWaitIdle(void)
|
||||
glRaytracingWaitFenceValue(value);
|
||||
}
|
||||
|
||||
static void glRaytracingPollPathTracingTimestamp(UINT slot)
|
||||
{
|
||||
if (!g_glRaytracingCmd.pathTracingTimestampReadback.resource ||
|
||||
!g_glRaytracingCmd.pathTracingTimestampFrequency ||
|
||||
slot >= GL_RAYTRACING_CMD_RING_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const UINT64 fenceValue = g_glRaytracingCmd.pathTracingTimestampFenceRing[slot];
|
||||
if (!fenceValue || !g_glRaytracingCmd.fence || g_glRaytracingCmd.fence->GetCompletedValue() < fenceValue)
|
||||
return;
|
||||
|
||||
const UINT64 offset = sizeof(UINT64) * 2ull * slot;
|
||||
D3D12_RANGE readRange = { offset, offset + sizeof(UINT64) * 2ull };
|
||||
UINT64* timestamps = nullptr;
|
||||
if (SUCCEEDED(g_glRaytracingCmd.pathTracingTimestampReadback.resource->Map(0, &readRange, reinterpret_cast<void**>(×tamps))) && timestamps != nullptr)
|
||||
{
|
||||
const UINT64 begin = timestamps[slot * 2 + 0];
|
||||
const UINT64 end = timestamps[slot * 2 + 1];
|
||||
if (end >= begin)
|
||||
{
|
||||
com_pathTracingGpuMsec = (float)((double)(end - begin) * 1000.0 / (double)g_glRaytracingCmd.pathTracingTimestampFrequency);
|
||||
}
|
||||
|
||||
D3D12_RANGE writeRange = { 0, 0 };
|
||||
g_glRaytracingCmd.pathTracingTimestampReadback.resource->Unmap(0, &writeRange);
|
||||
}
|
||||
g_glRaytracingCmd.pathTracingTimestampFenceRing[slot] = 0;
|
||||
}
|
||||
|
||||
static int glRaytracingCreatePathTracingTimestamps(void)
|
||||
{
|
||||
D3D12_QUERY_HEAP_DESC qh = {};
|
||||
qh.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
qh.Count = GL_RAYTRACING_CMD_RING_SIZE * 2;
|
||||
if (FAILED(g_glRaytracingCmd.device->CreateQueryHeap(&qh, IID_PPV_ARGS(&g_glRaytracingCmd.pathTracingTimestampHeap))))
|
||||
return 0;
|
||||
|
||||
g_glRaytracingCmd.pathTracingTimestampReadback = glRaytracingCreateBuffer(
|
||||
g_glRaytracingCmd.device.Get(),
|
||||
sizeof(UINT64) * GL_RAYTRACING_CMD_RING_SIZE * 2ull,
|
||||
D3D12_HEAP_TYPE_READBACK,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
D3D12_RESOURCE_FLAG_NONE);
|
||||
if (!g_glRaytracingCmd.pathTracingTimestampReadback.resource)
|
||||
return 0;
|
||||
|
||||
g_glRaytracingCmd.pathTracingTimestampFrequency = 0;
|
||||
if (FAILED(g_glRaytracingCmd.queue->GetTimestampFrequency(&g_glRaytracingCmd.pathTracingTimestampFrequency)) ||
|
||||
g_glRaytracingCmd.pathTracingTimestampFrequency == 0)
|
||||
{
|
||||
g_glRaytracingCmd.pathTracingTimestampHeap.Reset();
|
||||
g_glRaytracingCmd.pathTracingTimestampReadback = glRaytracingBuffer_t();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int glRaytracingCreateDirectCommandListPair(
|
||||
ID3D12Device5* device,
|
||||
ComPtr<ID3D12CommandAllocator>& allocator,
|
||||
@@ -562,6 +630,11 @@ static int glRaytracingInitCmdContext(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!glRaytracingCreatePathTracingTimestamps())
|
||||
{
|
||||
glRaytracingLog("path tracing timestamp queries unavailable");
|
||||
}
|
||||
|
||||
g_glRaytracingCmd.initialized = true;
|
||||
return 1;
|
||||
}
|
||||
@@ -586,6 +659,7 @@ static int glRaytracingBeginCmd(void)
|
||||
{
|
||||
const UINT slot = (g_glRaytracingCmd.cmdRingIndex + 1u) % GL_RAYTRACING_CMD_RING_SIZE;
|
||||
glRaytracingWaitFenceValue(g_glRaytracingCmd.cmdFenceValueRing[slot]);
|
||||
glRaytracingPollPathTracingTimestamp(slot);
|
||||
|
||||
g_glRaytracingCmd.cmdRingIndex = slot;
|
||||
g_glRaytracingCmd.cmdCurrentSlot = slot;
|
||||
@@ -1965,12 +2039,52 @@ int glRaytracingUpdateMesh(glRaytracingMeshHandle_t meshHandle, const glRaytraci
|
||||
if (!desc->vertices || !desc->indices || desc->vertexCount == 0 || desc->indexCount == 0)
|
||||
return 0;
|
||||
|
||||
const UINT64 vbBytes = UINT64(desc->vertexCount) * sizeof(glRaytracingVertex_t);
|
||||
const UINT64 ibBytes = UINT64(desc->indexCount) * sizeof(uint32_t);
|
||||
const bool sameVertexData =
|
||||
mesh->verticesCpu.size() == desc->vertexCount &&
|
||||
memcmp(mesh->verticesCpu.data(), desc->vertices, (size_t)vbBytes) == 0;
|
||||
const bool sameIndexData =
|
||||
mesh->indicesCpu.size() == desc->indexCount &&
|
||||
memcmp(mesh->indicesCpu.data(), desc->indices, (size_t)ibBytes) == 0;
|
||||
const bool sameDesc =
|
||||
mesh->descCpu.vertexCount == desc->vertexCount &&
|
||||
mesh->descCpu.indexCount == desc->indexCount &&
|
||||
mesh->descCpu.allowUpdate == desc->allowUpdate &&
|
||||
mesh->descCpu.opaque == desc->opaque;
|
||||
|
||||
if (sameDesc && sameVertexData && sameIndexData)
|
||||
return 1;
|
||||
|
||||
const bool canUpdateExistingBuffers =
|
||||
desc->allowUpdate != 0 &&
|
||||
mesh->descCpu.allowUpdate != 0 &&
|
||||
mesh->descCpu.opaque == desc->opaque &&
|
||||
mesh->blasBuilt != 0 &&
|
||||
mesh->vertexBuffer.resource &&
|
||||
mesh->indexBuffer.resource &&
|
||||
mesh->vertexBuffer.size >= vbBytes &&
|
||||
mesh->indexBuffer.size >= ibBytes &&
|
||||
mesh->verticesCpu.size() == desc->vertexCount &&
|
||||
mesh->indicesCpu.size() == desc->indexCount;
|
||||
|
||||
mesh->descCpu = *desc;
|
||||
mesh->verticesCpu.assign(desc->vertices, desc->vertices + desc->vertexCount);
|
||||
mesh->indicesCpu.assign(desc->indices, desc->indices + desc->indexCount);
|
||||
mesh->descCpu.vertices = nullptr;
|
||||
mesh->descCpu.indices = nullptr;
|
||||
|
||||
if (canUpdateExistingBuffers)
|
||||
{
|
||||
glRaytracingMapCopy(mesh->vertexBuffer.resource.Get(), mesh->verticesCpu.data(), (size_t)vbBytes);
|
||||
if (!sameIndexData)
|
||||
glRaytracingMapCopy(mesh->indexBuffer.resource.Get(), mesh->indicesCpu.data(), (size_t)ibBytes);
|
||||
|
||||
mesh->dirty = 1;
|
||||
glRaytracingInvalidateInstancesForMesh(meshHandle, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -2132,6 +2246,9 @@ int glRaytracingUpdateInstanceInScene(glRaytracingSceneHandle_t worldHandle, glR
|
||||
? 0u
|
||||
: glRaytracingNormalizeVisibleInstanceMask(newDesc.mask);
|
||||
|
||||
if (memcmp(&inst->descCpu, &newDesc, sizeof(newDesc)) == 0)
|
||||
return 1;
|
||||
|
||||
inst->descCpu = newDesc;
|
||||
inst->dirty = 1;
|
||||
|
||||
@@ -6440,6 +6557,18 @@ static bool glRaytracingLightingExecuteInternal(
|
||||
g_glRaytracingCmd.cmdList->SetComputeRootConstantBufferView(2, g_glRaytracingLighting.constantBuffer.gpuVA);
|
||||
g_glRaytracingCmd.cmdList->SetPipelineState1(g_glRaytracingLighting.rtStateObject.Get());
|
||||
|
||||
const UINT timestampBase = g_glRaytracingCmd.cmdCurrentSlot * 2u;
|
||||
const bool writeTimestamp =
|
||||
g_glRaytracingCmd.pathTracingTimestampHeap.Get() != nullptr &&
|
||||
g_glRaytracingCmd.pathTracingTimestampReadback.resource.Get() != nullptr;
|
||||
if (writeTimestamp)
|
||||
{
|
||||
g_glRaytracingCmd.cmdList->EndQuery(
|
||||
g_glRaytracingCmd.pathTracingTimestampHeap.Get(),
|
||||
D3D12_QUERY_TYPE_TIMESTAMP,
|
||||
timestampBase + 0u);
|
||||
}
|
||||
|
||||
const UINT shaderRecordSize = (UINT)glRaytracingAlignUp(
|
||||
D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES,
|
||||
D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT);
|
||||
@@ -6586,9 +6715,27 @@ static bool glRaytracingLightingExecuteInternal(
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
||||
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
|
||||
|
||||
if (writeTimestamp)
|
||||
{
|
||||
g_glRaytracingCmd.cmdList->EndQuery(
|
||||
g_glRaytracingCmd.pathTracingTimestampHeap.Get(),
|
||||
D3D12_QUERY_TYPE_TIMESTAMP,
|
||||
timestampBase + 1u);
|
||||
g_glRaytracingCmd.cmdList->ResolveQueryData(
|
||||
g_glRaytracingCmd.pathTracingTimestampHeap.Get(),
|
||||
D3D12_QUERY_TYPE_TIMESTAMP,
|
||||
timestampBase,
|
||||
2,
|
||||
g_glRaytracingCmd.pathTracingTimestampReadback.resource.Get(),
|
||||
sizeof(UINT64) * timestampBase);
|
||||
}
|
||||
|
||||
if (!glRaytracingEndCmd())
|
||||
return false;
|
||||
|
||||
if (writeTimestamp)
|
||||
g_glRaytracingCmd.pathTracingTimestampFenceRing[g_glRaytracingCmd.cmdCurrentSlot] = g_glRaytracingCmd.cmdLastFenceValue;
|
||||
|
||||
if (useInternalDenoiser)
|
||||
g_glRaytracingLighting.currentHistoryIndex = historyWriteIndex;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user