Finish D3D12 Support.

This commit is contained in:
Dario 2025-03-18 22:33:03 -03:00
parent 07fe67092f
commit 6a24d35dec
3 changed files with 36 additions and 7 deletions

View file

@ -2387,7 +2387,7 @@ namespace plume {
range.End = readRange->end;
}
void *outputData;
void *outputData = nullptr;
d3d->Map(subresource, (readRange != nullptr) ? &range : nullptr, &outputData);
return outputData;
}
@ -2638,7 +2638,15 @@ namespace plume {
this->desc = desc;
D3D12MA::POOL_DESC poolDesc = {};
poolDesc.HeapProperties.Type = toD3D12(desc.heapType);
// When using an UMA architecture without explicit support for GPU Upload heaps, we instead just make a custom heap with the same properties as Upload heaps.
if (desc.heapType == RenderHeapType::GPU_UPLOAD && device->capabilities.uma && !device->capabilities.gpuUploadHeap) {
poolDesc.HeapProperties = device->d3d->GetCustomHeapProperties(0, D3D12_HEAP_TYPE_UPLOAD);
}
else {
poolDesc.HeapProperties.Type = toD3D12(desc.heapType);
}
poolDesc.MinBlockCount = desc.minBlockCount;
poolDesc.MaxBlockCount = desc.maxBlockCount;
poolDesc.Flags |= desc.useLinearAlgorithm ? D3D12MA::POOL_FLAG_ALGORITHM_LINEAR : D3D12MA::POOL_FLAG_NONE;
@ -3392,7 +3400,7 @@ namespace plume {
if (SUCCEEDED(res)) {
triangleFanSupportOption = d3d12Options15.TriangleFanSupported;
}
// Check if dynamic depth bias and GPU upload heap are supported.
bool dynamicDepthBiasOption = false;
bool gpuUploadHeapOption = false;
@ -3435,7 +3443,10 @@ namespace plume {
capabilities.triangleFan = triangleFanSupportOption;
capabilities.dynamicDepthBias = dynamicDepthBiasOption;
capabilities.uma = uma;
capabilities.gpuUploadHeap = gpuUploadHeapOption;
// Pretend GPU Upload heaps are supported if UMA is supported, as the backend has a workaround using a custom pool for it.
capabilities.gpuUploadHeap = uma || gpuUploadHeapOption;
description.name = deviceName;
description.dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory;
description.vendor = RenderDeviceVendor(adapterDesc.VendorId);
@ -3533,6 +3544,13 @@ namespace plume {
colorTargetHeapAllocator = std::make_unique<D3D12DescriptorHeapAllocator>(this, TargetDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
depthTargetHeapAllocator = std::make_unique<D3D12DescriptorHeapAllocator>(this, TargetDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
// Create the custom upload pool that will be used as the fallback when using an UMA architecture without explicit support for GPU Upload heaps.
if (capabilities.uma && !capabilities.gpuUploadHeap) {
RenderPoolDesc poolDesc;
poolDesc.heapType = RenderHeapType::GPU_UPLOAD;
customUploadPool = std::make_unique<D3D12Pool>(this, poolDesc);
}
// Create a command queue only for retrieving the timestamp frequency. Delete it immediately afterwards.
std::unique_ptr<D3D12CommandQueue> timestampCommandQueue = std::make_unique<D3D12CommandQueue>(this, RenderCommandListType::DIRECT);
res = timestampCommandQueue->d3d->GetTimestampFrequency(&timestampFrequency);
@ -3582,7 +3600,12 @@ namespace plume {
}
std::unique_ptr<RenderBuffer> D3D12Device::createBuffer(const RenderBufferDesc &desc) {
return std::make_unique<D3D12Buffer>(this, nullptr, desc);
if ((desc.heapType == RenderHeapType::GPU_UPLOAD) && capabilities.uma && !capabilities.gpuUploadHeap) {
return std::make_unique<D3D12Buffer>(this, customUploadPool.get(), desc);
}
else {
return std::make_unique<D3D12Buffer>(this, nullptr, desc);
}
}
std::unique_ptr<RenderTexture> D3D12Device::createTexture(const RenderTextureDesc &desc) {

View file

@ -430,6 +430,7 @@ namespace plume {
std::unique_ptr<D3D12DescriptorHeapAllocator> samplerHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
std::unique_ptr<D3D12Pool> customUploadPool;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
uint64_t timestampFrequency = 1;

View file

@ -2109,6 +2109,8 @@ static void* LockVertexBuffer(GuestBuffer* buffer, uint32_t, uint32_t, uint32_t
return LockBuffer(buffer, flags);
}
static std::atomic<uint32_t> g_bufferUploadCount = 0;
template<typename T>
static void UnlockBuffer(GuestBuffer* buffer, bool useCopyQueue)
{
@ -2124,7 +2126,7 @@ static void UnlockBuffer(GuestBuffer* buffer, bool useCopyQueue)
}
};
if (useCopyQueue && (g_capabilities.uma || g_capabilities.gpuUploadHeap))
if (useCopyQueue && g_capabilities.gpuUploadHeap)
{
copyBuffer(reinterpret_cast<T*>(buffer->buffer->map()));
buffer->buffer->unmap();
@ -2153,6 +2155,8 @@ static void UnlockBuffer(GuestBuffer* buffer, bool useCopyQueue)
g_tempBuffers[g_frame].emplace_back(std::move(uploadBuffer));
}
}
g_bufferUploadCount++;
}
template<typename T>
@ -2330,10 +2334,11 @@ static void DrawProfiler()
std::lock_guard lock(g_userHeap.physicalMutex);
physicalDiagnostics = o1heapGetDiagnostics(g_userHeap.physicalHeap);
}
ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024)));
ImGui::Text("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
ImGui::Text("GPU Waits: %d", int32_t(g_waitForGPUCount));
ImGui::Text("Buffer Uploads: %d", int32_t(g_bufferUploadCount));
ImGui::NewLine();
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");