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 <enga@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
diff --git a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
index f9c9316..f52c598 100644
--- a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
+++ b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
@@ -258,7 +258,13 @@
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<uint64_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
}
@@ -311,11 +317,14 @@
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<uint64_t>::max()) {
return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
}