[PATCH vkd3d v2 2/4] vkd3d: Use arrayed Vulkan bindings if descriptor indexing is available.
Conor McCarthy
cmccarthy at codeweavers.com
Thu Jun 3 00:04:05 CDT 2021
The partial binding feature enables bindings with count > 1 even for
SRV and UAV descriptors, for which both buffer and image bindings
must be created to accomodate D3D12 heap flexibility. This patch
depends on shader model 5.1 support.
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
libs/vkd3d/state.c | 91 +++++++++++++++++++++++++++++++-------
libs/vkd3d/vkd3d_private.h | 1 +
2 files changed, 75 insertions(+), 17 deletions(-)
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index d07212f6..f676ab88 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, unsigned int descriptor_count, uint32_t vk_binding)
{
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 bindless)
{
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 = bindless ? 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 bindless)
{
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, bindless)))
return hr;
++info->cost;
break;
@@ -517,7 +520,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,
+ bool buffer_descriptor, unsigned int descriptor_count, enum vkd3d_shader_visibility shader_visibility,
struct vkd3d_descriptor_set_context *context)
{
struct vkd3d_shader_resource_binding *mapping
@@ -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,11 @@ 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, 1, shader_visibility, 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, 1, shader_visibility,
+ context);
}
return first_binding;
}
@@ -577,10 +581,40 @@ static uint32_t vkd3d_descriptor_magic_from_d3d12(D3D12_DESCRIPTOR_RANGE_TYPE ty
}
}
+static HRESULT d3d12_root_signature_init_bindless_descriptor_range(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, range->NumDescriptors, context->descriptor_binding))
+ return E_NOTIMPL;
+ ++context->current_binding;
+
+ d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->RegisterSpace,
+ range->BaseShaderRegister, true, range->NumDescriptors, shader_visibility, context);
+ }
+
+ if (!vk_binding_from_d3d12_descriptor_range(context->current_binding,
+ range, visibility, is_buffer, range->NumDescriptors, context->descriptor_binding))
+ return E_NOTIMPL;
+ ++context->current_binding;
+
+ d3d12_root_signature_append_vk_binding(root_signature, descriptor_type, range->RegisterSpace,
+ range->BaseShaderRegister, is_buffer, range->NumDescriptors, shader_visibility, 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)
{
- VkDescriptorSetLayoutBinding *cur_binding = context->current_binding;
struct d3d12_root_descriptor_table *table;
const D3D12_DESCRIPTOR_RANGE *range;
unsigned int i, j, k, range_count;
@@ -628,6 +662,24 @@ 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];
+
+ if (root_signature->bindless)
+ {
+ HRESULT hr;
+
+ table->ranges[j].binding = context->descriptor_binding;
+ if (FAILED(hr = d3d12_root_signature_init_bindless_descriptor_range(root_signature,
+ range, p->ShaderVisibility, context)))
+ return hr;
+
+ continue;
+ }
+
+ 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,
@@ -645,24 +697,25 @@ 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, 1, vk_current_binding + 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, 1, vk_current_binding))
return E_NOTIMPL;
++cur_binding;
}
table->ranges[j].binding = vk_binding;
+
+ context->current_binding = cur_binding;
}
}
- context->current_binding = cur_binding;
return S_OK;
}
@@ -809,7 +862,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)
{
@@ -820,6 +873,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->bindless = device->vk_info.EXT_descriptor_indexing;
hr = E_OUTOFMEMORY;
root_signature->parameter_count = desc->NumParameters;
@@ -1474,6 +1528,9 @@ static HRESULT d3d12_pipeline_state_init_compute_uav_counters(struct d3d12_pipel
|| !(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER))
continue;
+ if (d->count != 1)
+ FIXME("UAV counter arrays are not supported.\n");
+
state->uav_counters[j].register_space = d->register_space;
state->uav_counters[j].register_index = d->register_index;
state->uav_counters[j].shader_visibility = VKD3D_SHADER_VISIBILITY_COMPUTE;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 8dbb05b5..d86bf9a3 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 bindless;
struct d3d12_root_parameter *parameters;
unsigned int parameter_count;
--
2.31.1
More information about the wine-devel
mailing list