From 0b2702d96ec869cf8218e14b1ab10442992bec6b Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 3 Nov 2016 20:20:38 +0100 Subject: [PATCH] libs/vkd3d: Implement d3d12_command_list_SetGraphicsRootSignature(). --- libs/vkd3d/command.c | 83 +++++++++++++++++++++++++++++++++++++- libs/vkd3d/state.c | 25 +++++++++++- libs/vkd3d/vkd3d_private.h | 9 +++++ 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 5be16887..93d4191a 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -619,6 +619,18 @@ static bool d3d12_command_allocator_add_pipeline(struct d3d12_command_allocator return true; } +static bool d3d12_command_allocator_add_descriptor_pool(struct d3d12_command_allocator *allocator, + VkDescriptorPool pool) +{ + if (!vkd3d_array_reserve((void **)&allocator->descriptor_pools, &allocator->descriptor_pools_size, + allocator->descriptor_pool_count + 1, sizeof(*allocator->descriptor_pools))) + return false; + + allocator->descriptor_pools[allocator->descriptor_pool_count++] = pool; + + return true; +} + static void d3d12_command_list_allocator_destroyed(struct d3d12_command_list *list) { TRACE("list %p.\n", list); @@ -681,6 +693,12 @@ static ULONG STDMETHODCALLTYPE d3d12_command_allocator_Release(ID3D12CommandAllo if (allocator->current_command_list) d3d12_command_list_allocator_destroyed(allocator->current_command_list); + for (i = 0; i < allocator->descriptor_pool_count; ++i) + { + VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); + } + vkd3d_free(allocator->descriptor_pools); + for (i = 0; i < allocator->pipeline_count; ++i) { VK_CALL(vkDestroyPipeline(device->vk_device, allocator->pipelines[i], NULL)); @@ -777,6 +795,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_allocator_Reset(ID3D12CommandAllo device = allocator->device; vk_procs = &device->vk_procs; + for (i = 0; i < allocator->descriptor_pool_count; ++i) + { + VK_CALL(vkDestroyDescriptorPool(device->vk_device, allocator->descriptor_pools[i], NULL)); + } + allocator->descriptor_pool_count = 0; + for (i = 0; i < allocator->pipeline_count; ++i) { VK_CALL(vkDestroyPipeline(device->vk_device, allocator->pipelines[i], NULL)); @@ -885,6 +909,10 @@ static HRESULT d3d12_command_allocator_init(struct d3d12_command_allocator *allo allocator->pipelines_size = 0; allocator->pipeline_count = 0; + allocator->descriptor_pools = NULL; + allocator->descriptor_pools_size = 0; + allocator->descriptor_pool_count = 0; + allocator->command_buffers = NULL; allocator->command_buffers_size = 0; allocator->command_buffer_count = 0; @@ -2048,7 +2076,57 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList *iface, ID3D12RootSignature *root_signature) { - FIXME("iface %p, root_signature %p stub!\n", iface, root_signature); + struct d3d12_root_signature *rs = unsafe_impl_from_ID3D12RootSignature(root_signature); + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); + const struct vkd3d_vk_device_procs *vk_procs; + struct VkDescriptorSetAllocateInfo set_desc; + struct VkDescriptorPoolCreateInfo pool_desc; + VkDescriptorSet vk_descriptor_set; + VkDescriptorPool vk_pool; + VkResult vr; + + TRACE("iface %p, root_signature %p.\n", iface, root_signature); + + if (list->root_signature == rs || !rs->pool_size_count) + return; + + vk_procs = &list->device->vk_procs; + + pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_desc.pNext = NULL; + pool_desc.flags = 0; + pool_desc.maxSets = 1; + pool_desc.poolSizeCount = rs->pool_size_count; + pool_desc.pPoolSizes = rs->pool_sizes; + if ((vr = VK_CALL(vkCreateDescriptorPool(list->device->vk_device, &pool_desc, NULL, &vk_pool))) < 0) + { + ERR("Failed to create descriptor pool, vr %d.\n", vr); + return; + } + + set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + set_desc.pNext = NULL; + set_desc.descriptorPool = vk_pool; + set_desc.descriptorSetCount = 1; + set_desc.pSetLayouts = &rs->vk_set_layout; + if ((vr = VK_CALL(vkAllocateDescriptorSets(list->device->vk_device, &set_desc, &vk_descriptor_set))) < 0) + { + ERR("Failed to allocate descriptor set, vr %d.\n", vr); + VK_CALL(vkDestroyDescriptorPool(list->device->vk_device, vk_pool, NULL)); + return; + } + + if (!(d3d12_command_allocator_add_descriptor_pool(list->allocator, vk_pool))) + { + ERR("Failed to add descriptor pool.\n"); + VK_CALL(vkDestroyDescriptorPool(list->device->vk_device, vk_pool, NULL)); + return; + } + + VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, + rs->vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL)); + + list->root_signature = rs; } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList *iface, @@ -2606,6 +2684,9 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d list->current_framebuffer = VK_NULL_HANDLE; list->current_pipeline = VK_NULL_HANDLE; + list->state = NULL; + list->root_signature = NULL; + return S_OK; } diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index baf44935..d4483831 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -73,6 +73,7 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_Release(ID3D12RootSignature const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; VK_CALL(vkDestroyPipelineLayout(device->vk_device, root_signature->vk_pipeline_layout, NULL)); + vkd3d_free(root_signature->pool_sizes); VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); vkd3d_free(root_signature); @@ -139,7 +140,7 @@ static const struct ID3D12RootSignatureVtbl d3d12_root_signature_vtbl = d3d12_root_signature_GetDevice, }; -static struct d3d12_root_signature *unsafe_impl_from_ID3D12RootSignature(ID3D12RootSignature *iface) +struct d3d12_root_signature *unsafe_impl_from_ID3D12RootSignature(ID3D12RootSignature *iface) { if (!iface) return NULL; @@ -175,6 +176,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa struct VkPipelineLayoutCreateInfo pipeline_layout_info; struct VkDescriptorSetLayoutBinding *binding_desc; struct VkDescriptorSetLayoutCreateInfo set_desc; + size_t cbv_count = 0; unsigned int i; VkResult vr; @@ -208,6 +210,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa binding_desc[i].descriptorCount = 1; binding_desc[i].stageFlags = stage_flags_from_visibility(p->ShaderVisibility); binding_desc[i].pImmutableSamplers = NULL; + ++cbv_count; break; default: @@ -231,6 +234,24 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa return hresult_from_vk_result(vr); } + if (cbv_count) + { + if (!(root_signature->pool_sizes = vkd3d_calloc(1, sizeof(*root_signature->pool_sizes)))) + { + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); + return E_OUTOFMEMORY; + } + root_signature->pool_size_count = 1; + + root_signature->pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + root_signature->pool_sizes[0].descriptorCount = cbv_count; + } + else + { + root_signature->pool_sizes = NULL; + root_signature->pool_size_count = 0; + } + pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_info.pNext = NULL; pipeline_layout_info.flags = 0; @@ -243,6 +264,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa &root_signature->vk_pipeline_layout))) < 0) { WARN("Failed to create Vulkan pipeline layout, vr %d.\n", vr); + vkd3d_free(root_signature->pool_sizes); + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); return hresult_from_vk_result(vr); } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 254b4d1c..d2b13b60 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -217,11 +217,15 @@ struct d3d12_root_signature VkPipelineLayout vk_pipeline_layout; VkDescriptorSetLayout vk_set_layout; + struct VkDescriptorPoolSize *pool_sizes; + size_t pool_size_count; + struct d3d12_device *device; }; HRESULT d3d12_root_signature_create(struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc, struct d3d12_root_signature **root_signature) DECLSPEC_HIDDEN; +struct d3d12_root_signature *unsafe_impl_from_ID3D12RootSignature(ID3D12RootSignature *iface) DECLSPEC_HIDDEN; struct d3d12_graphics_pipeline_state { @@ -294,6 +298,10 @@ struct d3d12_command_allocator size_t pipelines_size; size_t pipeline_count; + VkDescriptorPool *descriptor_pools; + size_t descriptor_pools_size; + size_t descriptor_pool_count; + VkCommandBuffer *command_buffers; size_t command_buffers_size; size_t command_buffer_count; @@ -329,6 +337,7 @@ struct d3d12_command_list VkPipeline current_pipeline; struct d3d12_pipeline_state *state; + struct d3d12_root_signature *root_signature; struct d3d12_command_allocator *allocator; struct d3d12_device *device;