vkd3d: Force LINEAR images to be allocated as committed resources.
We have no way of expressing size / alignment requirements to applications since the API query does not provide us with heap information. Reuse the fallback path for promoting placed to committed. Guardians of the Galaxy hits a case where it tries to place 3x host-visible 3D images in one heap, and they end up overlapping in memory due to a 16x16x80 3D texture taking up far less space in optimal tiling compared to linear tiling on AMD. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
4a07d9c038
commit
233ff38175
|
@ -1477,6 +1477,7 @@ static bool vkd3d_heap_allocation_accept_deferred_resource_placements(struct d3d
|
|||
HRESULT vkd3d_allocate_heap_memory(struct d3d12_device *device, struct vkd3d_memory_allocator *allocator,
|
||||
const struct vkd3d_allocate_heap_memory_info *info, struct vkd3d_memory_allocation *allocation)
|
||||
{
|
||||
struct vkd3d_allocate_heap_memory_info heap_info;
|
||||
struct vkd3d_allocate_memory_info alloc_info;
|
||||
HRESULT hr;
|
||||
|
||||
|
@ -1492,6 +1493,27 @@ HRESULT vkd3d_allocate_heap_memory(struct d3d12_device *device, struct vkd3d_mem
|
|||
if (!(info->heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS))
|
||||
alloc_info.flags |= VKD3D_ALLOCATION_FLAG_GLOBAL_BUFFER;
|
||||
|
||||
if (is_cpu_accessible_heap(&info->heap_desc.Properties))
|
||||
{
|
||||
if (info->heap_desc.Flags & D3D12_HEAP_FLAG_DENY_BUFFERS)
|
||||
{
|
||||
/* If the heap was only designed to handle images, the heap is useless,
|
||||
* and we can force everything to go through committed path. */
|
||||
memset(allocation, 0, sizeof(*allocation));
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* CPU visible textures are never placed on a heap directly,
|
||||
* since LINEAR images have alignment / size requirements
|
||||
* that are vastly different from OPTIMAL ones.
|
||||
* We can place buffers however. */
|
||||
heap_info = *info;
|
||||
info = &heap_info;
|
||||
heap_info.heap_desc.Flags |= D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
}
|
||||
}
|
||||
|
||||
hr = vkd3d_allocate_memory(device, allocator, &alloc_info, allocation);
|
||||
if (hr == E_OUTOFMEMORY && vkd3d_heap_allocation_accept_deferred_resource_placements(device,
|
||||
&info->heap_desc.Properties, info->heap_desc.Flags))
|
||||
|
|
|
@ -2863,15 +2863,25 @@ HRESULT d3d12_resource_create_placed(struct d3d12_device *device, const D3D12_RE
|
|||
VkMemoryRequirements memory_requirements;
|
||||
VkBindImageMemoryInfo bind_info;
|
||||
struct d3d12_resource *object;
|
||||
bool force_committed;
|
||||
VkResult vr;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = d3d12_resource_validate_heap(desc, heap)))
|
||||
return hr;
|
||||
|
||||
if (heap->allocation.device_allocation.vk_memory == VK_NULL_HANDLE)
|
||||
/* Placed linear textures are ... problematic
|
||||
* since we have no way of signalling that they have different alignment and size requirements
|
||||
* than optimal textures. GetResourceAllocationInfo() does not take heap property information
|
||||
* and assumes that we are not modifying the tiling mode. */
|
||||
force_committed = desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER &&
|
||||
is_cpu_accessible_heap(&heap->desc.Properties);
|
||||
|
||||
if (force_committed || heap->allocation.device_allocation.vk_memory == VK_NULL_HANDLE)
|
||||
{
|
||||
WARN("Placing resource on heap with no memory backing it. Falling back to committed resource.\n");
|
||||
if (!force_committed)
|
||||
WARN("Placing resource on heap with no memory backing it. Falling back to committed resource.\n");
|
||||
|
||||
if (FAILED(hr = d3d12_resource_create_committed(device, desc, &heap->desc.Properties,
|
||||
heap->desc.Flags & ~(D3D12_HEAP_FLAG_DENY_BUFFERS |
|
||||
D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES |
|
||||
|
|
Loading…
Reference in New Issue