From c94f4a7a191d71ea6954b95fedaf341a49c62d0a Mon Sep 17 00:00:00 2001 From: Bryan Bernhart Date: Tue, 28 Apr 2020 15:58:45 +0000 Subject: [PATCH] D3D12: Fix invalid allocation size check. GetResourceAllocationInfo() returns UINT_MAX64 when the requested size is too large. This corrects the validation to OOM when D3D considers the size invalid. Only validating for zero-size would cause a device loss as certain D3D drivers may not always consider zero-sized invalid and NextPowerOfTwo(UINT_MAX64) would overflow the allocator. BUG=dawn:393 Change-Id: Idaad10c139f6428d4f48bca24027a6691257aca9 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/20400 Reviewed-by: Austin Eng Commit-Queue: Bryan Bernhart --- .../d3d12/ResourceAllocatorManagerD3D12.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp index f9c9316f67..f52c598e4f 100644 --- a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp +++ b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp @@ -258,7 +258,13 @@ namespace dawn_native { namespace d3d12 { resourceInfo = mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor); } - if (resourceInfo.SizeInBytes == 0) { + + // If d3d tells us the resource size is invalid, treat the error as OOM. + // Otherwise, creating the resource could cause a device loss (too large). + // This is because NextPowerOfTwo(UINT64_MAX) overflows and proceeds to + // incorrectly allocate a mismatched size. + if (resourceInfo.SizeInBytes == 0 || + resourceInfo.SizeInBytes == std::numeric_limits::max()) { return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid."); } @@ -311,11 +317,14 @@ namespace dawn_native { namespace d3d12 { heapProperties.CreationNodeMask = 0; heapProperties.VisibleNodeMask = 0; - // If d3d tells us the resource is "zero-sized", the size is invalid and may cause a device - // lost (too large for driver). Instead, treat the error as a OOM. + // If d3d tells us the resource size is invalid, treat the error as OOM. + // Otherwise, creating the resource could cause a device loss (too large). + // This is because NextPowerOfTwo(UINT64_MAX) overflows and proceeds to + // incorrectly allocate a mismatched size. D3D12_RESOURCE_ALLOCATION_INFO resourceInfo = mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor); - if (resourceInfo.SizeInBytes == 0) { + if (resourceInfo.SizeInBytes == 0 || + resourceInfo.SizeInBytes == std::numeric_limits::max()) { return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid."); }