[PATCH vkd3d 3/5] vkd3d-shader/spirv: Send descriptor offsets via a shader parameter.
Conor McCarthy
cmccarthy at codeweavers.com
Tue Nov 23 08:41:35 CST 2021
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
include/vkd3d_shader.h | 110 +++++++++++++++++---------------------
libs/vkd3d-shader/spirv.c | 21 ++++----
libs/vkd3d/state.c | 68 ++++++++++++++---------
3 files changed, 101 insertions(+), 98 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 4a51b3f4..deffef19 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -249,6 +249,8 @@ enum vkd3d_shader_parameter_name
{
VKD3D_SHADER_PARAMETER_NAME_UNKNOWN,
VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT,
+ VKD3D_SHADER_PARAMETER_NAME_DESCRIPTOR_OFFSETS,
+ VKD3D_SHADER_PARAMETER_NAME_UAV_COUNTER_OFFSETS,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
};
@@ -266,6 +268,52 @@ struct vkd3d_shader_parameter_specialization_constant
uint32_t id;
};
+struct vkd3d_shader_parameter_descriptor_offsets
+{
+ /**
+ * Pointer to an array of offsets into the descriptor arrays referenced by
+ * the 'bindings' array in struct vkd3d_shader_interface_info. This allows
+ * mapping multiple shader resource arrays to a single binding point in
+ * the target environment.
+ *
+ * For example, to map Direct3D constant buffer registers 'cb0[0:3]' and
+ * 'cb1[6:7]' to descriptors 8-12 and 4-5 in the Vulkan descriptor array in
+ * descriptor set 3 and with binding 2, set the following values in the
+ * 'bindings' array in struct vkd3d_shader_interface_info:
+ *
+ * \code
+ * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
+ * register_space = 0
+ * register_index = 0
+ * binding.set = 3
+ * binding.binding = 2
+ * binding.count = 4
+ *
+ * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
+ * register_space = 0
+ * register_index = 6
+ * binding.set = 3
+ * binding.binding = 2
+ * binding.count = 2
+ * \endcode
+ *
+ * and then pass \c {8, \c 4} as \a binding_offsets here.
+ *
+ * This field may be NULL, or the structure may be omitted from the
+ * parameter list, in which case the corresponding offsets are specified
+ * to be 0.
+ *
+ * If the parameter is specified under name
+ * VKD3D_SHADER_PARAMETER_NAME_UAV_COUNTER_OFFSETS, 'offsets' points to an
+ * array of offsets into the descriptor arrays referenced by the
+ * 'uav_counters' array in struct vkd3d_shader_interface_info. This works
+ * the same way as described above. UAV counter arrays are not supported in
+ * this version of vkd3d-shader, and therefore this field must be NULL, or
+ * the parameter omitted.
+ */
+ const unsigned int *offsets;
+};
+
struct vkd3d_shader_parameter
{
enum vkd3d_shader_parameter_name name;
@@ -275,6 +322,7 @@ struct vkd3d_shader_parameter
{
struct vkd3d_shader_parameter_immediate_constant immediate_constant;
struct vkd3d_shader_parameter_specialization_constant specialization_constant;
+ struct vkd3d_shader_parameter_descriptor_offsets descriptor_offsets;
} u;
};
@@ -458,68 +506,6 @@ struct vkd3d_shader_transform_feedback_info
unsigned int buffer_stride_count;
};
-/**
- * A chained structure containing descriptor offsets.
- *
- * This structure is optional.
- *
- * This structure extends vkd3d_shader_interface_info.
- *
- * This structure contains only input parameters.
- *
- * \since 1.3
- */
-struct vkd3d_shader_descriptor_offset_info
-{
- /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO. */
- enum vkd3d_shader_structure_type type;
- /** Optional pointer to a structure containing further parameters. */
- const void *next;
-
- /**
- * Pointer to an array of offsets into the descriptor arrays referenced by
- * the 'bindings' array in struct vkd3d_shader_interface_info. This allows
- * mapping multiple shader resource arrays to a single binding point in
- * the target environment.
- *
- * For example, to map Direct3D constant buffer registers 'cb0[0:3]' and
- * 'cb1[6:7]' to descriptors 8-12 and 4-5 in the Vulkan descriptor array in
- * descriptor set 3 and with binding 2, set the following values in the
- * 'bindings' array in struct vkd3d_shader_interface_info:
- *
- * \code
- * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
- * register_space = 0
- * register_index = 0
- * binding.set = 3
- * binding.binding = 2
- * binding.count = 4
- *
- * type = VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
- * register_space = 0
- * register_index = 6
- * binding.set = 3
- * binding.binding = 2
- * binding.count = 2
- * \endcode
- *
- * and then pass \c {8, \c 4} as \a binding_offsets here.
- *
- * This field may be NULL, in which case the corresponding offsets are
- * specified to be 0.
- */
- const unsigned int *binding_offsets;
-
- /**
- * Pointer to an array of offsets into the descriptor arrays referenced by
- * the 'uav_counters' array in struct vkd3d_shader_interface_info. This
- * works the same way as \ref binding_offsets above. UAV counter arrays are
- * not supported in this version of vkd3d-shader, and therefore this field
- * must either be NULL or specify 0 offsets.
- */
- const unsigned int *uav_counter_offsets;
-};
-
/** The format of a shader to be compiled or scanned. */
enum vkd3d_shader_source_type
{
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 522225d9..9f71c6e0 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2235,7 +2235,7 @@ struct vkd3d_dxbc_compiler
size_t control_flow_info_size;
struct vkd3d_shader_interface_info shader_interface;
- struct vkd3d_shader_descriptor_offset_info offset_info;
+ const unsigned int *binding_offsets;
struct vkd3d_push_constant_buffer_binding *push_constants;
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
@@ -2289,6 +2289,9 @@ static const char *vkd3d_dxbc_compiler_get_entry_point_name(const struct vkd3d_d
return info && info->entry_point ? info->entry_point : "main";
}
+static const struct vkd3d_shader_parameter *vkd3d_dxbc_compiler_get_shader_parameter(
+ struct vkd3d_dxbc_compiler *compiler, enum vkd3d_shader_parameter_name name);
+
struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version,
const struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
@@ -2297,8 +2300,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
const struct vkd3d_shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature;
const struct vkd3d_shader_interface_info *shader_interface;
- const struct vkd3d_shader_descriptor_offset_info *offset_info;
const struct vkd3d_shader_spirv_target_info *target_info;
+ const struct vkd3d_shader_parameter *parameter;
struct vkd3d_dxbc_compiler *compiler;
unsigned int max_element_count;
unsigned int i;
@@ -2391,15 +2394,13 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader
for (i = 0; i < shader_interface->push_constant_buffer_count; ++i)
compiler->push_constants[i].pc = shader_interface->push_constant_buffers[i];
}
-
- if ((offset_info = vkd3d_find_struct(shader_interface->next, DESCRIPTOR_OFFSET_INFO)))
- {
- compiler->offset_info = *offset_info;
- if (offset_info->uav_counter_offsets)
- WARN("Ignoring UAV counter offsets %p.\n", offset_info->uav_counter_offsets);
- }
}
+ if ((parameter = vkd3d_dxbc_compiler_get_shader_parameter(compiler, VKD3D_SHADER_PARAMETER_NAME_DESCRIPTOR_OFFSETS)))
+ compiler->binding_offsets = parameter->u.descriptor_offsets.offsets;
+ if ((parameter = vkd3d_dxbc_compiler_get_shader_parameter(compiler, VKD3D_SHADER_PARAMETER_NAME_UAV_COUNTER_OFFSETS)))
+ WARN("Ignoring UAV counter offsets %p.\n", parameter->u.descriptor_offsets.offsets);
+
compiler->scan_descriptor_info = scan_descriptor_info;
vkd3d_string_buffer_cache_init(&compiler->string_buffers);
@@ -2559,7 +2560,7 @@ static struct vkd3d_shader_descriptor_binding vkd3d_dxbc_compiler_get_descriptor
{
const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface;
unsigned int register_last = (range->last == ~0u) ? range->first : range->last;
- const unsigned int *binding_offsets = compiler->offset_info.binding_offsets;
+ const unsigned int *binding_offsets = compiler->binding_offsets;
enum vkd3d_shader_descriptor_type descriptor_type;
enum vkd3d_shader_binding_flag resource_type_flag;
struct vkd3d_shader_descriptor_binding binding;
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index cb3f99ad..8f788dba 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1880,13 +1880,29 @@ static HRESULT d3d12_pipeline_state_init_uav_counters(struct d3d12_pipeline_stat
return S_OK;
}
+static void spirv_target_info_append_descriptor_offsets(struct vkd3d_shader_spirv_target_info *target_info,
+ const struct d3d12_root_signature *root_signature)
+{
+ struct vkd3d_shader_parameter *parameter;
+
+ if (!root_signature->descriptor_offsets)
+ return;
+
+ parameter = (struct vkd3d_shader_parameter *)&target_info->parameters[target_info->parameter_count];
+ parameter->name = VKD3D_SHADER_PARAMETER_NAME_DESCRIPTOR_OFFSETS;
+ parameter->type = VKD3D_SHADER_PARAMETER_TYPE_UNKNOWN;
+ parameter->data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UNKNOWN;
+ parameter->u.descriptor_offsets.offsets = root_signature->descriptor_offsets;
+ ++target_info->parameter_count;
+}
+
static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *state,
struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_shader_scan_descriptor_info shader_info;
struct vkd3d_shader_interface_info shader_interface;
- struct vkd3d_shader_descriptor_offset_info offset_info;
+ struct vkd3d_shader_parameter shader_parameters[1];
const struct d3d12_root_signature *root_signature;
struct vkd3d_shader_spirv_target_info target_info;
VkPipelineLayout vk_pipeline_layout;
@@ -1925,15 +1941,11 @@ static HRESULT d3d12_pipeline_state_init_compute(struct d3d12_pipeline_state *st
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;
+ target_info.parameters = shader_parameters;
+ target_info.parameter_count = 0;
- if (root_signature->descriptor_offsets)
- {
- offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO;
- offset_info.next = NULL;
- offset_info.binding_offsets = root_signature->descriptor_offsets;
- offset_info.uav_counter_offsets = NULL;
- vkd3d_prepend_struct(&target_info, &offset_info);
- }
+ spirv_target_info_append_descriptor_offsets(&target_info, root_signature);
+ assert(target_info.parameter_count <= ARRAY_SIZE(shader_parameters));
shader_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
shader_interface.next = &target_info;
@@ -2437,13 +2449,14 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
VkVertexInputBindingDivisorDescriptionEXT *binding_divisor;
const struct vkd3d_vulkan_info *vk_info = &device->vk_info;
uint32_t instance_divisors[D3D12_VS_INPUT_REGISTER_COUNT];
+ struct vkd3d_shader_spirv_target_info *stage_target_info;
uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT];
- struct vkd3d_shader_parameter ps_shader_parameters[1];
+ struct vkd3d_shader_parameter ps_shader_parameters[2];
struct vkd3d_shader_transform_feedback_info xfb_info;
struct vkd3d_shader_spirv_target_info ps_target_info;
struct vkd3d_shader_interface_info shader_interface;
- struct vkd3d_shader_descriptor_offset_info offset_info;
- struct vkd3d_shader_spirv_target_info *target_info;
+ struct vkd3d_shader_parameter shader_parameters[1];
+ struct vkd3d_shader_spirv_target_info target_info;
const struct d3d12_root_signature *root_signature;
struct vkd3d_shader_signature input_signature;
bool have_attachment, is_dsv_format_unknown;
@@ -2624,11 +2637,24 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
ps_target_info.extensions = vk_info->shader_extensions;
ps_target_info.extension_count = vk_info->shader_extension_count;
ps_target_info.parameters = ps_shader_parameters;
- ps_target_info.parameter_count = ARRAY_SIZE(ps_shader_parameters);
+ ps_target_info.parameter_count = 1;
ps_target_info.dual_source_blending = is_dual_source_blending(&desc->BlendState.RenderTarget[0]);
ps_target_info.output_swizzles = ps_output_swizzle;
ps_target_info.output_swizzle_count = rt_count;
+ 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 = vk_info->shader_extensions;
+ target_info.extension_count = vk_info->shader_extension_count;
+ target_info.parameters = shader_parameters;
+ target_info.parameter_count = 0;
+
+ spirv_target_info_append_descriptor_offsets(&target_info, root_signature);
+ assert(target_info.parameter_count <= ARRAY_SIZE(shader_parameters));
+ spirv_target_info_append_descriptor_offsets(&ps_target_info, root_signature);
+ assert(ps_target_info.parameter_count <= ARRAY_SIZE(ps_shader_parameters));
+
if (ps_target_info.dual_source_blending && rt_count > 1)
{
WARN("Only one render target is allowed when dual source blending is used.\n");
@@ -2692,15 +2718,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
shader_interface.combined_samplers = NULL;
shader_interface.combined_sampler_count = 0;
- if (root_signature->descriptor_offsets)
- {
- offset_info.type = VKD3D_SHADER_STRUCTURE_TYPE_DESCRIPTOR_OFFSET_INFO;
- offset_info.next = NULL;
- offset_info.binding_offsets = root_signature->descriptor_offsets;
- offset_info.uav_counter_offsets = NULL;
- vkd3d_prepend_struct(&shader_interface, &offset_info);
- }
-
for (i = 0; i < ARRAY_SIZE(shader_stages); ++i)
{
struct vkd3d_shader_scan_descriptor_info shader_info =
@@ -2730,7 +2747,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
shader_interface.uav_counters = NULL;
shader_interface.uav_counter_count = 0;
- target_info = NULL;
+ stage_target_info = &target_info;
switch (shader_stages[i].stage)
{
case VK_SHADER_STAGE_VERTEX_BIT:
@@ -2757,7 +2774,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
case VK_SHADER_STAGE_FRAGMENT_BIT:
shader_interface.uav_counters = state->uav_counters.bindings;
shader_interface.uav_counter_count = state->uav_counters.binding_count;
- target_info = &ps_target_info;
+ stage_target_info = &ps_target_info;
break;
default:
@@ -2768,8 +2785,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
shader_interface.next = NULL;
if (shader_stages[i].stage == xfb_stage)
vkd3d_prepend_struct(&shader_interface, &xfb_info);
- if (target_info)
- vkd3d_prepend_struct(&shader_interface, target_info);
+ vkd3d_prepend_struct(&shader_interface, stage_target_info);
if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count],
shader_stages[i].stage, b, &shader_interface)))
--
2.33.0
More information about the wine-devel
mailing list