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>
This commit is contained in:
Bryan Bernhart 2020-04-28 15:58:45 +00:00 committed by Commit Bot service account
parent 88f2ec853f
commit c94f4a7a19
1 changed files with 13 additions and 4 deletions

View File

@ -258,7 +258,13 @@ namespace dawn_native { namespace d3d12 {
resourceInfo = resourceInfo =
mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor); 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."); return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
} }
@ -311,11 +317,14 @@ 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 // If d3d tells us the resource size is invalid, treat the error as OOM.
// lost (too large for driver). Instead, treat the error as a 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 = D3D12_RESOURCE_ALLOCATION_INFO resourceInfo =
mDevice->GetD3D12Device()->GetResourceAllocationInfo(0, 1, &resourceDescriptor); 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."); return DAWN_OUT_OF_MEMORY_ERROR("Resource allocation size was invalid.");
} }