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>
This commit is contained in:
Bryan Bernhart 2019-12-11 17:13:21 +00:00 committed by Commit Bot service account
parent 280b96ea8d
commit 6ce8f32fee
3 changed files with 16 additions and 7 deletions

View File

@ -82,7 +82,7 @@ namespace dawn_native { namespace d3d12 {
D3D12_RESOURCE_DESC resourceDescriptor; D3D12_RESOURCE_DESC resourceDescriptor;
resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; resourceDescriptor.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDescriptor.Alignment = 0; resourceDescriptor.Alignment = 0;
resourceDescriptor.Width = GetD3D12Size(); resourceDescriptor.Width = GetSize();
resourceDescriptor.Height = 1; resourceDescriptor.Height = 1;
resourceDescriptor.DepthOrArraySize = 1; resourceDescriptor.DepthOrArraySize = 1;
resourceDescriptor.MipLevels = 1; resourceDescriptor.MipLevels = 1;
@ -123,11 +123,6 @@ namespace dawn_native { namespace d3d12 {
DestroyInternal(); 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 { ComPtr<ID3D12Resource> Buffer::GetD3D12Resource() const {
return mResourceAllocation.GetD3D12Resource(); return mResourceAllocation.GetD3D12Resource();
} }

View File

@ -33,7 +33,6 @@ namespace dawn_native { namespace d3d12 {
MaybeError Initialize(); MaybeError Initialize();
uint32_t GetD3D12Size() const;
ComPtr<ID3D12Resource> GetD3D12Resource() const; ComPtr<ID3D12Resource> GetD3D12Resource() const;
D3D12_GPU_VIRTUAL_ADDRESS GetVA() const; D3D12_GPU_VIRTUAL_ADDRESS GetVA() const;
void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite); void OnMapCommandSerialFinished(uint32_t mapSerial, void* data, bool isWrite);

View File

@ -220,6 +220,9 @@ namespace dawn_native { namespace d3d12 {
resourceInfo = resourceInfo =
mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor); mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor);
} }
if (resourceInfo.SizeInBytes == 0) {
return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
}
BuddyMemoryAllocator* allocator = BuddyMemoryAllocator* allocator =
mSubAllocatedResourceAllocators[resourceHeapKindIndex].get(); mSubAllocatedResourceAllocators[resourceHeapKindIndex].get();
@ -261,6 +264,18 @@ namespace dawn_native { namespace d3d12 {
heapProperties.CreationNodeMask = 0; heapProperties.CreationNodeMask = 0;
heapProperties.VisibleNodeMask = 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 // Note: Heap flags are inferred by the resource descriptor and do not need to be explicitly
// provided to CreateCommittedResource. // provided to CreateCommittedResource.
ComPtr<ID3D12Resource> committedResource; ComPtr<ID3D12Resource> committedResource;