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.
This commit is contained in:
Józef Kucia 2017-08-11 13:58:04 +02:00
parent 4a767a8f11
commit 32e69fa945
3 changed files with 97 additions and 37 deletions

View File

@ -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]; 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_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; 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; return;
bindings->in_use = true; bindings->in_use = true;
set = vk_info->KHR_push_descriptor ? 1 : 0;
VK_CALL(vkCmdBindDescriptorSets(list->vk_command_buffer, bind_point, 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, 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) struct d3d12_root_signature *root_signature, VkDescriptorSet dst_set, VkDescriptorSet src_set)
{ {
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; 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; VkDevice vk_device = list->device->vk_device;
VkCopyDescriptorSet *descriptor_copies; VkCopyDescriptorSet *descriptor_copies;
unsigned int i; 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 vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
struct d3d12_root_signature *root_signature = bindings->root_signature; struct d3d12_root_signature *root_signature = bindings->root_signature;
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; 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; const struct d3d12_root_descriptor *root_descriptor;
struct VkWriteDescriptorSet descriptor_write; struct VkWriteDescriptorSet descriptor_write;
struct VkDescriptorBufferInfo buffer_info; 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.offset = gpu_address - resource->gpu_address;
buffer_info.range = VK_WHOLE_SIZE; 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.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_write.pNext = NULL; 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.pImageInfo = NULL;
descriptor_write.pBufferInfo = &buffer_info; descriptor_write.pBufferInfo = &buffer_info;
descriptor_write.pTexelBufferView = NULL; 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( 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 vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
struct d3d12_root_signature *root_signature = bindings->root_signature; struct d3d12_root_signature *root_signature = bindings->root_signature;
const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; 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; const struct d3d12_root_descriptor *root_descriptor;
struct VkWriteDescriptorSet descriptor_write; struct VkWriteDescriptorSet descriptor_write;
VkDevice vk_device = list->device->vk_device; 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; 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.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_write.pNext = NULL; 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.pImageInfo = NULL;
descriptor_write.pBufferInfo = NULL; descriptor_write.pBufferInfo = NULL;
descriptor_write.pTexelBufferView = &vk_buffer_view; 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( static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView(

View File

@ -71,6 +71,8 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa
vkd3d_free(root_signature->pool_sizes); vkd3d_free(root_signature->pool_sizes);
if (root_signature->vk_set_layout) if (root_signature->vk_set_layout)
VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); 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) 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 struct vkd3d_descriptor_set_context
{ {
VkDescriptorSetLayoutBinding *binding_desc;
VkDescriptorSetLayoutBinding *current_binding; VkDescriptorSetLayoutBinding *current_binding;
unsigned int descriptor_index;
uint32_t descriptor_index; uint32_t set_index;
uint32_t descriptor_binding;
}; };
static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature,
enum vkd3d_descriptor_type descriptor_type, unsigned int register_idx, enum vkd3d_descriptor_type descriptor_type, unsigned int register_idx,
bool buffer_descriptor, struct vkd3d_descriptor_set_context *context) 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].type = descriptor_type;
root_signature->descriptor_mapping[i].register_index = register_idx; root_signature->descriptor_mapping[i].register_index = register_idx;
root_signature->descriptor_mapping[i].is_buffer = buffer_descriptor; root_signature->descriptor_mapping[i].is_buffer = buffer_descriptor;
root_signature->descriptor_mapping[i].descriptor_set = 0; root_signature->descriptor_mapping[i].descriptor_set = context->set_index;
root_signature->descriptor_mapping[i].binding = context->descriptor_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, 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) || descriptor_type == VKD3D_DESCRIPTOR_TYPE_UAV)
&& duplicate_descriptors; && duplicate_descriptors;
first_binding = context->descriptor_index; first_binding = context->descriptor_binding;
for (i = 0; i < binding_count; ++i) for (i = 0; i < binding_count; ++i)
{ {
if (duplicate_descriptors) 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. */ /* Only a single push constant range may include the same stage in Vulkan. */
struct VkPushConstantRange push_constants[D3D12_SHADER_VISIBILITY_PIXEL + 1]; struct VkPushConstantRange push_constants[D3D12_SHADER_VISIBILITY_PIXEL + 1];
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; 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 VkPipelineLayoutCreateInfo pipeline_layout_info;
struct VkDescriptorSetLayoutCreateInfo set_desc; struct VkDescriptorSetLayoutCreateInfo set_desc[2];
struct vkd3d_descriptor_set_context context; struct vkd3d_descriptor_set_context context;
VkDescriptorSetLayoutBinding *binding_desc;
struct d3d12_root_signature_info info; struct d3d12_root_signature_info info;
VkDescriptorSetLayout set_layouts[2];
uint32_t push_constant_count; uint32_t push_constant_count;
VkResult vr; VkResult vr;
HRESULT hr; HRESULT hr;
memset(&context, 0, sizeof(context)); memset(&context, 0, sizeof(context));
binding_desc = NULL;
root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl; root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl;
root_signature->refcount = 1; 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->vk_pipeline_layout = VK_NULL_HANDLE;
root_signature->pool_sizes = NULL; root_signature->pool_sizes = NULL;
root_signature->vk_set_layout = VK_NULL_HANDLE; root_signature->vk_set_layout = VK_NULL_HANDLE;
root_signature->vk_push_set_layout = VK_NULL_HANDLE;
root_signature->parameters = NULL; root_signature->parameters = NULL;
root_signature->descriptor_mapping = NULL; root_signature->descriptor_mapping = NULL;
root_signature->static_sampler_count = 0; 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)))) sizeof(*root_signature->static_samplers))))
goto fail; 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; 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))) if (FAILED(hr = d3d12_root_signature_init_descriptor_pool_size(root_signature, &info)))
goto fail; 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))) if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context)))
goto fail; 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))) if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &context)))
goto fail; goto fail;
root_signature->copy_descriptor_count = context.descriptor_binding;
if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context))) if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context)))
goto fail; goto fail;
set_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; if (context.descriptor_binding)
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)
{ {
WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); set_desc[context.set_index].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
hr = hresult_from_vk_result(vr); set_desc[context.set_index].pNext = NULL;
goto fail; 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.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipeline_layout_info.pNext = NULL; pipeline_layout_info.pNext = NULL;
pipeline_layout_info.flags = 0; pipeline_layout_info.flags = 0;
pipeline_layout_info.setLayoutCount = 1; pipeline_layout_info.setLayoutCount = context.set_index;
pipeline_layout_info.pSetLayouts = &root_signature->vk_set_layout; pipeline_layout_info.pSetLayouts = set_layouts;
pipeline_layout_info.pushConstantRangeCount = push_constant_count; pipeline_layout_info.pushConstantRangeCount = push_constant_count;
pipeline_layout_info.pPushConstantRanges = push_constants; pipeline_layout_info.pPushConstantRanges = push_constants;
if ((vr = VK_CALL(vkCreatePipelineLayout(device->vk_device, &pipeline_layout_info, NULL, 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; return S_OK;
fail: fail:
vkd3d_free(context.binding_desc); vkd3d_free(binding_desc);
d3d12_root_signature_cleanup(root_signature, device); d3d12_root_signature_cleanup(root_signature, device);
return hr; return hr;
} }

View File

@ -305,6 +305,9 @@ struct d3d12_root_signature
VkPipelineLayout vk_pipeline_layout; VkPipelineLayout vk_pipeline_layout;
VkDescriptorSetLayout vk_set_layout; VkDescriptorSetLayout vk_set_layout;
VkDescriptorSetLayout vk_push_set_layout;
unsigned int copy_descriptor_count;
struct VkDescriptorPoolSize *pool_sizes; struct VkDescriptorPoolSize *pool_sizes;
size_t pool_size_count; size_t pool_size_count;