diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index a55a97f6..423fdc5b 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2805,15 +2805,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des break; } - if (range->descriptor_count == UINT_MAX) - { - vk_descriptor_write->dstSet = vk_descriptor_sets[set + 1]; - vk_descriptor_write->dstBinding = 0; - } - else - { - vk_descriptor_write->dstBinding += use_array ? 1 : range->descriptor_count; - } + vk_descriptor_write->dstSet = vk_descriptor_sets[range->image_set]; + vk_descriptor_write->dstBinding = use_array ? range->image_binding : range->image_binding + index; vk_image_info->sampler = VK_NULL_HANDLE; vk_image_info->imageView = u.view->v.u.vk_image_view; @@ -2934,10 +2927,11 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list } static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *vk_descriptor_write, - const struct d3d12_root_parameter *root_parameter, VkDescriptorSet vk_descriptor_set, + const struct d3d12_root_parameter *root_parameter, const VkDescriptorSet *vk_descriptor_sets, VkBufferView *vk_buffer_view, const VkDescriptorBufferInfo *vk_buffer_info) { const struct d3d12_root_descriptor *root_descriptor; + VkDescriptorSet vk_descriptor_set; switch (root_parameter->parameter_type) { @@ -2956,6 +2950,7 @@ static bool vk_write_descriptor_set_from_root_descriptor(VkWriteDescriptorSet *v } root_descriptor = &root_parameter->u.descriptor; + vk_descriptor_set = vk_descriptor_sets ? vk_descriptor_sets[root_descriptor->set] : VK_NULL_HANDLE; vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; vk_descriptor_write->pNext = NULL; @@ -3011,7 +3006,7 @@ static void d3d12_command_list_update_push_descriptors(struct d3d12_command_list } if (!vk_write_descriptor_set_from_root_descriptor(&descriptor_writes[descriptor_count], - root_parameter, bindings->descriptor_sets[0], vk_buffer_view, vk_buffer_info)) + root_parameter, bindings->descriptor_sets, vk_buffer_view, vk_buffer_info)) continue; ++descriptor_count; @@ -4612,8 +4607,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, if (vk_info->KHR_push_descriptor) { - vk_write_descriptor_set_from_root_descriptor(&descriptor_write, - root_parameter, VK_NULL_HANDLE, NULL, &buffer_info); + vk_write_descriptor_set_from_root_descriptor(&descriptor_write, root_parameter, NULL, NULL, &buffer_info); VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bindings->vk_bind_point, root_signature->vk_pipeline_layout, 0, 1, &descriptor_write)); } @@ -4621,7 +4615,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, { d3d12_command_list_prepare_descriptors(list, bind_point); vk_write_descriptor_set_from_root_descriptor(&descriptor_write, - root_parameter, bindings->descriptor_sets[0], NULL, &buffer_info); + root_parameter, bindings->descriptor_sets, NULL, &buffer_info); VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL)); VKD3D_ASSERT(index < ARRAY_SIZE(bindings->push_descriptors)); @@ -4685,8 +4679,7 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li if (vk_info->KHR_push_descriptor) { - vk_write_descriptor_set_from_root_descriptor(&descriptor_write, - root_parameter, VK_NULL_HANDLE, &vk_buffer_view, NULL); + vk_write_descriptor_set_from_root_descriptor(&descriptor_write, root_parameter, NULL, &vk_buffer_view, NULL); VK_CALL(vkCmdPushDescriptorSetKHR(list->vk_command_buffer, bindings->vk_bind_point, root_signature->vk_pipeline_layout, 0, 1, &descriptor_write)); } @@ -4694,7 +4687,7 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li { d3d12_command_list_prepare_descriptors(list, bind_point); vk_write_descriptor_set_from_root_descriptor(&descriptor_write, - root_parameter, bindings->descriptor_sets[0], &vk_buffer_view, NULL); + root_parameter, bindings->descriptor_sets, &vk_buffer_view, NULL); VK_CALL(vkUpdateDescriptorSets(list->device->vk_device, 1, &descriptor_write, 0, NULL)); VKD3D_ASSERT(index < ARRAY_SIZE(bindings->push_descriptors)); diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 2b0f81d3..4834a623 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -717,6 +717,7 @@ struct vk_binding_array VkDescriptorSetLayoutBinding *bindings; size_t capacity, count; + unsigned int descriptor_set; unsigned int table_index; unsigned int unbounded_offset; VkDescriptorSetLayoutCreateFlags flags; @@ -754,14 +755,24 @@ static bool vk_binding_array_add_binding(struct vk_binding_array *array, return true; } +static void vk_binding_array_make_unbound(struct vk_binding_array *array, + unsigned int offset, unsigned int table_index) +{ + array->unbounded_offset = offset; + array->table_index = table_index; +} + struct vkd3d_descriptor_set_context { struct vk_binding_array vk_bindings[VKD3D_MAX_DESCRIPTOR_SETS]; + struct vk_binding_array *current_binding_array[VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT]; unsigned int table_index; - unsigned int unbounded_offset; unsigned int descriptor_index; unsigned int uav_counter_index; unsigned int push_constant_index; + + struct vk_binding_array *push_descriptor_set; + bool push_descriptor; }; static void descriptor_set_context_cleanup(struct vkd3d_descriptor_set_context *context) @@ -786,46 +797,65 @@ static bool vkd3d_validate_descriptor_set_count(struct d3d12_device *device, uns return true; } -static struct vk_binding_array *d3d12_root_signature_current_vk_binding_array( - struct d3d12_root_signature *root_signature, struct vkd3d_descriptor_set_context *context) +static struct vk_binding_array *d3d12_root_signature_append_vk_binding_array( + struct d3d12_root_signature *root_signature, VkDescriptorSetLayoutCreateFlags flags, + struct vkd3d_descriptor_set_context *context) { + struct vk_binding_array *array; + unsigned int set; + if (root_signature->vk_set_count >= ARRAY_SIZE(context->vk_bindings)) return NULL; - return &context->vk_bindings[root_signature->vk_set_count]; -} - -static void d3d12_root_signature_append_vk_binding_array(struct d3d12_root_signature *root_signature, - VkDescriptorSetLayoutCreateFlags flags, struct vkd3d_descriptor_set_context *context) -{ - struct vk_binding_array *array; - - if (!(array = d3d12_root_signature_current_vk_binding_array(root_signature, context)) || !array->count) - return; - - array->table_index = context->table_index; - array->unbounded_offset = context->unbounded_offset; + set = root_signature->vk_set_count++; + array = &context->vk_bindings[set]; + array->descriptor_set = set; + array->unbounded_offset = UINT_MAX; array->flags = flags; - ++root_signature->vk_set_count; + return array; +} + +static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type( + struct d3d12_root_signature *root_signature, enum vkd3d_shader_descriptor_type descriptor_type, + struct vkd3d_descriptor_set_context *context) +{ + struct vk_binding_array *array, **current; + + if (context->push_descriptor) + { + if (!context->push_descriptor_set) + context->push_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); + + return context->push_descriptor_set; + } + + current = context->current_binding_array; + if (!(array = current[descriptor_type])) + { + array = d3d12_root_signature_append_vk_binding_array(root_signature, 0, context); + current[descriptor_type] = array; + } + + return array; } static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signature *root_signature, - enum vkd3d_shader_descriptor_type descriptor_type, unsigned int register_space, - unsigned int register_idx, bool buffer_descriptor, enum vkd3d_shader_visibility shader_visibility, - unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context, - const VkSampler *immutable_sampler, unsigned int *binding_idx) + struct vk_binding_array *array, enum vkd3d_shader_descriptor_type descriptor_type, + unsigned int register_space, unsigned int register_idx, bool buffer_descriptor, + enum vkd3d_shader_visibility shader_visibility, unsigned int descriptor_count, + struct vkd3d_descriptor_set_context *context, const VkSampler *immutable_sampler) { struct vkd3d_shader_descriptor_offset *offset = root_signature->descriptor_offsets ? &root_signature->descriptor_offsets[context->descriptor_index] : NULL; struct vkd3d_shader_resource_binding *mapping; - struct vk_binding_array *array; + VkDescriptorType vk_descriptor_type; unsigned int idx; - if (!(array = d3d12_root_signature_current_vk_binding_array(root_signature, context)) - || !(vk_binding_array_add_binding(&context->vk_bindings[root_signature->vk_set_count], - vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, buffer_descriptor), descriptor_count, - stage_flags_from_vkd3d_shader_visibility(shader_visibility), immutable_sampler, &idx))) + vk_descriptor_type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, buffer_descriptor); + if (!vk_binding_array_add_binding(array, vk_descriptor_type, descriptor_count, + stage_flags_from_vkd3d_shader_visibility(shader_visibility), immutable_sampler, &idx)) return E_OUTOFMEMORY; mapping = &root_signature->descriptor_mapping[context->descriptor_index++]; @@ -834,7 +864,7 @@ static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signatur mapping->register_index = register_idx; mapping->shader_visibility = shader_visibility; mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; - mapping->binding.set = root_signature->vk_set_count; + mapping->binding.set = array->descriptor_set; mapping->binding.binding = idx; mapping->binding.count = descriptor_count; if (offset) @@ -843,12 +873,6 @@ static HRESULT d3d12_root_signature_append_vk_binding(struct d3d12_root_signatur offset->dynamic_offset_index = ~0u; } - if (context->unbounded_offset != UINT_MAX) - d3d12_root_signature_append_vk_binding_array(root_signature, 0, context); - - if (binding_idx) - *binding_idx = idx; - return S_OK; } @@ -911,7 +935,7 @@ static unsigned int vk_binding_count_from_descriptor_range(const struct d3d12_ro } static HRESULT d3d12_root_signature_init_descriptor_table_binding(struct d3d12_root_signature *root_signature, - const struct d3d12_root_descriptor_table_range *range, D3D12_SHADER_VISIBILITY visibility, + struct d3d12_root_descriptor_table_range *range, D3D12_SHADER_VISIBILITY visibility, unsigned int vk_binding_array_count, unsigned int bindings_per_range, struct vkd3d_descriptor_set_context *context) { @@ -919,34 +943,49 @@ static HRESULT d3d12_root_signature_init_descriptor_table_binding(struct d3d12_r bool is_buffer = range->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER; enum vkd3d_shader_descriptor_type descriptor_type = range->type; unsigned int i, register_space = range->register_space; + struct vk_binding_array *array; HRESULT hr; - if (range->descriptor_count == UINT_MAX) - context->unbounded_offset = range->offset; + if (!(array = d3d12_root_signature_vk_binding_array_for_type(root_signature, descriptor_type, context))) + return E_OUTOFMEMORY; + range->set = array->descriptor_set - root_signature->main_set; + range->binding = array->count; for (i = 0; i < bindings_per_range; ++i) { - if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, + if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, array, descriptor_type, register_space, range->base_register_idx + i, is_buffer, shader_visibility, - vk_binding_array_count, context, NULL, NULL))) + vk_binding_array_count, context, NULL))) return hr; } + if (range->descriptor_count == UINT_MAX) + { + vk_binding_array_make_unbound(array, range->offset, context->table_index); + context->current_binding_array[descriptor_type] = NULL; + } + if (descriptor_type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV && descriptor_type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) - { - context->unbounded_offset = UINT_MAX; return S_OK; - } + if (!(array = d3d12_root_signature_vk_binding_array_for_type(root_signature, descriptor_type, context))) + return E_OUTOFMEMORY; + + range->image_set = array->descriptor_set - root_signature->main_set; + range->image_binding = array->count; for (i = 0; i < bindings_per_range; ++i) { - if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, + if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, array, descriptor_type, register_space, range->base_register_idx + i, false, shader_visibility, - vk_binding_array_count, context, NULL, NULL))) + vk_binding_array_count, context, NULL))) return hr; } - context->unbounded_offset = UINT_MAX; + if (range->descriptor_count == UINT_MAX) + { + vk_binding_array_make_unbound(array, range->offset, context->table_index); + context->current_binding_array[descriptor_type] = NULL; + } return S_OK; } @@ -1199,16 +1238,16 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo if (use_vk_heaps) { - /* set, binding and vk_binding_count are not used. */ + /* set, binding, image_set, image_binding, and vk_binding_count are not used. */ range->set = 0; range->binding = 0; + range->image_set = 0; + range->image_binding = 0; range->vk_binding_count = 0; d3d12_root_signature_map_descriptor_heap_binding(root_signature, range, shader_visibility, context); continue; } - range->set = root_signature->vk_set_count - root_signature->main_set; - if (root_signature->use_descriptor_arrays) { if (j && range->type != table->ranges[j - 1].type) @@ -1229,6 +1268,8 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo range->set = base_range->set; range->binding = base_range->binding; + range->image_set = base_range->image_set; + range->image_binding = base_range->image_binding; range->vk_binding_count = base_range->vk_binding_count - rel_offset; d3d12_root_signature_map_descriptor_unbounded_binding(root_signature, range, rel_offset, shader_visibility, context); @@ -1251,8 +1292,6 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo bindings_per_range = range->descriptor_count; } - range->binding = context->vk_bindings[root_signature->vk_set_count].count; - if (FAILED(hr = d3d12_root_signature_init_descriptor_table_binding(root_signature, range, p->ShaderVisibility, vk_binding_array_count, bindings_per_range, context))) return hr; @@ -1266,7 +1305,9 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_signature *root_signature, const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) { - unsigned int binding, i; + enum vkd3d_shader_descriptor_type descriptor_type; + struct vk_binding_array *array; + unsigned int i; HRESULT hr; root_signature->push_descriptor_mask = 0; @@ -1281,14 +1322,19 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign root_signature->push_descriptor_mask |= 1u << i; - if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, - vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType), - p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, true, - vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), 1, context, NULL, &binding))) - return hr; + descriptor_type = vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType); + if (!(array = d3d12_root_signature_vk_binding_array_for_type(root_signature, descriptor_type, context))) + return E_OUTOFMEMORY; root_signature->parameters[i].parameter_type = p->ParameterType; - root_signature->parameters[i].u.descriptor.binding = binding; + root_signature->parameters[i].u.descriptor.set = array->descriptor_set; + root_signature->parameters[i].u.descriptor.binding = array->count; + + if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, array, descriptor_type, + p->u.Descriptor.RegisterSpace, p->u.Descriptor.ShaderRegister, true, + vkd3d_shader_visibility_from_d3d12(p->ShaderVisibility), 1, context, NULL))) + return hr; + } return S_OK; @@ -1298,10 +1344,19 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa struct d3d12_device *device, const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) { + struct vk_binding_array *array; unsigned int i; HRESULT hr; VKD3D_ASSERT(root_signature->static_sampler_count == desc->NumStaticSamplers); + + if (!desc->NumStaticSamplers) + return S_OK; + + if (!(array = d3d12_root_signature_vk_binding_array_for_type(root_signature, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, context))) + return E_OUTOFMEMORY; + for (i = 0; i < desc->NumStaticSamplers; ++i) { const D3D12_STATIC_SAMPLER_DESC *s = &desc->pStaticSamplers[i]; @@ -1309,16 +1364,13 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa if (FAILED(hr = vkd3d_create_static_sampler(device, s, &root_signature->static_samplers[i]))) return hr; - if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, + if (FAILED(hr = d3d12_root_signature_append_vk_binding(root_signature, array, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, s->RegisterSpace, s->ShaderRegister, false, vkd3d_shader_visibility_from_d3d12(s->ShaderVisibility), 1, context, - &root_signature->static_samplers[i], NULL))) + &root_signature->static_samplers[i]))) return hr; } - if (device->use_vk_heaps) - d3d12_root_signature_append_vk_binding_array(root_signature, 0, context); - return S_OK; } @@ -1456,8 +1508,6 @@ static HRESULT d3d12_root_signature_create_descriptor_set_layouts(struct d3d12_r unsigned int i; HRESULT hr; - d3d12_root_signature_append_vk_binding_array(root_signature, 0, context); - if (!vkd3d_validate_descriptor_set_count(root_signature->device, root_signature->vk_set_count)) return E_INVALIDARG; @@ -1518,7 +1568,6 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa HRESULT hr; memset(&context, 0, sizeof(context)); - context.unbounded_offset = UINT_MAX; root_signature->ID3D12RootSignature_iface.lpVtbl = &d3d12_root_signature_vtbl; root_signature->refcount = 1; @@ -1580,17 +1629,11 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa sizeof(*root_signature->static_samplers)))) goto fail; + context.push_descriptor = vk_info->KHR_push_descriptor; 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) - { - d3d12_root_signature_append_vk_binding_array(root_signature, - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, &context); - } - - root_signature->main_set = root_signature->vk_set_count; + root_signature->main_set = !!context.push_descriptor_set; + context.push_descriptor = false; if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc, root_signature->push_constant_ranges, &root_signature->push_constant_range_count))) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index eb57c3d4..ea22b37d 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -65,6 +65,8 @@ * this number to prevent excessive pool memory use. */ #define VKD3D_MAX_VIRTUAL_HEAP_DESCRIPTORS_PER_TYPE (16 * 1024u) +#define VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT (VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + 1) + extern uint64_t object_global_serial_id; struct d3d12_command_list; @@ -899,6 +901,8 @@ struct d3d12_root_descriptor_table_range unsigned int vk_binding_count; uint32_t set; uint32_t binding; + uint32_t image_set; + uint32_t image_binding; enum vkd3d_shader_descriptor_type type; uint32_t descriptor_magic; @@ -920,6 +924,7 @@ struct d3d12_root_constant struct d3d12_root_descriptor { + uint32_t set; uint32_t binding; };