Simplifies the code path for handling array bindings and unbounded ranges.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/command.c | 6 +----- libs/vkd3d/state.c | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 7150c59b..8bed7303 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2674,7 +2674,6 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
descriptor_table = root_signature_get_descriptor_table(root_signature, index);
- descriptor = base_descriptor; descriptor_count = 0; current_descriptor_write = descriptor_writes; current_image_info = image_infos; @@ -2682,10 +2681,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list { range = &descriptor_table->ranges[i];
- if (range->offset != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) - { - descriptor = base_descriptor + range->offset; - } + descriptor = base_descriptor + range->offset;
for (j = 0; j < range->descriptor_count; ++j, ++descriptor) { diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index a381679e..d62cb9a0 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -591,6 +591,8 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo for (i = 0; i < desc->NumParameters; ++i) { const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; + unsigned int offset = 0; + if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) continue;
@@ -604,6 +606,25 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo if (!(table->ranges = vkd3d_calloc(table->range_count, sizeof(*table->ranges)))) return E_OUTOFMEMORY;
+ for (j = 0; j < range_count; ++j) + { + range = &p->u.DescriptorTable.pDescriptorRanges[j]; + + if (range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + offset = range->OffsetInDescriptorsFromTableStart; + + table->ranges[j].offset = offset; + table->ranges[j].descriptor_count = range->NumDescriptors; + table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType); + table->ranges[j].register_space = range->RegisterSpace; + table->ranges[j].base_register_idx = range->BaseShaderRegister; + + TRACE("Descriptor table %u, range %u, offset %u, type %#x, count %u.\n", i, j, + offset, range->RangeType, range->NumDescriptors); + + offset += range->NumDescriptors; + } + for (j = 0; j < range_count; ++j) { range = &p->u.DescriptorTable.pDescriptorRanges[j]; @@ -638,12 +659,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo ++cur_binding; }
- table->ranges[j].offset = range->OffsetInDescriptorsFromTableStart; - table->ranges[j].descriptor_count = range->NumDescriptors; table->ranges[j].binding = vk_binding; - table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType); - table->ranges[j].register_space = range->RegisterSpace; - table->ranges[j].base_register_idx = range->BaseShaderRegister; } }
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- tests/d3d12.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index b10f24be..a03cb965 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -2863,6 +2863,16 @@ static void test_root_signature_limits(void) hr = create_root_signature(device, &root_signature_desc, &root_signature); ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+ /* Windows results vary for overflowing to zero, but anything beyond that is invalid. */ + root_signature_desc.NumParameters = 1; + descriptor_ranges[0].NumDescriptors = 0x1001; + descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0xFFFFF000; + hr = create_root_signature(device, &root_signature_desc, &root_signature); + todo + ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + ID3D12RootSignature_Release(root_signature); + refcount = ID3D12Device_Release(device); ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount); }
On Fri, 30 Jul 2021 at 06:04, Conor McCarthy cmccarthy@codeweavers.com wrote:
- /* Windows results vary for overflowing to zero, but anything beyond that is invalid. */
- root_signature_desc.NumParameters = 1;
- descriptor_ranges[0].NumDescriptors = 0x1001;
- descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0xFFFFF000;
Lowercase hexadecimal constants, please.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/state.c | 3 +++ tests/d3d12.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index d62cb9a0..46804883 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -613,6 +613,9 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo if (range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) offset = range->OffsetInDescriptorsFromTableStart;
+ if (offset + range->NumDescriptors < offset) + return E_INVALIDARG; + table->ranges[j].offset = offset; table->ranges[j].descriptor_count = range->NumDescriptors; table->ranges[j].descriptor_magic = vkd3d_descriptor_magic_from_d3d12(range->RangeType); diff --git a/tests/d3d12.c b/tests/d3d12.c index a03cb965..95792926 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -2868,10 +2868,7 @@ static void test_root_signature_limits(void) descriptor_ranges[0].NumDescriptors = 0x1001; descriptor_ranges[0].OffsetInDescriptorsFromTableStart = 0xFFFFF000; hr = create_root_signature(device, &root_signature_desc, &root_signature); - todo ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr); - if (SUCCEEDED(hr)) - ID3D12RootSignature_Release(root_signature);
refcount = ID3D12Device_Release(device); ok(!refcount, "ID3D12Device has %u references left.\n", (unsigned int)refcount);
On Fri, 30 Jul 2021 at 06:04, Conor McCarthy cmccarthy@codeweavers.com wrote:
@@ -613,6 +613,9 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo if (range->OffsetInDescriptorsFromTableStart != D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) offset = range->OffsetInDescriptorsFromTableStart;
if (offset + range->NumDescriptors < offset)
return E_INVALIDARG;
Zebediah recently introduce the vkd3d_bound_range() helper for this kind of check; we should probably use it here as well.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/device.c | 4 ++++ libs/vkd3d/vkd3d_private.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index be0bf2fb..0fadb521 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1457,6 +1457,10 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->shader_extensions[0] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION; }
+ if (vulkan_info->EXT_descriptor_indexing) + vulkan_info->shader_extensions[vulkan_info->shader_extension_count++] + = VKD3D_SHADER_SPIRV_EXTENSION_EXT_DESCRIPTOR_INDEXING; + /* Disable unused Vulkan features. */ features->shaderTessellationAndGeometryPointSize = VK_FALSE;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 76a07c38..70e3248f 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -51,7 +51,7 @@
#define VKD3D_MAX_COMPATIBLE_FORMAT_COUNT 6u #define VKD3D_MAX_QUEUE_FAMILY_COUNT 3u -#define VKD3D_MAX_SHADER_EXTENSIONS 1u +#define VKD3D_MAX_SHADER_EXTENSIONS 2u #define VKD3D_MAX_SHADER_STAGES 5u #define VKD3D_MAX_VK_SYNC_OBJECTS 4u #define VKD3D_MAX_DESCRIPTOR_SETS 2u
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Required for enabling extensions, e.g. descriptor indexing.
Signed-of-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/state.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 46804883..47b1a797 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1550,6 +1550,7 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st struct vkd3d_shader_scan_descriptor_info shader_info; struct vkd3d_shader_interface_info shader_interface; const struct d3d12_root_signature *root_signature; + struct vkd3d_shader_spirv_target_info target_info; VkPipelineLayout vk_pipeline_layout; HRESULT hr; int ret; @@ -1581,8 +1582,14 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st } vkd3d_shader_free_scan_descriptor_info(&shader_info);
+ memset(&target_info, 0, sizeof(target_info)); + target_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO; + target_info.environment = VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0; + target_info.extensions = device->vk_info.shader_extensions; + target_info.extension_count = device->vk_info.shader_extension_count; + shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; - shader_interface.next = NULL; + shader_interface.next = &target_info; shader_interface.bindings = root_signature->descriptor_mapping; shader_interface.binding_count = root_signature->binding_count; shader_interface.push_constant_buffers = root_signature->root_constants;
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Simplifies the calling of a helper function to create descriptor arrays.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/state.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 47b1a797..558a426c 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -580,7 +580,6 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature, const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) { - VkDescriptorSetLayoutBinding *cur_binding = context->current_binding; struct d3d12_root_descriptor_table *table; const D3D12_DESCRIPTOR_RANGE *range; unsigned int i, j, k, range_count; @@ -630,8 +629,12 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
for (j = 0; j < range_count; ++j) { + VkDescriptorSetLayoutBinding *cur_binding; + range = &p->u.DescriptorTable.pDescriptorRanges[j];
+ cur_binding = context->current_binding; + vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature, vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType), range->RegisterSpace, range->BaseShaderRegister, range->NumDescriptors, false, true, @@ -663,10 +666,11 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo }
table->ranges[j].binding = vk_binding; + + context->current_binding = cur_binding; } }
- context->current_binding = cur_binding; return S_OK; }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Descriptor indexing is required for its partial binding feature. Separate buffer and image descriptor arrays are needed for implementing D3D12 SRV and UAV descriptor ranges, so not all of the Vulkan descriptors will be populated.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- libs/vkd3d/command.c | 11 ++-- libs/vkd3d/state.c | 127 ++++++++++++++++++++++++++++++++----- libs/vkd3d/vkd3d_private.h | 1 + tests/d3d12.c | 2 - 4 files changed, 118 insertions(+), 23 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 8bed7303..7bab8ee4 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2592,7 +2592,7 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_descriptor_write, VkDescriptorImageInfo *vk_image_info, const struct d3d12_desc *descriptor, uint32_t descriptor_range_magic, VkDescriptorSet vk_descriptor_set, - uint32_t vk_binding, unsigned int index) + uint32_t vk_binding, unsigned int index, bool use_array) { const struct vkd3d_view *view = descriptor->u.view;
@@ -2602,8 +2602,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des vk_descriptor_write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; vk_descriptor_write->pNext = NULL; vk_descriptor_write->dstSet = vk_descriptor_set; - vk_descriptor_write->dstBinding = vk_binding + index; - vk_descriptor_write->dstArrayElement = 0; + vk_descriptor_write->dstBinding = use_array ? vk_binding : vk_binding + index; + vk_descriptor_write->dstArrayElement = use_array ? index : 0; vk_descriptor_write->descriptorCount = 1; vk_descriptor_write->descriptorType = descriptor->vk_descriptor_type; vk_descriptor_write->pImageInfo = NULL; @@ -2620,7 +2620,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des case VKD3D_DESCRIPTOR_MAGIC_UAV: /* We use separate bindings for buffer and texture SRVs/UAVs. * See d3d12_root_signature_init(). */ - vk_descriptor_write->dstBinding = vk_binding + 2 * index; + if(!use_array) + vk_descriptor_write->dstBinding = vk_binding + 2 * index; if (descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER && descriptor->vk_descriptor_type != VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) ++vk_descriptor_write->dstBinding; @@ -2707,7 +2708,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list
if (!vk_write_descriptor_set_from_d3d12_desc(current_descriptor_write, current_image_info, descriptor, range->descriptor_magic, - bindings->descriptor_set, range->binding, j)) + bindings->descriptor_set, range->binding, j, root_signature->use_descriptor_arrays)) continue;
++descriptor_count; diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index a13b8534..8bec8f68 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -300,12 +300,12 @@ static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_d3d12_root_p
static bool vk_binding_from_d3d12_descriptor_range(struct VkDescriptorSetLayoutBinding *binding_desc, const D3D12_DESCRIPTOR_RANGE *descriptor_range, D3D12_SHADER_VISIBILITY shader_visibility, - bool is_buffer, uint32_t vk_binding) + bool is_buffer, uint32_t vk_binding, unsigned int descriptor_count) { binding_desc->binding = vk_binding; binding_desc->descriptorType = vk_descriptor_type_from_d3d12_range_type(descriptor_range->RangeType, is_buffer); - binding_desc->descriptorCount = 1; + binding_desc->descriptorCount = descriptor_count; binding_desc->stageFlags = stage_flags_from_visibility(shader_visibility); binding_desc->pImmutableSamplers = NULL;
@@ -323,13 +323,14 @@ struct d3d12_root_signature_info };
static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_signature_info *info, - const D3D12_ROOT_DESCRIPTOR_TABLE *table) + const D3D12_ROOT_DESCRIPTOR_TABLE *table, bool use_array) { unsigned int i;
for (i = 0; i < table->NumDescriptorRanges; ++i) { const D3D12_DESCRIPTOR_RANGE *range = &table->pDescriptorRanges[i]; + unsigned int binding_count;
if (range->NumDescriptors == 0xffffffff) { @@ -337,6 +338,8 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig return E_NOTIMPL; }
+ binding_count = use_array ? 1 : range->NumDescriptors; + switch (range->RangeType) { case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: @@ -344,11 +347,11 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig * to preserve compatibility between Vulkan resource bindings for the same * root signature, we create descriptor set layouts with two bindings for * each SRV and UAV. */ - info->binding_count += range->NumDescriptors; + info->binding_count += binding_count; break; case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: /* As above. */ - info->binding_count += range->NumDescriptors; + info->binding_count += binding_count; break; case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: break; @@ -359,14 +362,14 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig return E_NOTIMPL; }
- info->binding_count += range->NumDescriptors; + info->binding_count += binding_count; }
return S_OK; }
static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_info *info, - const D3D12_ROOT_SIGNATURE_DESC *desc) + const D3D12_ROOT_SIGNATURE_DESC *desc, bool use_array) { unsigned int i; HRESULT hr; @@ -381,7 +384,7 @@ static HRESULT d3d12_root_signature_info_from_desc(struct d3d12_root_signature_i { case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: if (FAILED(hr = d3d12_root_signature_info_count_descriptors(info, - &p->u.DescriptorTable))) + &p->u.DescriptorTable, use_array))) return hr; ++info->cost; break; @@ -518,7 +521,7 @@ struct vkd3d_descriptor_set_context static void 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, - struct vkd3d_descriptor_set_context *context) + unsigned int descriptor_count, struct vkd3d_descriptor_set_context *context) { struct vkd3d_shader_resource_binding *mapping = &root_signature->descriptor_mapping[context->descriptor_index++]; @@ -530,7 +533,7 @@ static void d3d12_root_signature_append_vk_binding(struct d3d12_root_signature * mapping->flags = buffer_descriptor ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; mapping->binding.set = root_signature->vk_set_count; mapping->binding.binding = context->descriptor_binding++; - mapping->binding.count = 1; + mapping->binding.count = descriptor_count; }
static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signature *root_signature, @@ -551,10 +554,10 @@ static uint32_t d3d12_root_signature_assign_vk_bindings(struct d3d12_root_signat { if (duplicate_descriptors) d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, - base_register_idx + i, true, shader_visibility, context); + base_register_idx + i, true, shader_visibility, 1, context);
d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, register_space, - base_register_idx + i, is_buffer_descriptor, shader_visibility, context); + base_register_idx + i, is_buffer_descriptor, shader_visibility, 1, context); } return first_binding; } @@ -577,6 +580,36 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty } }
+static HRESULT d3d12_root_signature_init_descriptor_array_binding(struct d3d12_root_signature *root_signature, + const D3D12_DESCRIPTOR_RANGE *range, D3D12_SHADER_VISIBILITY visibility, + struct vkd3d_descriptor_set_context *context) +{ + enum vkd3d_shader_descriptor_type descriptor_type = vkd3d_descriptor_type_from_d3d12_range_type(range->RangeType); + enum vkd3d_shader_visibility shader_visibility = vkd3d_shader_visibility_from_d3d12(visibility); + bool is_buffer = descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_CBV; + + if (descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || descriptor_type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + { + if (!vk_binding_from_d3d12_descriptor_range(context->current_binding, + range, visibility, true, context->descriptor_binding, range->NumDescriptors)) + return E_NOTIMPL; + ++context->current_binding; + + d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->RegisterSpace, + range->BaseShaderRegister, true, shader_visibility, range->NumDescriptors, context); + } + + if (!vk_binding_from_d3d12_descriptor_range(context->current_binding, + range, visibility, is_buffer, context->descriptor_binding, range->NumDescriptors)) + return E_NOTIMPL; + ++context->current_binding; + + d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->RegisterSpace, + range->BaseShaderRegister, is_buffer, shader_visibility, range->NumDescriptors, context); + + return S_OK; +} + static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_root_signature *root_signature, const D3D12_ROOT_SIGNATURE_DESC *desc, struct vkd3d_descriptor_set_context *context) { @@ -584,6 +617,7 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo const D3D12_DESCRIPTOR_RANGE *range; unsigned int i, j, k, range_count; uint32_t vk_binding; + HRESULT hr;
root_signature->descriptor_table_mask = 0;
@@ -633,6 +667,17 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
range = &p->u.DescriptorTable.pDescriptorRanges[j];
+ if (root_signature->use_descriptor_arrays) + { + table->ranges[j].binding = context->descriptor_binding; + + if (FAILED(hr = d3d12_root_signature_init_descriptor_array_binding(root_signature, + range, p->ShaderVisibility, context))) + return hr; + + continue; + } + cur_binding = context->current_binding;
vk_binding = d3d12_root_signature_assign_vk_bindings(root_signature, @@ -652,14 +697,14 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo
/* Assign binding for image view. */ if (!vk_binding_from_d3d12_descriptor_range(cur_binding, - range, p->ShaderVisibility, false, vk_current_binding + 1)) + range, p->ShaderVisibility, false, vk_current_binding + 1, 1)) return E_NOTIMPL;
++cur_binding; }
if (!vk_binding_from_d3d12_descriptor_range(cur_binding, - range, p->ShaderVisibility, true, vk_current_binding)) + range, p->ShaderVisibility, true, vk_current_binding, 1)) return E_NOTIMPL;
++cur_binding; @@ -742,11 +787,32 @@ static HRESULT d3d12_root_signature_init_static_samplers(struct d3d12_root_signa return S_OK; }
+static bool vk_binding_uses_partial_binding(const VkDescriptorSetLayoutBinding *binding) +{ + if (binding->descriptorCount == 1) + return false; + + switch (binding->descriptorType) + { + /* Types mapped in vk_descriptor_type_from_d3d12_range_type() from D3D12 SRV and UAV types, + * i.e. those which can be a buffer or an image. */ + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + return true; + default: + return false; + } +} + static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device, VkDescriptorSetLayoutCreateFlags flags, unsigned int binding_count, const VkDescriptorSetLayoutBinding *bindings, VkDescriptorSetLayout *set_layout) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkDescriptorSetLayoutBindingFlagsCreateInfoEXT flags_info; + VkDescriptorBindingFlagsEXT *set_flags = NULL; VkDescriptorSetLayoutCreateInfo set_desc; VkResult vr;
@@ -755,7 +821,35 @@ static HRESULT vkd3d_create_descriptor_set_layout(struct d3d12_device *device, set_desc.flags = flags; set_desc.bindingCount = binding_count; set_desc.pBindings = bindings; - if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, set_layout))) < 0) + if (device->vk_info.EXT_descriptor_indexing) + { + unsigned int i; + + for (i = 0; i < binding_count; ++i) + if (vk_binding_uses_partial_binding(&bindings[i])) + break; + + if (i < binding_count) + { + if (!(set_flags = vkd3d_malloc(binding_count * sizeof(*set_flags)))) + return E_OUTOFMEMORY; + + for (i = 0; i < binding_count; ++i) + set_flags[i] = vk_binding_uses_partial_binding(&bindings[i]) + ? VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT : 0; + + flags_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT; + flags_info.pNext = NULL; + flags_info.bindingCount = binding_count; + flags_info.pBindingFlags = set_flags; + + set_desc.pNext = &flags_info; + } + } + + vr = VK_CALL(vkCreateDescriptorSetLayout(device->vk_device, &set_desc, NULL, set_layout)); + vkd3d_free(set_flags); + if (vr < 0) { WARN("Failed to create Vulkan descriptor set layout, vr %d.\n", vr); return hresult_from_vk_result(vr); @@ -817,7 +911,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa | D3D12_ROOT_SIGNATURE_FLAG_ALLOW_STREAM_OUTPUT)) FIXME("Ignoring root signature flags %#x.\n", desc->Flags);
- if (FAILED(hr = d3d12_root_signature_info_from_desc(&info, desc))) + if (FAILED(hr = d3d12_root_signature_info_from_desc(&info, desc, device->vk_info.EXT_descriptor_indexing))) return hr; if (info.cost > D3D12_MAX_ROOT_COST) { @@ -828,6 +922,7 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa root_signature->binding_count = info.binding_count; root_signature->static_sampler_count = desc->NumStaticSamplers; root_signature->root_descriptor_count = info.root_descriptor_count; + root_signature->use_descriptor_arrays = device->vk_info.EXT_descriptor_indexing;
hr = E_OUTOFMEMORY; root_signature->parameter_count = desc->NumParameters; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 70e3248f..deb8ee99 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -702,6 +702,7 @@ struct d3d12_root_signature VkPipelineLayout vk_pipeline_layout; uint32_t vk_set_count; VkDescriptorSetLayout vk_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS]; + bool use_descriptor_arrays;
struct d3d12_root_parameter *parameters; unsigned int parameter_count; diff --git a/tests/d3d12.c b/tests/d3d12.c index 486ca040..d3384abb 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -34635,7 +34635,6 @@ static void test_resource_arrays(void) get_cpu_descriptor_handle(&context, heap, ARRAY_SIZE(input_buffers) + i)); }
- todo context.pipeline_state = create_compute_pipeline_state(device, context.root_signature, shader_bytecode(cs_code, sizeof(cs_code))); if (!context.pipeline_state) @@ -34658,7 +34657,6 @@ static void test_resource_arrays(void) transition_sub_resource_state(command_list, output_buffers[i], 0, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE); get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_R32_UINT, &rb, queue, command_list); - todo_if(i) check_readback_data_uint(&rb, NULL, uav_data[i], 0); release_resource_readback(&rb); reset_command_list(command_list, context.allocator);
On Fri, 30 Jul 2021 at 06:05, Conor McCarthy cmccarthy@codeweavers.com wrote:
@@ -2620,7 +2620,8 @@ static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_des case VKD3D_DESCRIPTOR_MAGIC_UAV: /* We use separate bindings for buffer and texture SRVs/UAVs. * See d3d12_root_signature_init(). */
vk_descriptor_write->dstBinding = vk_binding + 2 * index;
if(!use_array)
vk_descriptor_write->dstBinding = vk_binding + 2 * index;
Missing space between "if" and "(!use_array)".