From 60fc7ee1572fb47c1bb27871c5ec5b75b2a4d0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 27 Sep 2016 12:13:37 +0200 Subject: [PATCH] libs/vkd3d: Allocate VkCommandBuffer when creating ID3D12CommandList. --- libs/vkd3d/command.c | 92 +++++++++++++++++++++++++++++++++++++- libs/vkd3d/vkd3d_private.h | 5 +++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 278ab40a..dd90e0ca 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -22,6 +22,72 @@ #include "vkd3d_private.h" +static HRESULT vkd3d_command_allocator_allocate_command_list(struct d3d12_command_allocator *allocator, + struct d3d12_command_list *list) +{ + struct d3d12_device *device = allocator->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkCommandBufferAllocateInfo command_buffer_info; + VkCommandBufferBeginInfo begin_info; + VkResult vr; + + TRACE("allocator %p, list %p.\n", allocator, list); + + if (allocator->current_command_list) + { + FIXME("Allocation for multiple command list not supported.\n"); + return E_NOTIMPL; + } + + command_buffer_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_info.pNext = NULL; + command_buffer_info.commandPool = allocator->vk_command_pool; + command_buffer_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_info.commandBufferCount = 1; + + if ((vr = VK_CALL(vkAllocateCommandBuffers(device->vk_device, &command_buffer_info, + &list->vk_command_buffer)))) + { + WARN("Failed to allocate Vulkan command buffer, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + begin_info.pNext = NULL; + begin_info.flags = 0; + begin_info.pInheritanceInfo = NULL; + + if ((vr = VK_CALL(vkBeginCommandBuffer(list->vk_command_buffer, &begin_info)))) + ERR("Failed to begin command buffer, vr %d.\n", vr); + + allocator->current_command_list = list; + + return S_OK; +} + +static void vkd3d_command_allocator_free_command_list(struct d3d12_command_allocator *allocator, + struct d3d12_command_list *list) +{ + struct d3d12_device *device = allocator->device; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + + TRACE("allocator %p, list %p.\n", allocator, list); + + VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool, + 1, &list->vk_command_buffer)); + + if (allocator->current_command_list == list) + allocator->current_command_list = NULL; +} + +static void vkd3d_command_list_destroyed(struct d3d12_command_list *list) +{ + TRACE("list %p.\n", list); + + list->allocator = NULL; + list->vk_command_buffer = VK_NULL_HANDLE; +} + /* ID3D12CommandAllocator */ static inline struct d3d12_command_allocator *impl_from_ID3D12CommandAllocator(ID3D12CommandAllocator *iface) { @@ -72,6 +138,9 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo struct d3d12_device *device = allocator->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + if (allocator->current_command_list) + vkd3d_command_list_destroyed(allocator->current_command_list); + VK_CALL(vkDestroyCommandPool(device->vk_device, allocator->vk_command_pool, NULL)); vkd3d_free(allocator); @@ -191,6 +260,8 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo return hresult_from_vk_result(vr); } + allocator->current_command_list = NULL; + allocator->device = device; ID3D12Device_AddRef(&device->ID3D12Device_iface); @@ -274,6 +345,10 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL { struct d3d12_device *device = list->device; + /* When command pool is destroyed, all command buffers are implicitly freed. */ + if (list->allocator) + vkd3d_command_allocator_free_command_list(list->allocator, list); + vkd3d_free(list); ID3D12Device_Release(&device->ID3D12Device_iface); @@ -760,20 +835,28 @@ static const struct ID3D12GraphicsCommandListVtbl d3d12_command_list_vtbl = d3d12_command_list_ExecuteIndirect, }; -static void d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, +static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, D3D12_COMMAND_LIST_TYPE type, struct d3d12_command_allocator *allocator, ID3D12PipelineState *initial_pipeline_state) { + HRESULT hr; + list->ID3D12GraphicsCommandList_iface.lpVtbl = &d3d12_command_list_vtbl; list->refcount = 1; list->type = type; + list->allocator = allocator; + if (FAILED(hr = vkd3d_command_allocator_allocate_command_list(allocator, list))) + return hr; + if (initial_pipeline_state) FIXME("Ignoring initial pipeline state %p.\n", initial_pipeline_state); list->device = device; ID3D12Device_AddRef(&device->ID3D12Device_iface); + + return S_OK; } HRESULT d3d12_command_list_create(struct d3d12_device *device, @@ -782,6 +865,7 @@ HRESULT d3d12_command_list_create(struct d3d12_device *device, { struct d3d12_command_allocator *allocator; struct d3d12_command_list *object; + HRESULT hr; if (!(allocator = unsafe_impl_from_ID3D12CommandAllocator(allocator_iface))) { @@ -802,7 +886,11 @@ HRESULT d3d12_command_list_create(struct d3d12_device *device, if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY; - d3d12_command_list_init(object, device, type, allocator, initial_pipeline_state); + if (FAILED(hr = d3d12_command_list_init(object, device, type, allocator, initial_pipeline_state))) + { + vkd3d_free(object); + return hr; + } TRACE("Created command list %p.\n", object); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 2c36f06c..951fbbea 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -32,6 +32,7 @@ #include +struct d3d12_command_list; struct d3d12_device; struct vkd3d_instance @@ -108,6 +109,7 @@ struct d3d12_command_allocator VkCommandPool vk_command_pool; + struct d3d12_command_list *current_command_list; struct d3d12_device *device; }; @@ -122,6 +124,9 @@ struct d3d12_command_list D3D12_COMMAND_LIST_TYPE type; + VkCommandBuffer vk_command_buffer; + + struct d3d12_command_allocator *allocator; struct d3d12_device *device; };