There are two motivations for this:
* First, the structure *almost* corresponds to D3D12_SHADER_INPUT_BIND_DESC, and if more elements were included, it could be used as-is for shader reflection.
There is the quirk that currently we return scan information based on the shader instructions, whereas d3dcompiler shader reflection expects to get it from the shader reflection data (i.e. the RDEF chunk), which is particularly relevant in the case that the RDEF chunk is stripped.
That said, even if we have to introduce an extra scan API to account for this difference, being able to reuse the same structure seems like a benefit.
In order to reuse this structure, we need to add the following elements:
- Register ID (added in part 1 of this series)
- Sample count (added in part 2 of this series)
- Flags or resource types to distinguish between typed, raw, and structured buffers. I have not decided which representation makes the most sense; opinions are welcome.
* Second, I think it makes sense to use this reflection information internally in spirv.c (and potentially other compiler backends) to declare resources in the target environment, instead of parsing DCL instructions. The idea here is that this allows backends to be more agnostic as to how resources are declared (or inferred) in the frontend, while avoiding the need to synthesize those DCL instructions in the frontend either [especially since epenthesizing instructions is more expensive than converting them to NOPs.]
In order to do that, we will need vkd3d_shader_scan_descriptor_info1 to cover everything that is currently covered by DCL instructions. This needs the same elements as above (register ID and sample count), but also:
- Structure stride (added in part 2 of this series)
- Constant buffer used width (added in part 2 of this series)
I don't currently have a proof-of-concept using these new elements. On the other hand, since it's just an extension of an existing API, I figured that seemed less critical.
This does conflict trivially with 280; I'm submitting it now since 280 is accepted, but due to Alexandre's vacation may not be committed soon, and since this is new API I'd rather get comments early anyway.
-- v2: vkd3d-shader: Get rid of the uav_ranges array. vkd3d-shader: Add register ID to struct vkd3d_shader_descriptor_info1. vkd3d-shader: Introduce struct vkd3d_shader_scan_descriptor_info1. vkd3d-shader: Centralize cleanup on error in scan_with_parser(). vkd3d-shader: Factor more code into vkd3d_shader_scan_get_uav_descriptor_info().
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/vkd3d_shader_main.c | 39 +++++++++------------------ 1 file changed, 13 insertions(+), 26 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index e6ffb84d..4d45e1e2 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -703,18 +703,23 @@ static struct vkd3d_shader_cf_info *vkd3d_shader_scan_find_innermost_loop_cf_inf return NULL; }
-static struct vkd3d_shader_descriptor_info *vkd3d_shader_scan_get_uav_descriptor_info( - const struct vkd3d_shader_scan_context *context, unsigned int range_id) +static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_register *reg, uint32_t flag) { + unsigned int range_id = reg->idx[0].offset; unsigned int i;
+ if (!context->scan_descriptor_info) + return; + for (i = 0; i < context->uav_range_count; ++i) { if (context->uav_ranges[i].id == range_id) - return &context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx]; + { + context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx].flags |= flag; + break; + } } - - return NULL; }
static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instruction *instruction) @@ -730,13 +735,7 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { - struct vkd3d_shader_descriptor_info *d; - - if (!context->scan_descriptor_info) - return; - - d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); - d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ; + vkd3d_shader_scan_add_uav_flag(context, reg, VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ); }
static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction) @@ -749,13 +748,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { - struct vkd3d_shader_descriptor_info *d; - - if (!context->scan_descriptor_info) - return; - - d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); - d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER; + vkd3d_shader_scan_add_uav_flag(context, reg, VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER); }
static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_instruction *instruction) @@ -768,13 +761,7 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { - struct vkd3d_shader_descriptor_info *d; - - if (!context->scan_descriptor_info) - return; - - d = vkd3d_shader_scan_get_uav_descriptor_info(context, reg->idx[0].offset); - d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS; + vkd3d_shader_scan_add_uav_flag(context, reg, VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS); }
static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context,
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/vkd3d_shader_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 4d45e1e2..569409cc 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1132,11 +1132,7 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info { instruction = &parser->instructions.elements[i]; if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) - { - if (scan_descriptor_info) - vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); break; - } }
for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i) @@ -1156,13 +1152,17 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info || !vkd3d_shader_signature_from_shader_signature(&signature_info->patch_constant, &parser->shader_desc.patch_constant_signature)) { - vkd3d_shader_free_scan_signature_info(signature_info); - if (scan_descriptor_info) - vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); ret = VKD3D_ERROR_OUT_OF_MEMORY; } }
+ if (ret < 0) + { + if (scan_descriptor_info) + vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); + if (signature_info) + vkd3d_shader_free_scan_signature_info(signature_info); + } vkd3d_shader_scan_context_cleanup(&context); return ret; }
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 18 ++--- libs/vkd3d-shader/vkd3d_shader_main.c | 90 ++++++++++++++++++------ libs/vkd3d-shader/vkd3d_shader_private.h | 19 ++++- 3 files changed, 95 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2725ed80..fa605f18 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2310,7 +2310,7 @@ struct spirv_compiler
uint32_t binding_idx;
- const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; unsigned int input_control_point_count; unsigned int output_control_point_count; bool use_vocp; @@ -2380,7 +2380,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler)
static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *shader_version, struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, - const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, + const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location) { const struct shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature; @@ -5695,13 +5695,13 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty } }
-static const struct vkd3d_shader_descriptor_info *spirv_compiler_get_descriptor_info( +static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor_info( struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range) { - const struct vkd3d_shader_scan_descriptor_info *descriptor_info = compiler->scan_descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; unsigned int register_last = (range->last == ~0u) ? range->first : range->last; - const struct vkd3d_shader_descriptor_info *d; + const struct vkd3d_shader_descriptor_info1 *d; unsigned int i;
for (i = 0; i < descriptor_info->descriptor_count; ++i) @@ -5721,7 +5721,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler bool raw_structured, uint32_t depth) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_descriptor_info *d; + const struct vkd3d_shader_descriptor_info1 *d; bool uav_read, uav_atomics; uint32_t sampled_type_id; SpvImageFormat format; @@ -5756,7 +5756,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi const struct vkd3d_shader_combined_resource_sampler *current; uint32_t image_type_id, type_id, ptr_type_id, var_id; enum vkd3d_shader_binding_flag resource_type_flag; - const struct vkd3d_shader_descriptor_info *d; + const struct vkd3d_shader_descriptor_info1 *d; struct vkd3d_symbol symbol; unsigned int i; bool depth; @@ -5889,7 +5889,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
if (is_uav) { - const struct vkd3d_shader_descriptor_info *d; + const struct vkd3d_shader_descriptor_info1 *d;
d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range); @@ -9635,7 +9635,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, }
int spirv_compile(struct vkd3d_shader_parser *parser, - const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, + const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 569409cc..b202adbf 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -579,7 +579,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig
struct vkd3d_shader_scan_context { - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; size_t descriptors_size;
struct vkd3d_shader_message_context *message_context; @@ -612,7 +612,7 @@ struct vkd3d_shader_scan_context
static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, struct vkd3d_shader_message_context *message_context) { unsigned int i; @@ -769,8 +769,8 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags) { - struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info; - struct vkd3d_shader_descriptor_info *d; + struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; + struct vkd3d_shader_descriptor_info1 *d;
if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size, info->descriptor_count + 1, sizeof(*info->descriptors))) @@ -1104,24 +1104,64 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_OK; }
+static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descriptor_info *info, + const struct vkd3d_shader_scan_descriptor_info1 *info1) +{ + unsigned int i; + + if (!(info->descriptors = vkd3d_malloc(info1->descriptor_count * sizeof(*info->descriptors)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + for (i = 0; i < info1->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *src = &info1->descriptors[i]; + struct vkd3d_shader_descriptor_info *dst = &info->descriptors[i]; + + dst->type = src->type; + dst->register_space = src->register_space; + dst->register_index = src->register_index; + dst->resource_type = src->resource_type; + dst->resource_data_type = src->resource_data_type; + dst->flags = src->flags; + dst->count = src->count; + } + info->descriptor_count = info1->descriptor_count; + + return VKD3D_OK; +} + +static void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info) +{ + TRACE("scan_descriptor_info %p.\n", scan_descriptor_info); + + vkd3d_free(scan_descriptor_info->descriptors); +} + static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser) + struct vkd3d_shader_message_context *message_context, + struct vkd3d_shader_scan_descriptor_info1 *descriptor_info1, struct vkd3d_shader_parser *parser) { - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; + struct vkd3d_shader_scan_descriptor_info1 local_descriptor_info1 = {0}; + struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_instruction *instruction; struct vkd3d_shader_scan_context context; int ret = VKD3D_OK; unsigned int i;
- if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO))) + descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); + if (descriptor_info1) { - scan_descriptor_info->descriptors = NULL; - scan_descriptor_info->descriptor_count = 0; + descriptor_info1->descriptors = NULL; + descriptor_info1->descriptor_count = 0; + } + else if (descriptor_info) + { + descriptor_info1 = &local_descriptor_info1; } signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO);
- vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context); + vkd3d_shader_scan_context_init(&context, compile_info, descriptor_info1, message_context);
if (TRACE_ON()) { @@ -1156,13 +1196,22 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info } }
+ if (!ret && descriptor_info) + ret = convert_descriptor_info(descriptor_info, descriptor_info1); + if (ret < 0) { - if (scan_descriptor_info) - vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); + if (descriptor_info) + vkd3d_shader_free_scan_descriptor_info(descriptor_info); + if (descriptor_info1) + vkd3d_shader_free_scan_descriptor_info1(descriptor_info1); if (signature_info) vkd3d_shader_free_scan_signature_info(signature_info); } + else + { + vkd3d_shader_free_scan_descriptor_info1(&local_descriptor_info1); + } vkd3d_shader_scan_context_cleanup(&context); return ret; } @@ -1179,7 +1228,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info, return ret; }
- ret = scan_with_parser(compile_info, message_context, parser); + ret = scan_with_parser(compile_info, message_context, NULL, parser); vkd3d_shader_parser_destroy(parser);
return ret; @@ -1197,7 +1246,7 @@ static int scan_d3dbc(const struct vkd3d_shader_compile_info *compile_info, return ret; }
- ret = scan_with_parser(compile_info, message_context, parser); + ret = scan_with_parser(compile_info, message_context, NULL, parser); vkd3d_shader_parser_destroy(parser);
return ret; @@ -1215,7 +1264,7 @@ static int scan_dxil(const struct vkd3d_shader_compile_info *compile_info, return ret; }
- ret = scan_with_parser(compile_info, message_context, parser); + ret = scan_with_parser(compile_info, message_context, NULL, parser); vkd3d_shader_parser_destroy(parser);
return ret; @@ -1274,7 +1323,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { - struct vkd3d_shader_scan_descriptor_info scan_descriptor_info; + struct vkd3d_shader_scan_descriptor_info1 scan_descriptor_info; struct vkd3d_glsl_generator *glsl_generator; struct vkd3d_shader_compile_info scan_info; int ret; @@ -1282,11 +1331,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source);
scan_info = *compile_info; - scan_descriptor_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO; - scan_descriptor_info.next = scan_info.next; - scan_info.next = &scan_descriptor_info;
- if ((ret = scan_with_parser(&scan_info, message_context, parser)) < 0) + if ((ret = scan_with_parser(&scan_info, message_context, &scan_descriptor_info, parser)) < 0) return ret;
switch (compile_info->target_type) @@ -1300,7 +1346,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, message_context, &parser->location))) { ERR("Failed to create GLSL generator.\n"); - vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); + vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); return VKD3D_ERROR; }
@@ -1318,7 +1364,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, assert(0); }
- vkd3d_shader_free_scan_descriptor_info(&scan_descriptor_info); + vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); return ret; }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index dc43175d..adc7755c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1108,6 +1108,23 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse parser->ops->parser_destroy(parser); }
+struct vkd3d_shader_descriptor_info1 +{ + enum vkd3d_shader_descriptor_type type; + unsigned int register_space; + unsigned int register_index; + enum vkd3d_shader_resource_type resource_type; + enum vkd3d_shader_resource_data_type resource_data_type; + unsigned int flags; + unsigned int count; +}; + +struct vkd3d_shader_scan_descriptor_info1 +{ + struct vkd3d_shader_descriptor_info1 *descriptors; + unsigned int descriptor_count; +}; + void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_version *shader_version);
@@ -1230,7 +1247,7 @@ void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); #define SPIRV_MAX_SRC_COUNT 6
int spirv_compile(struct vkd3d_shader_parser *parser, - const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, + const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/vkd3d_shader_main.c | 17 ++++++++++------- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index b202adbf..3d74f779 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -765,9 +765,9 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont }
static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, - enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range, - enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, - unsigned int flags) + enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, + const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, + enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags) { struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; struct vkd3d_shader_descriptor_info1 *d; @@ -781,6 +781,7 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c
d = &info->descriptors[info->descriptor_count]; d->type = type; + d->register_id = reg->idx[0].offset; d->register_space = range->space; d->register_index = range->first; d->resource_type = resource_type; @@ -817,7 +818,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc if (!context->scan_descriptor_info) return;
- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &cb->range, + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); }
@@ -834,7 +835,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte flags = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; else flags = 0; - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler->range, + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT, flags); }
@@ -851,7 +852,8 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; else type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; - vkd3d_shader_scan_add_descriptor(context, type, &resource->range, resource_type, resource_data_type, 0); + vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, &resource->range, + resource_type, resource_data_type, 0); if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset, context->scan_descriptor_info->descriptor_count - 1); @@ -1178,9 +1180,10 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i) { struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; + struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1};
if (parser->shader_desc.flat_constant_count[i].external) - vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); }
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index adc7755c..65d2d4fd 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1113,6 +1113,7 @@ struct vkd3d_shader_descriptor_info1 enum vkd3d_shader_descriptor_type type; unsigned int register_space; unsigned int register_index; + unsigned int register_id; enum vkd3d_shader_resource_type resource_type; enum vkd3d_shader_resource_data_type resource_data_type; unsigned int flags;
From: Zebediah Figura zfigura@codeweavers.com
This is now redundant; the register ID is encoded into the scan descriptors. --- libs/vkd3d-shader/vkd3d_shader_main.c | 35 +++------------------------ 1 file changed, 3 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 3d74f779..fbce762a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -599,14 +599,6 @@ struct vkd3d_shader_scan_context size_t cf_info_size; size_t cf_info_count;
- struct - { - unsigned int id; - unsigned int descriptor_idx; - } *uav_ranges; - size_t uav_ranges_size; - size_t uav_range_count; - enum vkd3d_shader_api_version api_version; };
@@ -635,7 +627,6 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con
static void vkd3d_shader_scan_context_cleanup(struct vkd3d_shader_scan_context *context) { - vkd3d_free(context->uav_ranges); vkd3d_free(context->cf_info); }
@@ -712,11 +703,11 @@ static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_contex if (!context->scan_descriptor_info) return;
- for (i = 0; i < context->uav_range_count; ++i) + for (i = 0; i < context->scan_descriptor_info->descriptor_count; ++i) { - if (context->uav_ranges[i].id == range_id) + if (context->scan_descriptor_info->descriptors[i].register_id == range_id) { - context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx].flags |= flag; + context->scan_descriptor_info->descriptors[i].flags |= flag; break; } } @@ -793,23 +784,6 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c return true; }
-static bool vkd3d_shader_scan_add_uav_range(struct vkd3d_shader_scan_context *context, - unsigned int id, unsigned int descriptor_idx) -{ - if (!vkd3d_array_reserve((void **)&context->uav_ranges, &context->uav_ranges_size, - context->uav_range_count + 1, sizeof(*context->uav_ranges))) - { - ERR("Failed to allocate UAV range.\n"); - return false; - } - - context->uav_ranges[context->uav_range_count].id = id; - context->uav_ranges[context->uav_range_count].descriptor_idx = descriptor_idx; - ++context->uav_range_count; - - return true; -} - static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_instruction *instruction) { @@ -854,9 +828,6 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, &resource->range, resource_type, resource_data_type, 0); - if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) - vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset, - context->scan_descriptor_info->descriptor_count - 1); }
static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context,
I can see the value in avoiding exposing the API unless necessary. It'd be an awkward and nontrivial bit of extra work to make this internal, though, given how the descriptor info is currently accessed by vkd3d_shader_parser_compile().
Maybe not trivial, but it doesn't seem that hard? In particular, I imagine we can essentially just pass the new structure as optional parameter to scan_with_parser() and use it instead of "local_descriptor_info1" if present.
Okay, it's significantly easier than I thought; I don't know what kind of tunnel vision I had that was preventing me from doing it cleanly.
I've pushed a new version that does this. It also keeps all the current naming, which makes it look like it's still an exported structure. I think this is fine, because I'm still pretty confident we'll want to export this eventually, but I can change it if requested.
+static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descriptor_info *info, + const struct vkd3d_shader_scan_descriptor_info1 *info1) +{ + unsigned int i; + + if (!(info->descriptors = vkd3d_malloc(info1->descriptor_count * sizeof(*info->descriptors)))) + return VKD3D_ERROR_OUT_OF_MEMORY;
The vkd3d_malloc() call is safe because sizeof(*info->descriptors) <= sizeof(*info1->descriptors), but I don't think it's setting a great example; we'd generally want to use vkd3d_calloc().