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.");
         }