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;