From: Conor McCarthy Subject: [PATCH vkd3d] vkd3d: Return the standard D3D12 resource alignment instead the Vulkan requirement. Message-Id: <20210604143012.34408-1-cmccarthy@codeweavers.com> Date: Sat, 5 Jun 2021 00:30:12 +1000 Some apps, e.g. WoW, ignore a non-standard alignment and use the expected one. Signed-off-by: Conor McCarthy --- libs/vkd3d/device.c | 15 ++++++++++++--- libs/vkd3d/resource.c | 6 ++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index a63fc92b..941e6d04 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3221,7 +3221,7 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) { - info->SizeInBytes = desc->Width; + info->SizeInBytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; } else @@ -3235,9 +3235,18 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour requested_alignment = desc->Alignment ? desc->Alignment : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; info->Alignment = max(info->Alignment, requested_alignment); - } - info->SizeInBytes = align(info->SizeInBytes, info->Alignment); + info->SizeInBytes = align(info->SizeInBytes, info->Alignment); + + /* Pad by the maximum heap offset increase which may be needed to align an offset + * supplied by the calling application to a higher Vulkan requirement. This allows + * us to return the standard D3D12 alignment and adjust resource placement later. */ + if(info->Alignment > requested_alignment) + { + info->SizeInBytes += info->Alignment - requested_alignment; + info->Alignment = requested_alignment; + } + } TRACE("Size %#"PRIx64", alignment %#"PRIx64".\n", info->SizeInBytes, info->Alignment); diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index a9d4d464..f3ddc9cb 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1901,9 +1901,15 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, VkResult vr; if (d3d12_resource_is_buffer(resource)) + { VK_CALL(vkGetBufferMemoryRequirements(vk_device, resource->u.vk_buffer, &requirements)); + } else + { VK_CALL(vkGetImageMemoryRequirements(vk_device, resource->u.vk_image, &requirements)); + /* Padding in d3d12_device_GetResourceAllocationInfo() leaves room to align the offset. */ + heap_offset = align(heap_offset, requirements.alignment); + } if (heap_offset % requirements.alignment) { -- 2.31.1