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; range.End = readRange->end;
} }
void *outputData; void *outputData = nullptr;
d3d->Map(subresource, (readRange != nullptr) ? &range : nullptr, &outputData); d3d->Map(subresource, (readRange != nullptr) ? &range : nullptr, &outputData);
return outputData; return outputData;
} }
@ -2638,7 +2638,15 @@ namespace plume {
this->desc = desc; this->desc = desc;
D3D12MA::POOL_DESC poolDesc = {}; 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.MinBlockCount = desc.minBlockCount;
poolDesc.MaxBlockCount = desc.maxBlockCount; poolDesc.MaxBlockCount = desc.maxBlockCount;
poolDesc.Flags |= desc.useLinearAlgorithm ? D3D12MA::POOL_FLAG_ALGORITHM_LINEAR : D3D12MA::POOL_FLAG_NONE; poolDesc.Flags |= desc.useLinearAlgorithm ? D3D12MA::POOL_FLAG_ALGORITHM_LINEAR : D3D12MA::POOL_FLAG_NONE;
@ -3435,7 +3443,10 @@ namespace plume {
capabilities.triangleFan = triangleFanSupportOption; capabilities.triangleFan = triangleFanSupportOption;
capabilities.dynamicDepthBias = dynamicDepthBiasOption; capabilities.dynamicDepthBias = dynamicDepthBiasOption;
capabilities.uma = uma; 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.name = deviceName;
description.dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory; description.dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory;
description.vendor = RenderDeviceVendor(adapterDesc.VendorId); description.vendor = RenderDeviceVendor(adapterDesc.VendorId);
@ -3533,6 +3544,13 @@ namespace plume {
colorTargetHeapAllocator = std::make_unique<D3D12DescriptorHeapAllocator>(this, TargetDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); colorTargetHeapAllocator = std::make_unique<D3D12DescriptorHeapAllocator>(this, TargetDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
depthTargetHeapAllocator = std::make_unique<D3D12DescriptorHeapAllocator>(this, TargetDescriptorHeapSize, D3D12_DESCRIPTOR_HEAP_TYPE_DSV); 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. // 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); std::unique_ptr<D3D12CommandQueue> timestampCommandQueue = std::make_unique<D3D12CommandQueue>(this, RenderCommandListType::DIRECT);
res = timestampCommandQueue->d3d->GetTimestampFrequency(&timestampFrequency); res = timestampCommandQueue->d3d->GetTimestampFrequency(&timestampFrequency);
@ -3582,7 +3600,12 @@ namespace plume {
} }
std::unique_ptr<RenderBuffer> D3D12Device::createBuffer(const RenderBufferDesc &desc) { 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) { 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> samplerHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator; std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator; std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
std::unique_ptr<D3D12Pool> customUploadPool;
RenderDeviceCapabilities capabilities; RenderDeviceCapabilities capabilities;
RenderDeviceDescription description; RenderDeviceDescription description;
uint64_t timestampFrequency = 1; 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); return LockBuffer(buffer, flags);
} }
static std::atomic<uint32_t> g_bufferUploadCount = 0;
template<typename T> template<typename T>
static void UnlockBuffer(GuestBuffer* buffer, bool useCopyQueue) 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())); copyBuffer(reinterpret_cast<T*>(buffer->buffer->map()));
buffer->buffer->unmap(); buffer->buffer->unmap();
@ -2153,6 +2155,8 @@ static void UnlockBuffer(GuestBuffer* buffer, bool useCopyQueue)
g_tempBuffers[g_frame].emplace_back(std::move(uploadBuffer)); g_tempBuffers[g_frame].emplace_back(std::move(uploadBuffer));
} }
} }
g_bufferUploadCount++;
} }
template<typename T> template<typename T>
@ -2334,6 +2338,7 @@ static void DrawProfiler()
ImGui::Text("Heap Allocated: %d MB", int32_t(diagnostics.allocated / (1024 * 1024))); 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("Physical Heap Allocated: %d MB", int32_t(physicalDiagnostics.allocated / (1024 * 1024)));
ImGui::Text("GPU Waits: %d", int32_t(g_waitForGPUCount)); ImGui::Text("GPU Waits: %d", int32_t(g_waitForGPUCount));
ImGui::Text("Buffer Uploads: %d", int32_t(g_bufferUploadCount));
ImGui::NewLine(); ImGui::NewLine();
ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported"); ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported");