From 0014c4fbf97224690b4793d5723d9616d545cbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 25 Sep 2018 14:13:02 +0200 Subject: [PATCH] vkd3d: Implement d3d12_device_GetResourceAllocationInfo() for textures. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Vulkan, we have to create an image to get its memory requirements. It would be very helpful if we could get the memory requirements without creating a resource. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- libs/vkd3d/device.c | 50 ++++++++++++++++++++++++++++++-------- libs/vkd3d/resource.c | 24 ++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 16 ++++++------ 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 54196acb..8cc61420 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -2025,7 +2025,10 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour ID3D12Device *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, UINT count, const D3D12_RESOURCE_DESC *resource_descs) { + UINT64 default_alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + struct d3d12_device *device = impl_from_ID3D12Device(iface); const D3D12_RESOURCE_DESC *desc; + bool valid = true; TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p.\n", iface, info, visible_mask, count, resource_descs); @@ -2042,22 +2045,49 @@ static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResour } desc = &resource_descs[0]; - if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - info->SizeInBytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); - info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; - } - else - { - FIXME("Unhandled dimension %#x.\n", desc->Dimension); - } if (FAILED(d3d12_resource_validate_desc(desc))) { WARN("Invalid resource desc.\n"); - info->SizeInBytes = ~(UINT64)0; + valid = false; } + if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + info->SizeInBytes = desc->Width; + info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + } + else + { + if (desc->SampleDesc.Count != 1) + default_alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; + + if (valid && FAILED(vkd3d_get_image_allocation_info(device, desc, info))) + { + WARN("Failed to get allocation info for texture.\n"); + valid = false; + } + } + + if (desc->Alignment % info->Alignment) + { + WARN("Invalid resource alignment %#"PRIx64" (required %#"PRIx64").\n", + desc->Alignment, info->Alignment); + valid = false; + } + + if (valid) + { + info->SizeInBytes = align(info->SizeInBytes, info->Alignment); + } + else + { + info->SizeInBytes = ~(UINT64)0; + info->Alignment = default_alignment; + } + + TRACE("Size %#"PRIx64", alignment %#"PRIx64".\n", info->SizeInBytes, info->Alignment); + return info; } diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index d5690dee..82ff7010 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -409,6 +409,30 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device, return S_OK; } +HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info) +{ + static const D3D12_HEAP_PROPERTIES heap_properties = {D3D12_HEAP_TYPE_DEFAULT}; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkMemoryRequirements requirements; + VkImage vk_image; + HRESULT hr; + + assert(desc->Dimension != D3D12_RESOURCE_DIMENSION_BUFFER); + + /* XXX: We have to create an image to get its memory requirements. */ + if (SUCCEEDED(hr = vkd3d_create_image(device, &heap_properties, 0, desc, &vk_image))) + { + VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements)); + VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL)); + + allocation_info->SizeInBytes = requirements.size; + allocation_info->Alignment = requirements.alignment; + } + + return hr; +} + static unsigned int vkd3d_select_memory_type(struct d3d12_device *device, uint32_t memory_type_mask, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags) { diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index c4d6dd53..189ee432 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -251,6 +251,15 @@ HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_h const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource) DECLSPEC_HIDDEN; struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface) DECLSPEC_HIDDEN; +HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_buffer, + const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, + VkDeviceMemory *vk_memory) DECLSPEC_HIDDEN; +HRESULT vkd3d_create_buffer(struct d3d12_device *device, + const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, + const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer) DECLSPEC_HIDDEN; +HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info) DECLSPEC_HIDDEN; + struct vkd3d_view { LONG refcount; @@ -773,13 +782,6 @@ VkPipeline d3d12_device_find_cached_pipeline(struct d3d12_device *device, bool d3d12_device_put_pipeline_to_cache(struct d3d12_device *device, const struct vkd3d_pipeline_key *key, VkPipeline vk_pipeline, struct list *list) DECLSPEC_HIDDEN; -HRESULT vkd3d_create_buffer(struct d3d12_device *device, - const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, - const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer) DECLSPEC_HIDDEN; -HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_buffer, - const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, - VkDeviceMemory *vk_memory) DECLSPEC_HIDDEN; - /* utils */ struct vkd3d_format {