From 32e69fa9453b38495a4a6e0f00ab67ad439a8429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Fri, 11 Aug 2017 13:58:04 +0200 Subject: [PATCH] libs/vkd3d: Use KHR_push_descriptor for root descriptors. Thanks to KHR_push_descriptor, we do not have to allocate descriptor sets for subsequent root descriptor parameters updates. --- libs/vkd3d/command.c | 39 +++++++++++++--- libs/vkd3d/state.c | 92 +++++++++++++++++++++++++------------- libs/vkd3d/vkd3d_private.h | 3 ++ 3 files changed, 97 insertions(+), 37 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 8f1e7a82..827249a6 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1622,14 +1622,17 @@ static void d3d12_command_list_update_descriptors(struct d3d12_command_list *lis { struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; struct d3d12_root_signature *rs = bindings->root_signature; + uint32_t set; - if (!rs || !rs->pool_size_count) + if (!rs || !rs->pool_size_count || !rs->vk_set_layout) return; bindings->in_use = true; + set = vk_info->KHR_push_descriptor ? 1 : 0; VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bind_point, - rs->vk_pipeline_layout, 0, 1, &bindings->descriptor_set, 0, NULL)); + rs->vk_pipeline_layout, set, 1, &bindings->descriptor_set, 0, NULL)); } static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list, @@ -2263,7 +2266,7 @@ static void d3d12_command_list_copy_descriptors(struct d3d12_command_list *list, struct d3d12_root_signature *root_signature, VkDescriptorSet dst_set, VkDescriptorSet src_set) { const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; - unsigned int count = root_signature->descriptor_count; + unsigned int count = root_signature->copy_descriptor_count; VkDevice vk_device = list->device->vk_device; VkCopyDescriptorSet *descriptor_copies; unsigned int i; @@ -2571,6 +2574,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; struct d3d12_root_signature *root_signature = bindings->root_signature; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; const struct d3d12_root_descriptor *root_descriptor; struct VkWriteDescriptorSet descriptor_write; struct VkDescriptorBufferInfo buffer_info; @@ -2584,7 +2588,8 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, buffer_info.offset = gpu_address - resource->gpu_address; buffer_info.range = VK_WHOLE_SIZE; - d3d12_command_list_prepare_descriptors(list, bind_point); + if (!vk_info->KHR_push_descriptor) + d3d12_command_list_prepare_descriptors(list, bind_point); descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_write.pNext = NULL; @@ -2596,7 +2601,16 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, descriptor_write.pImageInfo = NULL; descriptor_write.pBufferInfo = &buffer_info; descriptor_write.pTexelBufferView = NULL; - VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL)); + + if (vk_info->KHR_push_descriptor) + { + VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bind_point, + root_signature->vk_pipeline_layout, 0, 1, &descriptor_write)); + } + else + { + VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL)); + } } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( @@ -2627,6 +2641,7 @@ static void d3d12_command_list_set_root_uav(struct d3d12_command_list *list, struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; struct d3d12_root_signature *root_signature = bindings->root_signature; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; const struct d3d12_root_descriptor *root_descriptor; struct VkWriteDescriptorSet descriptor_write; VkDevice vk_device = list->device->vk_device; @@ -2649,7 +2664,8 @@ static void d3d12_command_list_set_root_uav(struct d3d12_command_list *list, return; } - d3d12_command_list_prepare_descriptors(list, bind_point); + if (!vk_info->KHR_push_descriptor) + d3d12_command_list_prepare_descriptors(list, bind_point); descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_write.pNext = NULL; @@ -2661,7 +2677,16 @@ static void d3d12_command_list_set_root_uav(struct d3d12_command_list *list, descriptor_write.pImageInfo = NULL; descriptor_write.pBufferInfo = NULL; descriptor_write.pTexelBufferView = &vk_buffer_view; - VK_CALL(vkUpdateDescriptorSets(vk_device, 1, &descriptor_write, 0, NULL)); + + if (vk_info->KHR_push_descriptor) + { + VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bind_point, + root_signature->vk_pipeline_layout, 0, 1, &descriptor_write)); + } + else + { + VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL)); + } } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 49aa4e71..be8530bc 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -71,6 +71,8 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa vkd3d_free(root_signature->pool_sizes); if (root_signature->vk_set_layout) VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); + if (root_signature->vk_push_set_layout) + VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_push_set_layout, NULL)); if (root_signature->parameters) { @@ -582,23 +584,23 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat struct vkd3d_descriptor_set_context { - VkDescriptorSetLayoutBinding *binding_desc; VkDescriptorSetLayoutBinding *current_binding; - - uint32_t descriptor_index; + unsigned int descriptor_index; + uint32_t set_index; + uint32_t descriptor_binding; }; static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, enum vkd3d_descriptor_type descriptor_type, unsigned int register_idx, bool buffer_descriptor, struct vkd3d_descriptor_set_context *context) { - unsigned int i = context->descriptor_index; + unsigned int i = context->descriptor_index++; root_signature->descriptor_mapping[i].type = descriptor_type; root_signature->descriptor_mapping[i].register_index = register_idx; root_signature->descriptor_mapping[i].is_buffer = buffer_descriptor; - root_signature->descriptor_mapping[i].descriptor_set = 0; - root_signature->descriptor_mapping[i].binding = context->descriptor_index++; + root_signature->descriptor_mapping[i].descriptor_set = context->set_index; + root_signature->descriptor_mapping[i].binding = context->descriptor_binding++; } static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, @@ -614,7 +616,7 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat || descriptor_type == VKD3D_DESCRIPTOR_TYPE_UAV) && duplicate_descriptors; - first_binding = context->descriptor_index; + first_binding = context->descriptor_binding; for (i = 0; i < binding_count; ++i) { if (duplicate_descriptors) @@ -769,15 +771,19 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa /* Only a single push constant range may include the same stage in Vulkan. */ struct VkPushConstantRange push_constants[D3D12_SHADER_VISIBILITY_PIXEL + 1]; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + const struct vkd3d_vulkan_info *vk_info = &device->vk_info; struct VkPipelineLayoutCreateInfo pipeline_layout_info; - struct VkDescriptorSetLayoutCreateInfo set_desc; + struct VkDescriptorSetLayoutCreateInfo set_desc[2]; struct vkd3d_descriptor_set_context context; + VkDescriptorSetLayoutBinding *binding_desc; struct d3d12_root_signature_info info; + VkDescriptorSetLayout set_layouts[2]; uint32_t push_constant_count; VkResult vr; HRESULT hr; memset(&context, 0, sizeof(context)); + binding_desc = NULL; root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl; root_signature->refcount = 1; @@ -785,6 +791,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa root_signature->vk_pipeline_layout = VK_NULL_HANDLE; root_signature->pool_sizes = NULL; root_signature->vk_set_layout = VK_NULL_HANDLE; + root_signature->vk_push_set_layout = VK_NULL_HANDLE; root_signature->parameters = NULL; root_signature->descriptor_mapping = NULL; root_signature->static_sampler_count = 0; @@ -820,46 +827,71 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa sizeof(*root_signature->static_samplers)))) goto fail; - if (!(context.binding_desc = vkd3d_calloc(info.descriptor_count, sizeof(*context.binding_desc)))) + if (!(binding_desc = vkd3d_calloc(info.descriptor_count, sizeof(*binding_desc)))) goto fail; - context.current_binding = context.binding_desc; + context.current_binding = binding_desc; if (FAILED(hr = d3d12_root_signature_init_descriptor_pool_size(root_signature, &info))) goto fail; - if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc, &info, - push_constants, &push_constant_count))) - goto fail; - if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context))) goto fail; + /* We use KHR_push_descriptor for root descriptor parameters. */ + if (vk_info->KHR_push_descriptor) + { + set_desc[context.set_index].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + set_desc[context.set_index].pNext = NULL; + set_desc[context.set_index].flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR; + set_desc[context.set_index].bindingCount = context.descriptor_binding; + set_desc[context.set_index].pBindings = binding_desc; + if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc[context.set_index], + NULL, &root_signature->vk_push_set_layout))) < 0) + { + WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); + goto fail; + } + + set_layouts[context.set_index++] = root_signature->vk_push_set_layout; + context.current_binding = binding_desc; + context.descriptor_binding = 0; + } + + if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc, &info, + push_constants, &push_constant_count))) + goto fail; if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &context))) goto fail; - + root_signature->copy_descriptor_count = context.descriptor_binding; if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context))) goto fail; - set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - set_desc.pNext = NULL; - set_desc.flags = 0; - set_desc.bindingCount = info.descriptor_count; - set_desc.pBindings = context.binding_desc; - vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, &root_signature->vk_set_layout)); - vkd3d_free(context.binding_desc); - context.binding_desc = NULL; - if (vr < 0) + if (context.descriptor_binding) { - WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); - hr = hresult_from_vk_result(vr); - goto fail; + set_desc[context.set_index].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + set_desc[context.set_index].pNext = NULL; + set_desc[context.set_index].flags = 0; + set_desc[context.set_index].bindingCount = context.descriptor_binding; + set_desc[context.set_index].pBindings = binding_desc; + if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc[context.set_index], + NULL, &root_signature->vk_set_layout))) < 0) + { + WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); + hr = hresult_from_vk_result(vr); + goto fail; + } + + set_layouts[context.set_index++] = root_signature->vk_set_layout; } + vkd3d_free(binding_desc); + binding_desc = NULL; pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipeline_layout_info.pNext = NULL; pipeline_layout_info.flags = 0; - pipeline_layout_info.setLayoutCount = 1; - pipeline_layout_info.pSetLayouts = &root_signature->vk_set_layout; + pipeline_layout_info.setLayoutCount = context.set_index; + pipeline_layout_info.pSetLayouts = set_layouts; pipeline_layout_info.pushConstantRangeCount = push_constant_count; pipeline_layout_info.pPushConstantRanges = push_constants; if ((vr = VK_CALL(vkCreatePipelineLayout(device->vk_device, &pipeline_layout_info, NULL, @@ -876,7 +908,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa return S_OK; fail: - vkd3d_free(context.binding_desc); + vkd3d_free(binding_desc); d3d12_root_signature_cleanup(root_signature, device); return hr; } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 536697ae..9bfcc943 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -305,6 +305,9 @@ struct d3d12_root_signature VkPipelineLayout vk_pipeline_layout; VkDescriptorSetLayout vk_set_layout; + VkDescriptorSetLayout vk_push_set_layout; + + unsigned int copy_descriptor_count; struct VkDescriptorPoolSize *pool_sizes; size_t pool_size_count;