diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 396a8242..c198eb11 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2268,7 +2268,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12 } static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *list, - VkDescriptorSet descriptor_set, unsigned int index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) + struct d3d12_root_signature *root_signature, VkDescriptorSet descriptor_set, + unsigned int index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor) { struct d3d12_device *device = list->device; const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -2276,6 +2277,8 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l struct d3d12_cbv_srv_uav_desc *descriptor; struct VkDescriptorImageInfo image_info; + assert(root_signature->parameters[index].parameter_type == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE); + /* FIXME: Only a single descriptor is supported currently. */ descriptor = (struct d3d12_cbv_srv_uav_desc *)(intptr_t)base_descriptor.ptr; @@ -2335,8 +2338,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I FIXME("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64" partial-stub!\n", iface, root_parameter_index, base_descriptor.ptr); - d3d12_command_list_set_descriptor_table(list, list->compute_descriptor_set, - root_parameter_index, base_descriptor); + d3d12_command_list_set_descriptor_table(list, list->compute_root_signature, + list->compute_descriptor_set, root_parameter_index, base_descriptor); } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList *iface, @@ -2347,8 +2350,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable( FIXME("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64" partial-stub!\n", iface, root_parameter_index, base_descriptor.ptr); - d3d12_command_list_set_descriptor_table(list, list->graphics_descriptor_set, - root_parameter_index, base_descriptor); + d3d12_command_list_set_descriptor_table(list, list->graphics_root_signature, + list->graphics_descriptor_set, root_parameter_index, base_descriptor); } static void d3d12_command_list_set_root_constants(struct d3d12_command_list *list, @@ -2358,6 +2361,8 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis const struct d3d12_root_constant *constant = &root_signature->parameters[index].u.constant; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + assert(root_signature->parameters[index].parameter_type == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS); + VK_CALL(vkCmdPushConstants(list->vk_command_buffer, root_signature->vk_pipeline_layout, constant->stage_flags, constant->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); } @@ -2420,6 +2425,8 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, struct VkDescriptorBufferInfo buffer_info; struct d3d12_resource *resource; + assert(root_signature->parameters[index].parameter_type == D3D12_ROOT_PARAMETER_TYPE_CBV); + resource = vkd3d_gpu_va_allocator_dereference(&list->device->gpu_va_allocator, gpu_address); buffer_info.buffer = resource->u.vk_buffer; buffer_info.offset = gpu_address - resource->gpu_address; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 72eb2093..66406f11 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -73,7 +73,14 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); if (root_signature->parameters) + { + for (i = 0; i < root_signature->parameter_count; ++i) + { + if (root_signature->parameters[i].parameter_type == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + vkd3d_free(root_signature->parameters[i].u.descriptor_table.ranges); + } vkd3d_free(root_signature->parameters); + } if (root_signature->descriptor_mapping) vkd3d_free(root_signature->descriptor_mapping); @@ -435,6 +442,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat } else { + /* Move used push constants ranges to front. */ offset = 0; for (i = 0, j = 0; i <= D3D12_SHADER_VISIBILITY_PIXEL; ++i) { @@ -470,6 +478,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat offset = push_constants_offset[idx]; push_constants_offset[idx] += p->u.Constants.Num32BitValues * sizeof(uint32_t); + root_signature->parameters[i].parameter_type = p->ParameterType; root_constant->stage_flags = push_count == 1 ? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility); root_constant->offset = offset; @@ -488,18 +497,27 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat return S_OK; } -static uint32_t d3d12_root_signature_assign_vk_binding(struct d3d12_root_signature *root_signature, - enum vkd3d_descriptor_type descriptor_type, unsigned int register_idx, uint32_t *descriptor_idx) +static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, + enum vkd3d_descriptor_type descriptor_type, unsigned int base_register_idx, + unsigned int binding_count, uint32_t *descriptor_idx) { - uint32_t binding = *descriptor_idx; + uint32_t first_binding, binding; + unsigned int i; - root_signature->descriptor_mapping[binding].type = descriptor_type; - root_signature->descriptor_mapping[binding].register_index = register_idx; - root_signature->descriptor_mapping[binding].descriptor_set = 0; - root_signature->descriptor_mapping[binding].binding = binding; + first_binding = *descriptor_idx; + for (i = 0; i < binding_count; ++i) + { + binding = *descriptor_idx; - *descriptor_idx += 1; - return binding; + root_signature->descriptor_mapping[binding].type = descriptor_type; + root_signature->descriptor_mapping[binding].register_index = base_register_idx + i; + root_signature->descriptor_mapping[binding].descriptor_set = 0; + root_signature->descriptor_mapping[binding].binding = binding; + + *descriptor_idx += 1; + } + + return first_binding; } static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signature, @@ -535,7 +553,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa if (FAILED(hr = d3d12_root_signature_info_from_desc(&info, desc))) return hr; - if (!(root_signature->parameters = vkd3d_calloc(desc->NumParameters, + root_signature->parameter_count = desc->NumParameters; + if (!(root_signature->parameters = vkd3d_calloc(root_signature->parameter_count, sizeof(*root_signature->parameters)))) { hr = E_OUTOFMEMORY; @@ -577,17 +596,32 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa switch (p->ParameterType) { case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - for (j = 0; j < p->u.DescriptorTable.NumDescriptorRanges; ++j) + { + struct d3d12_root_descriptor_table *table = &root_signature->parameters[i].u.descriptor_table; + unsigned int range_count = p->u.DescriptorTable.NumDescriptorRanges; + + root_signature->parameters[i].parameter_type = p->ParameterType; + table->range_count = range_count; + if (!(table->ranges = vkd3d_calloc(table->range_count, sizeof(*table->ranges)))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + + for (j = 0; j < range_count; ++j) { const D3D12_DESCRIPTOR_RANGE *descriptor_range = &p->u.DescriptorTable.pDescriptorRanges[j]; + uint32_t vk_binding; - for (k = 0; k < p->u.DescriptorTable.pDescriptorRanges[j].NumDescriptors; ++k) + vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature, + vkd3d_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType), + descriptor_range->BaseShaderRegister, descriptor_range->NumDescriptors, + &descriptor_idx); + + /* Unroll descriptor range. */ + for (k = 0; k < descriptor_range->NumDescriptors; ++k) { - uint32_t vk_binding = d3d12_root_signature_assign_vk_binding(root_signature, - vkd3d_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType), - descriptor_range->BaseShaderRegister + k, &descriptor_idx); - - if (!vk_binding_from_d3d12_descriptor_range(cur_binding, descriptor_range, vk_binding)) + if (!vk_binding_from_d3d12_descriptor_range(cur_binding, descriptor_range, vk_binding + k)) { hr = E_NOTIMPL; goto fail; @@ -598,8 +632,12 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa ++cur_binding; } + + table->ranges[j].binding = vk_binding; + table->ranges[j].descriptor_count = descriptor_range->NumDescriptors; } break; + } case D3D12_ROOT_PARAMETER_TYPE_CBV: case D3D12_ROOT_PARAMETER_TYPE_SRV: @@ -611,14 +649,15 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa hr = E_NOTIMPL; goto fail; } - cur_binding->binding = d3d12_root_signature_assign_vk_binding(root_signature, + cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, vkd3d_descriptor_type_from_d3d12_root_parameter_type(p->ParameterType), - p->u.Descriptor.ShaderRegister, &descriptor_idx); + p->u.Descriptor.ShaderRegister, 1, &descriptor_idx); cur_binding->descriptorType = vk_descriptor_type_from_d3d12_root_parameter(p->ParameterType); cur_binding->descriptorCount = 1; cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility); cur_binding->pImmutableSamplers = NULL; + root_signature->parameters[i].parameter_type = p->ParameterType; root_signature->parameters[i].u.descriptor.binding = cur_binding->binding; ++cur_binding; @@ -649,8 +688,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa if (FAILED(hr = d3d12_device_create_static_sampler(device, s, &root_signature->static_samplers[i]))) goto fail; - cur_binding->binding = d3d12_root_signature_assign_vk_binding(root_signature, - VKD3D_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, &descriptor_idx); + cur_binding->binding = d3d12_root_signature_assign_vk_bindings(root_signature, + VKD3D_DESCRIPTOR_TYPE_SAMPLER, s->ShaderRegister, 1, &descriptor_idx); cur_binding->descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; cur_binding->descriptorCount = 1; cur_binding->stageFlags = stage_flags_from_visibility(s->ShaderVisibility); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index dd387ce2..f13002b8 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -265,6 +265,18 @@ struct d3d12_query_heap HRESULT d3d12_query_heap_create(struct d3d12_device *device, struct d3d12_query_heap **heap) DECLSPEC_HIDDEN; +struct d3d12_root_descriptor_table_range +{ + uint32_t binding; + unsigned int descriptor_count; +}; + +struct d3d12_root_descriptor_table +{ + unsigned int range_count; + struct d3d12_root_descriptor_table_range *ranges; +}; + struct d3d12_root_constant { VkShaderStageFlags stage_flags; @@ -278,10 +290,12 @@ struct d3d12_root_descriptor struct d3d12_root_parameter { + D3D12_ROOT_PARAMETER_TYPE parameter_type; union { struct d3d12_root_constant constant; struct d3d12_root_descriptor descriptor; + struct d3d12_root_descriptor_table descriptor_table; } u; }; @@ -298,6 +312,7 @@ struct d3d12_root_signature size_t pool_size_count; struct d3d12_root_parameter *parameters; + unsigned int parameter_count; unsigned int descriptor_count; struct vkd3d_shader_resource_binding *descriptor_mapping;