diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 9d03dd92..0ac4a518 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2339,26 +2339,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable( } static void d3d12_command_list_set_root_constants(struct d3d12_command_list *list, - struct d3d12_root_signature *root_signature, unsigned int root_parameter_index, + struct d3d12_root_signature *root_signature, unsigned int index, unsigned int offset, unsigned int count, const void *data) { + const struct d3d12_root_constant *constant = &root_signature->parameters[index].u.constant; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; - struct d3d12_root_constant *constant = NULL; - unsigned int i; - - for (i = 0; i < root_signature->constant_count; ++i) - { - if (root_signature->constants[i].root_parameter_index == root_parameter_index) - { - constant = &root_signature->constants[i]; - break; - } - } - if (!constant) - { - WARN("Invalid root parameter index %u.\n", root_parameter_index); - return; - } 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)); @@ -2413,9 +2398,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(I } static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, - VkDescriptorSet descriptor_set, unsigned int root_parameter_index, - D3D12_GPU_VIRTUAL_ADDRESS gpu_address) + struct d3d12_root_signature *root_signature, VkDescriptorSet descriptor_set, + unsigned int index, D3D12_GPU_VIRTUAL_ADDRESS gpu_address) { + const struct d3d12_root_descriptor *root_descriptor = &root_signature->parameters[index].u.descriptor; const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; struct VkWriteDescriptorSet descriptor_write; struct VkDescriptorBufferInfo buffer_info; @@ -2429,7 +2415,7 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_write.pNext = NULL; descriptor_write.dstSet = descriptor_set; - descriptor_write.dstBinding = root_parameter_index; + descriptor_write.dstBinding = root_descriptor->binding; descriptor_write.dstArrayElement = 0; descriptor_write.descriptorCount = 1; descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -2447,7 +2433,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); - d3d12_command_list_set_root_cbv(list, list->compute_descriptor_set, root_parameter_index, address); + d3d12_command_list_set_root_cbv(list, list->compute_root_signature, + list->compute_descriptor_set, root_parameter_index, address); } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( @@ -2458,7 +2445,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferVi TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); - d3d12_command_list_set_root_cbv(list, list->graphics_descriptor_set, root_parameter_index, address); + d3d12_command_list_set_root_cbv(list, list->graphics_root_signature, + list->graphics_descriptor_set, root_parameter_index, address); } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 97a2e7e2..72eb2093 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -72,10 +72,11 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa if (root_signature->vk_set_layout) VK_CALL(vkDestroyDescriptorSetLayout(device->vk_device, root_signature->vk_set_layout, NULL)); + if (root_signature->parameters) + vkd3d_free(root_signature->parameters); + if (root_signature->descriptor_mapping) vkd3d_free(root_signature->descriptor_mapping); - if (root_signature->constants) - vkd3d_free(root_signature->constants); if (root_signature->push_constants) vkd3d_free(root_signature->push_constants); @@ -451,6 +452,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat for (i = 0, j = 0; i < desc->NumParameters; ++i) { + struct d3d12_root_constant *root_constant = &root_signature->parameters[i].u.constant; const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; unsigned int idx; @@ -468,10 +470,9 @@ 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->constants[j].root_parameter_index = i; - root_signature->constants[j].stage_flags = push_count == 1 + root_constant->stage_flags = push_count == 1 ? push_constants[0].stageFlags : stage_flags_from_visibility(p->ShaderVisibility); - root_signature->constants[j].offset = offset; + root_constant->offset = offset; root_signature->push_constants[j].register_index = p->u.Constants.ShaderRegister; root_signature->push_constants[j].shader_visibility @@ -523,8 +524,8 @@ 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->parameters = NULL; root_signature->descriptor_mapping = NULL; - root_signature->constants = NULL; root_signature->static_sampler_count = 0; root_signature->static_samplers = NULL; @@ -534,6 +535,13 @@ 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, + sizeof(*root_signature->parameters)))) + { + hr = E_OUTOFMEMORY; + goto fail; + } + if (!(binding_desc = vkd3d_calloc(info.descriptor_count, sizeof(*binding_desc)))) { hr = E_OUTOFMEMORY; @@ -547,12 +555,6 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa goto fail; } root_signature->constant_count = info.root_constant_count; - if (!(root_signature->constants = vkd3d_calloc(root_signature->constant_count, - sizeof(*root_signature->constants)))) - { - hr = E_OUTOFMEMORY; - goto fail; - } if (!(root_signature->push_constants = vkd3d_calloc(root_signature->constant_count, sizeof(*root_signature->push_constants)))) { @@ -617,6 +619,8 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa cur_binding->stageFlags = stage_flags_from_visibility(p->ShaderVisibility); cur_binding->pImmutableSamplers = NULL; + root_signature->parameters[i].u.descriptor.binding = cur_binding->binding; + ++cur_binding; break; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 3df2390f..de312d77 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -264,11 +264,24 @@ HRESULT d3d12_query_heap_create(struct d3d12_device *device, struct d3d12_root_constant { - unsigned int root_parameter_index; VkShaderStageFlags stage_flags; uint32_t offset; }; +struct d3d12_root_descriptor +{ + uint32_t binding; +}; + +struct d3d12_root_parameter +{ + union + { + struct d3d12_root_constant constant; + struct d3d12_root_descriptor descriptor; + } u; +}; + /* ID3D12RootSignature */ struct d3d12_root_signature { @@ -281,11 +294,12 @@ struct d3d12_root_signature struct VkDescriptorPoolSize *pool_sizes; size_t pool_size_count; + struct d3d12_root_parameter *parameters; + unsigned int descriptor_count; struct vkd3d_shader_resource_binding *descriptor_mapping; unsigned int constant_count; - struct d3d12_root_constant *constants; struct vkd3d_shader_push_constant *push_constants; unsigned int static_sampler_count; diff --git a/tests/d3d12.c b/tests/d3d12.c index 712dbe8e..1626ada3 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -7009,11 +7009,12 @@ static void test_cs_constant_buffer(void) ID3D12PipelineState *pipeline_state; D3D12_RESOURCE_DESC resource_desc; ID3D12Resource *resource, *cb; + unsigned int descriptor_size; struct resource_readback rb; struct test_context context; ID3D12CommandQueue *queue; ID3D12Device *device; - unsigned int x; + unsigned int i, x; float value; HRESULT hr; void *ptr; @@ -7074,7 +7075,7 @@ static void test_cs_constant_buffer(void) ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr); descriptor_ranges[0].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; - descriptor_ranges[0].NumDescriptors = 1; + descriptor_ranges[0].NumDescriptors = 4; descriptor_ranges[0].BaseShaderRegister = 0; descriptor_ranges[0].RegisterSpace = 0; descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0; @@ -7098,13 +7099,16 @@ static void test_cs_constant_buffer(void) shader_bytecode(cs_code, sizeof(cs_code))); heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; - heap_desc.NumDescriptors = 1; + heap_desc.NumDescriptors = 4; heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; heap_desc.NodeMask = 0; hr = ID3D12Device_CreateDescriptorHeap(device, &heap_desc, &IID_ID3D12DescriptorHeap, (void **)&descriptor_heap); ok(SUCCEEDED(hr), "Failed to create descriptor heap, hr %#x.\n", hr); + descriptor_size = ID3D12Device_GetDescriptorHandleIncrementSize(device, + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + cpu_descriptor_handle = ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(descriptor_heap); gpu_descriptor_handle = ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(descriptor_heap); @@ -7116,6 +7120,12 @@ static void test_cs_constant_buffer(void) uav_desc.Buffer.CounterOffsetInBytes = 0; uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; ID3D12Device_CreateUnorderedAccessView(device, resource, NULL, &uav_desc, cpu_descriptor_handle); + /* For tier 1 hardware all descriptors must be populated. */ + for (i = 1; i < heap_desc.NumDescriptors; ++i) + { + cpu_descriptor_handle.ptr += descriptor_size; + ID3D12Device_CreateUnorderedAccessView(device, NULL, NULL, &uav_desc, cpu_descriptor_handle); + } ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, root_signature); ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(command_list, 1,