D3D12: Fix 64-bit overflow for large buffers and return OOM.

Use `resourceDesc.alignment` + GetResourceAllocationInfo
 to determine the buffer size and OOM should it return an
empty sized buffer instead of overflowing + INVALID_ARGS.

BUG=dawn:238

Change-Id: I0a2cc7dac629d55624dafa4a3c4a45f16e90049c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14420
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/d3d12/BufferD3D12.cpp b/src/dawn_native/d3d12/BufferD3D12.cpp
index 8f32c36..9cfc536 100644
--- a/src/dawn_native/d3d12/BufferD3D12.cpp
+++ b/src/dawn_native/d3d12/BufferD3D12.cpp
@@ -82,7 +82,7 @@
         D3D12_RESOURCE_DESC resourceDescriptor;
         resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
         resourceDescriptor.Alignment = 0;
-        resourceDescriptor.Width = GetD3D12Size();
+        resourceDescriptor.Width = GetSize();
         resourceDescriptor.Height = 1;
         resourceDescriptor.DepthOrArraySize = 1;
         resourceDescriptor.MipLevels = 1;
@@ -123,11 +123,6 @@
         DestroyInternal();
     }
 
-    uint32_t Buffer::GetD3D12Size() const {
-        // TODO(enga@google.com): TODO investigate if this needs to be a constraint at the API level
-        return Align(GetSize(), 256);
-    }
-
     ComPtr<ID3D12Resource> Buffer::GetD3D12Resource() const {
         return mResourceAllocation.GetD3D12Resource();
     }
diff --git a/src/dawn_native/d3d12/BufferD3D12.h b/src/dawn_native/d3d12/BufferD3D12.h
index 6a5b936..91a7fba 100644
--- a/src/dawn_native/d3d12/BufferD3D12.h
+++ b/src/dawn_native/d3d12/BufferD3D12.h
@@ -33,7 +33,6 @@
 
         MaybeError Initialize();
 
-        uint32_t GetD3D12Size() const;
         ComPtr<ID3D12Resource> GetD3D12Resource() const;
         D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
         void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);
diff --git a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
index 5200a14..e066062 100644
--- a/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
+++ b/src/dawn_native/d3d12/ResourceAllocatorManagerD3D12.cpp
@@ -220,6 +220,9 @@
             resourceInfo =
                 mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor);
         }
+        if (resourceInfo.SizeInBytes == 0) {
+            return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
+        }
 
         BuddyMemoryAllocator* allocator =
             mSubAllocatedResourceAllocators[resourceHeapKindIndex].get();
@@ -261,6 +264,18 @@
         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.
+        D3D12_RESOURCE_ALLOCATION_INFO resourceInfo =
+            mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor);
+        if (resourceInfo.SizeInBytes == 0) {
+            return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
+        }
+
+        if (resourceInfo.SizeInBytes > kMaxHeapSize) {
+            return ResourceHeapAllocation{};  // Invalid
+        }
+
         // Note: Heap flags are inferred by the resource descriptor and do not need to be explicitly
         // provided to CreateCommittedResource.
         ComPtr<ID3D12Resource> committedResource;