diff --git a/src/gpgmm/d3d12/ErrorD3D12.cpp b/src/gpgmm/d3d12/ErrorD3D12.cpp index 77df9ee91..333d6243b 100644 --- a/src/gpgmm/d3d12/ErrorD3D12.cpp +++ b/src/gpgmm/d3d12/ErrorD3D12.cpp @@ -14,6 +14,7 @@ #include "gpgmm/d3d12/ErrorD3D12.h" +#include "gpgmm/utils/Log.h" #include "gpgmm/utils/WindowsUtils.h" #include @@ -30,4 +31,47 @@ namespace gpgmm::d3d12 { return ss.str(); } + std::string GetDeviceErrorMessage(ID3D12Device* device, HRESULT error) { + if (error == DXGI_ERROR_DEVICE_REMOVED) { + if (device == nullptr) { + return "Device was not found but removed " + GetErrorMessage(error); + } + + HRESULT removedReason = device->GetDeviceRemovedReason(); + std::string removedReasonStr; + switch (error) { + case DXGI_ERROR_DEVICE_HUNG: { + removedReasonStr = "HUNG"; + break; + } + case DXGI_ERROR_DEVICE_REMOVED: { + removedReasonStr = "REMOVED"; + break; + } + case DXGI_ERROR_DEVICE_RESET: { + removedReasonStr = "RESET"; + break; + } + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: { + removedReasonStr = "INTERNAL_ERROR"; + break; + } + case DXGI_ERROR_INVALID_CALL: { + removedReasonStr = "INVALID_CALL"; + break; + } + case S_OK: { + removedReasonStr = "S_OK"; + break; + } + default: + break; + } + + return "Device was removed: " + removedReasonStr + " " + GetErrorMessage(removedReason); + } + + return GetErrorMessage(error); + } + } // namespace gpgmm::d3d12 diff --git a/src/gpgmm/d3d12/ErrorD3D12.h b/src/gpgmm/d3d12/ErrorD3D12.h index e4cd9eadd..645ea2c24 100644 --- a/src/gpgmm/d3d12/ErrorD3D12.h +++ b/src/gpgmm/d3d12/ErrorD3D12.h @@ -41,7 +41,7 @@ namespace gpgmm::d3d12 { for (;;) \ break - std::string GetErrorMessage(HRESULT error); + std::string GetDeviceErrorMessage(ID3D12Device* device, HRESULT error); } // namespace gpgmm::d3d12 diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index b99bd9b84..e004166ab 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -250,7 +250,8 @@ namespace gpgmm::d3d12 { // If the memory allocation was successful, the resource will be created using it. // Else, if the resource creation fails, the memory allocation will be cleaned up. template - HRESULT TryAllocateResource(MemoryAllocator* allocator, + HRESULT TryAllocateResource(ID3D12Device* device, + MemoryAllocator* allocator, const MemoryAllocationRequest& request, CreateResourceFn&& createResourceFn) { std::unique_ptr allocation = allocator->TryAllocateMemory(request); @@ -266,7 +267,8 @@ namespace gpgmm::d3d12 { HRESULT hr = createResourceFn(*allocation); if (FAILED(hr)) { InfoEvent(allocator->GetTypename(), EventMessageId::AllocatorFailed) - << "Failed to create resource using allocation: " + GetErrorMessage(hr); + << "Failed to create resource using allocation: " + + GetDeviceErrorMessage(device, hr); allocator->DeallocateMemory(std::move(allocation)); } return hr; @@ -838,8 +840,8 @@ namespace gpgmm::d3d12 { // CreateResource(). request.AlwaysPrefetch = false; - ReturnIfSucceeded( - TryAllocateResource(allocator, request, [&](const auto& subAllocation) -> HRESULT { + ReturnIfSucceeded(TryAllocateResource( + mDevice.Get(), allocator, request, [&](const auto& subAllocation) -> HRESULT { // Committed resource implicitly creates a resource heap which can be // used for sub-allocation. ComPtr committedResource; @@ -875,8 +877,8 @@ namespace gpgmm::d3d12 { request.Alignment = resourceInfo.Alignment; - ReturnIfSucceeded( - TryAllocateResource(allocator, request, [&](const auto& subAllocation) -> HRESULT { + ReturnIfSucceeded(TryAllocateResource( + mDevice.Get(), allocator, request, [&](const auto& subAllocation) -> HRESULT { // Resource is placed at an offset corresponding to the allocation offset. // Each allocation maps to a disjoint (physical) address range so no physical // memory is can be aliased or will overlap. @@ -918,8 +920,8 @@ namespace gpgmm::d3d12 { request.Alignment = allocator->GetMemoryAlignment(); - ReturnIfSucceeded( - TryAllocateResource(allocator, request, [&](const auto& allocation) -> HRESULT { + ReturnIfSucceeded(TryAllocateResource( + mDevice.Get(), allocator, request, [&](const auto& allocation) -> HRESULT { Heap* resourceHeap = ToBackend(allocation.GetMemory()); ComPtr placedResource; ReturnIfFailed(CreatePlacedResource(resourceHeap, allocation.GetOffset(), @@ -951,8 +953,8 @@ namespace gpgmm::d3d12 { } if (!isAlwaysCommitted) { - InfoEvent(GetTypename(), EventMessageId::Unknown) - << "Resource allocation could not be created from memory pool."; + InfoEvent(GetTypename(), EventMessageId::AllocatorFailed) + << "Unable to allocate by using a heap, falling back to a committed resource."; } ComPtr committedResource;