GPU: Correctly recycle D3D12 descriptor heaps (#14234)

This commit is contained in:
Evan Hemsley
2025-10-13 13:00:00 -07:00
committed by GitHub
parent 228a7d8e54
commit 20206b8e66

View File

@@ -980,6 +980,10 @@ struct D3D12CommandBuffer
// Set at acquire time
D3D12DescriptorHeap *gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + 1];
D3D12DescriptorHeap **usedDescriptorHeaps;
Uint32 usedDescriptorHeapCount;
Uint32 usedDescriptorHeapCapacity;
D3D12UniformBuffer **usedUniformBuffers;
Uint32 usedUniformBufferCount;
Uint32 usedUniformBufferCapacity;
@@ -1565,6 +1569,7 @@ static void D3D12_INTERNAL_DestroyCommandBuffer(D3D12CommandBuffer *commandBuffe
SDL_free(commandBuffer->usedSamplers);
SDL_free(commandBuffer->usedGraphicsPipelines);
SDL_free(commandBuffer->usedComputePipelines);
SDL_free(commandBuffer->usedDescriptorHeaps);
SDL_free(commandBuffer->usedUniformBuffers);
SDL_free(commandBuffer->textureDownloads);
SDL_free(commandBuffer);
@@ -2268,6 +2273,28 @@ static bool D3D12_INTERNAL_ExpandStagingDescriptorPool(
return true;
}
static void D3D12_INTERNAL_TrackGPUDescriptorHeap(
D3D12CommandBuffer *commandBuffer,
D3D12DescriptorHeap *descriptorHeap)
{
Uint32 i;
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
if (commandBuffer->usedDescriptorHeaps[i] == descriptorHeap) {
return;
}
}
if (commandBuffer->usedDescriptorHeapCount == commandBuffer->usedDescriptorHeapCapacity) {
commandBuffer->usedDescriptorHeapCapacity += 1;
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_realloc(
commandBuffer->usedDescriptorHeaps,
commandBuffer->usedDescriptorHeapCapacity * sizeof(D3D12DescriptorHeap *));
}
commandBuffer->usedDescriptorHeaps[commandBuffer->usedDescriptorHeapCount] = descriptorHeap;
commandBuffer->usedDescriptorHeapCount += 1;
}
static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
D3D12CommandBuffer *commandBuffer,
D3D12_DESCRIPTOR_HEAP_TYPE descriptorHeapType)
@@ -2289,6 +2316,7 @@ static D3D12DescriptorHeap *D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(
}
SDL_UnlockMutex(pool->lock);
D3D12_INTERNAL_TrackGPUDescriptorHeap(commandBuffer, result);
return result;
}
@@ -4885,14 +4913,7 @@ static void D3D12_INTERNAL_SetGPUDescriptorHeaps(D3D12CommandBuffer *commandBuff
viewHeap = D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
samplerHeap = D3D12_INTERNAL_AcquireGPUDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
if (commandBuffer->gpuDescriptorHeaps[0] != NULL) {
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(commandBuffer->renderer, commandBuffer->gpuDescriptorHeaps[0]);
}
commandBuffer->gpuDescriptorHeaps[0] = viewHeap;
if (commandBuffer->gpuDescriptorHeaps[1] != NULL) {
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(commandBuffer->renderer, commandBuffer->gpuDescriptorHeaps[1]);
}
commandBuffer->gpuDescriptorHeaps[1] = samplerHeap;
heaps[0] = viewHeap->handle;
@@ -7284,6 +7305,11 @@ static bool D3D12_INTERNAL_AllocateCommandBuffer(
commandBuffer->usedComputePipelines = (D3D12ComputePipeline **)SDL_calloc(
commandBuffer->usedComputePipelineCapacity, sizeof(D3D12ComputePipeline *));
commandBuffer->usedDescriptorHeapCapacity = 4;
commandBuffer->usedDescriptorHeapCount = 0;
commandBuffer->usedDescriptorHeaps = (D3D12DescriptorHeap **)SDL_calloc(
commandBuffer->usedDescriptorHeapCapacity, sizeof(D3D12DescriptorHeap *));
commandBuffer->usedUniformBufferCapacity = 4;
commandBuffer->usedUniformBufferCount = 0;
commandBuffer->usedUniformBuffers = (D3D12UniformBuffer **)SDL_calloc(
@@ -7702,13 +7728,13 @@ static bool D3D12_INTERNAL_CleanCommandBuffer(
NULL);
CHECK_D3D12_ERROR_AND_RETURN("Could not reset command list", false);
// Return descriptor heaps to pool
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
renderer,
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]);
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
renderer,
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]);
// Return descriptor heaps to pool, pools own their own locks
for (i = 0; i < commandBuffer->usedDescriptorHeapCount; i += 1) {
D3D12_INTERNAL_ReturnGPUDescriptorHeapToPool(
renderer,
commandBuffer->usedDescriptorHeaps[i]);
}
commandBuffer->usedDescriptorHeapCount = 0;
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV] = NULL;
commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER] = NULL;