vkd3d: reject creating a resource that is placed if the heap is too small

The spec is pretty clear that it's invalid usage. Return E_INVALIDARG
like native drivers.

This is a workaround for the inventory GPU hang with Cyberpunk 2077
which is actually a game bug. Luckily the game handles this error
properly.

The problem is that the game always assume that an image with 2 mips
is smaller than the same image but with 6 mips. This is not always
true if the swizzle mode is different and a recent Mesa update changed
that. Then the game creates a D3D12 heap that is too small and this
triggered a memory violation and then a GPU hang with RADV.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
Samuel Pitoiset 2021-06-17 14:19:05 +02:00 committed by Hans-Kristian Arntzen
parent 1ea31701c5
commit 72d9b322b8
1 changed files with 18 additions and 0 deletions

View File

@ -2552,6 +2552,24 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
/* Align manually. This works because we padded the required allocation size reported to the app. */
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, object->res.vk_image, &memory_requirements));
heap_offset = align(heap_offset, memory_requirements.alignment);
if (heap_offset + memory_requirements.size > heap->allocation.resource.size)
{
ERR("Heap too small for the texture (heap=%"PRIu64", res=%"PRIu64".\n",
heap->allocation.resource.size, heap_offset + memory_requirements.size);
hr = E_INVALIDARG;
goto fail;
}
}
else
{
if (heap_offset + desc->Width > heap->allocation.resource.size)
{
ERR("Heap too small for the buffer (heap=%"PRIu64", res=%"PRIu64".\n",
heap->allocation.resource.size, heap_offset + desc->Width);
hr = E_INVALIDARG;
goto fail;
}
}
vkd3d_memory_allocation_slice(&object->mem, &heap->allocation, heap_offset, 0);