vkd3d-shader: Introduce an internal shader signature structure.

A register count is required for Shader Model 6 signatures, including
those normalised from earlier models.
This commit is contained in:
Conor McCarthy 2023-04-04 16:22:57 +10:00 committed by Alexandre Julliard
parent 5ae068168c
commit a0a18b1620
Notes: Alexandre Julliard 2023-05-03 22:38:32 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/197
6 changed files with 122 additions and 52 deletions

View File

@ -322,12 +322,12 @@ int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxbc,
}
static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *section,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *s)
struct vkd3d_shader_message_context *message_context, struct shader_signature *s)
{
bool has_stream_index, has_min_precision;
struct vkd3d_shader_signature_element *e;
const char *data = section->data.code;
uint32_t count, header_size;
struct signature_element *e;
const char *ptr = data;
unsigned int i;
@ -389,6 +389,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
read_dword(&ptr, &e[i].sysval_semantic);
read_dword(&ptr, &e[i].component_type);
read_dword(&ptr, &e[i].register_index);
e[i].register_count = 1;
read_dword(&ptr, &mask);
e[i].mask = mask & 0xff;
e[i].used_mask = (mask >> 8) & 0xff;
@ -423,7 +424,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section,
struct vkd3d_shader_message_context *message_context, void *ctx)
{
struct vkd3d_shader_signature *is = ctx;
struct shader_signature *is = ctx;
if (section->tag != TAG_ISGN)
return VKD3D_OK;
@ -431,13 +432,13 @@ static int isgn_handler(const struct vkd3d_shader_dxbc_section_desc *section,
if (is->elements)
{
FIXME("Multiple input signatures.\n");
vkd3d_shader_free_shader_signature(is);
shader_signature_cleanup(is);
}
return shader_parse_signature(section, message_context, is);
}
int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature)
struct vkd3d_shader_message_context *message_context, struct shader_signature *signature)
{
int ret;
@ -516,9 +517,9 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section,
void free_shader_desc(struct vkd3d_shader_desc *desc)
{
vkd3d_shader_free_shader_signature(&desc->input_signature);
vkd3d_shader_free_shader_signature(&desc->output_signature);
vkd3d_shader_free_shader_signature(&desc->patch_constant_signature);
shader_signature_cleanup(&desc->input_signature);
shader_signature_cleanup(&desc->output_signature);
shader_signature_cleanup(&desc->patch_constant_signature);
}
int shader_extract_from_dxbc(const struct vkd3d_shader_code *dxbc,

View File

@ -320,7 +320,7 @@ static bool shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param
}
static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param,
const struct vkd3d_shader_signature_element *e, enum vkd3d_shader_register_type reg_type)
const struct signature_element *e, enum vkd3d_shader_register_type reg_type)
{
param->write_mask = e->mask;
param->modifiers = 0;
@ -329,11 +329,11 @@ static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param,
}
static enum vkd3d_result shader_normaliser_emit_hs_input(struct vkd3d_shader_normaliser *normaliser,
const struct vkd3d_shader_signature *s, unsigned int input_control_point_count, unsigned int dst)
const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst)
{
const struct vkd3d_shader_signature_element *e;
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_dst_param *param;
const struct signature_element *e;
unsigned int i, count;
for (i = 0, count = 1; i < s->element_count; ++i)
@ -380,7 +380,7 @@ static enum vkd3d_result shader_normaliser_emit_hs_input(struct vkd3d_shader_nor
}
enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser,
const struct vkd3d_shader_signature *input_signature)
const struct shader_signature *input_signature)
{
struct vkd3d_shader_instruction_array *instructions = &normaliser->instructions;
unsigned int input_control_point_count;

View File

@ -2243,9 +2243,9 @@ struct spirv_compiler
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
bool after_declarations_section;
const struct vkd3d_shader_signature *input_signature;
const struct vkd3d_shader_signature *output_signature;
const struct vkd3d_shader_signature *patch_constant_signature;
const struct shader_signature *input_signature;
const struct shader_signature *output_signature;
const struct shader_signature *patch_constant_signature;
const struct vkd3d_shader_transform_feedback_info *xfb_info;
struct vkd3d_shader_output_info
{
@ -2329,8 +2329,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
const struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info,
struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location)
{
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 shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature;
const struct 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;
@ -4258,8 +4258,8 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(const struct sp
return NULL;
}
static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element_for_reg(
const struct vkd3d_shader_signature *signature, unsigned int *signature_element_index,
static const struct signature_element *vkd3d_find_signature_element_for_reg(
const struct shader_signature *signature, unsigned int *signature_element_index,
unsigned int reg_idx, DWORD write_mask)
{
unsigned int signature_idx;
@ -4342,7 +4342,7 @@ static const struct vkd3d_shader_phase *spirv_compiler_get_current_shader_phase(
}
static void spirv_compiler_decorate_xfb_output(struct spirv_compiler *compiler,
uint32_t id, unsigned int component_count, const struct vkd3d_shader_signature_element *signature_element)
uint32_t id, unsigned int component_count, const struct signature_element *signature_element)
{
const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info;
const struct vkd3d_shader_transform_feedback_element *xfb_element;
@ -4423,7 +4423,7 @@ static uint32_t spirv_compiler_emit_builtin_variable(struct spirv_compiler *comp
return id;
}
static bool needs_private_io_variable(const struct vkd3d_shader_signature *signature,
static bool needs_private_io_variable(const struct shader_signature *signature,
unsigned int reg_idx, const struct vkd3d_spirv_builtin *builtin,
unsigned int *component_count, unsigned int *out_write_mask)
{
@ -4443,7 +4443,7 @@ static bool needs_private_io_variable(const struct vkd3d_shader_signature *signa
for (i = 0, count = 0; i < signature->element_count; ++i)
{
const struct vkd3d_shader_signature_element *current = &signature->elements[i];
const struct signature_element *current = &signature->elements[i];
if (current->register_index != reg_idx)
continue;
@ -4478,10 +4478,10 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
enum vkd3d_shader_interpolation_mode interpolation_mode)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_signature_element *signature_element;
const struct vkd3d_shader_signature *shader_signature;
const struct vkd3d_shader_register *reg = &dst->reg;
unsigned int component_idx, input_component_count;
const struct signature_element *signature_element;
const struct shader_signature *shader_signature;
enum vkd3d_shader_component_type component_type;
uint32_t type_id, ptr_type_id, float_type_id;
const struct vkd3d_spirv_builtin *builtin;
@ -4786,8 +4786,7 @@ static bool is_dual_source_blending(const struct spirv_compiler *compiler)
return compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && info && info->dual_source_blending;
}
static void calculate_clip_or_cull_distance_mask(const struct vkd3d_shader_signature_element *e,
uint32_t *mask)
static void calculate_clip_or_cull_distance_mask(const struct signature_element *e, uint32_t *mask)
{
if (e->semantic_index >= sizeof(*mask) * CHAR_BIT / VKD3D_VEC4_SIZE)
{
@ -4799,11 +4798,11 @@ static void calculate_clip_or_cull_distance_mask(const struct vkd3d_shader_signa
}
static uint32_t calculate_sysval_array_mask(struct spirv_compiler *compiler,
const struct vkd3d_shader_signature *signature, enum vkd3d_shader_input_sysval_semantic sysval)
const struct shader_signature *signature, enum vkd3d_shader_input_sysval_semantic sysval)
{
const struct vkd3d_shader_signature_element *e;
const struct vkd3d_spirv_builtin *sig_builtin;
const struct vkd3d_spirv_builtin *builtin;
const struct signature_element *e;
uint32_t signature_idx, mask = 0;
if (!(builtin = get_spirv_builtin_for_sysval(compiler, sysval)))
@ -4829,7 +4828,7 @@ static uint32_t calculate_sysval_array_mask(struct spirv_compiler *compiler,
/* Emits arrayed SPIR-V built-in variables. */
static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler *compiler)
{
const struct vkd3d_shader_signature *output_signature = compiler->output_signature;
const struct shader_signature *output_signature = compiler->output_signature;
uint32_t clip_distance_mask = 0, clip_distance_id = 0;
uint32_t cull_distance_mask = 0, cull_distance_id = 0;
const struct vkd3d_spirv_builtin *builtin;
@ -4837,7 +4836,7 @@ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler *
for (i = 0; i < output_signature->element_count; ++i)
{
const struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
const struct signature_element *e = &output_signature->elements[i];
switch (e->sysval_semantic)
{
@ -4872,7 +4871,7 @@ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler *
for (i = 0; i < output_signature->element_count; ++i)
{
const struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
const struct signature_element *e = &output_signature->elements[i];
switch (e->sysval_semantic)
{
@ -4956,11 +4955,11 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_signature_element *signature_element;
const struct vkd3d_shader_signature *shader_signature;
const struct vkd3d_shader_register *reg = &dst->reg;
unsigned int component_idx, output_component_count;
const struct signature_element *signature_element;
enum vkd3d_shader_component_type component_type;
const struct shader_signature *shader_signature;
const struct vkd3d_spirv_builtin *builtin;
struct vkd3d_symbol *symbol = NULL;
bool use_private_variable = false;
@ -5123,7 +5122,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
}
static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *compiler,
const struct vkd3d_shader_signature_element *e)
const struct signature_element *e)
{
enum vkd3d_shader_input_sysval_semantic sysval;
const struct vkd3d_spirv_builtin *builtin;
@ -5142,14 +5141,14 @@ static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *com
}
static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compiler,
const struct vkd3d_shader_signature *signature, const struct vkd3d_shader_signature_element *output,
const struct shader_signature *signature, const struct signature_element *output,
const struct vkd3d_shader_output_info *output_info,
uint32_t output_index_id, uint32_t val_id, unsigned int write_mask)
{
unsigned int dst_write_mask, use_mask, uninit_mask, swizzle, mask;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id;
const struct vkd3d_shader_signature_element *element;
const struct signature_element *element;
unsigned int i, index, array_idx;
uint32_t output_id;
@ -5238,7 +5237,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler *
uint32_t param_type_id[MAX_REG_OUTPUT + 1], param_id[MAX_REG_OUTPUT + 1] = {0};
uint32_t void_id, type_id, ptr_type_id, function_type_id, function_id;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_signature *signature;
const struct shader_signature *signature;
uint32_t output_index_id = 0;
bool is_patch_constant;
unsigned int i, count;
@ -5323,7 +5322,7 @@ static void spirv_compiler_emit_hull_shader_builtins(struct spirv_compiler *comp
static void spirv_compiler_emit_hull_shader_patch_constants(struct spirv_compiler *compiler)
{
const struct vkd3d_shader_signature *signature = compiler->patch_constant_signature;
const struct shader_signature *signature = compiler->patch_constant_signature;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t register_count = 0;
unsigned int signature_idx;
@ -6446,7 +6445,7 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
{
const struct vkd3d_shader_signature *signature = compiler->output_signature;
const struct shader_signature *signature = compiler->output_signature;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_symbol reg_symbol, *symbol;
struct vkd3d_shader_register reg;
@ -6485,7 +6484,7 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
for (i = 0; i < signature->element_count; ++i)
{
const struct vkd3d_shader_signature_element *e = &signature->elements[i];
const struct signature_element *e = &signature->elements[i];
reg.type = VKD3DSPR_OUTPUT;
reg.idx[0].offset = e->register_index;
@ -6548,8 +6547,8 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler,
static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler)
{
const struct vkd3d_shader_signature *output_signature = compiler->output_signature;
const struct vkd3d_shader_signature *input_signature = compiler->input_signature;
const struct shader_signature *output_signature = compiler->output_signature;
const struct shader_signature *input_signature = compiler->input_signature;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
enum vkd3d_shader_component_type component_type;
struct vkd3d_shader_src_param invocation;
@ -6580,8 +6579,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
assert(input_signature->element_count == output_signature->element_count);
for (i = 0; i < output_signature->element_count; ++i)
{
const struct vkd3d_shader_signature_element *output = &output_signature->elements[i];
const struct vkd3d_shader_signature_element *input = &input_signature->elements[i];
const struct signature_element *output = &output_signature->elements[i];
const struct signature_element *input = &input_signature->elements[i];
assert(input->mask == output->mask);
assert(input->component_type == output->component_type);

View File

@ -2060,7 +2060,7 @@ static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
};
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t *byte_code,
size_t byte_code_size, const char *source_name, const struct vkd3d_shader_signature *output_signature,
size_t byte_code_size, const char *source_name, const struct shader_signature *output_signature,
struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_version version;
@ -2128,7 +2128,7 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t
memset(sm4->output_map, 0xff, sizeof(sm4->output_map));
for (i = 0; i < output_signature->element_count; ++i)
{
struct vkd3d_shader_signature_element *e = &output_signature->elements[i];
struct signature_element *e = &output_signature->elements[i];
if (version.type == VKD3D_SHADER_TYPE_PIXEL
&& ascii_strcasecmp(e->semantic_name, "SV_Target"))

View File

@ -1401,10 +1401,54 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu
desc->version = 0;
}
static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_signature *signature,
const struct shader_signature *src)
{
unsigned int i;
signature->element_count = src->element_count;
if (!src->elements)
{
assert(!signature->element_count);
signature->elements = NULL;
return true;
}
if (!(signature->elements = vkd3d_calloc(signature->element_count, sizeof(*signature->elements))))
return false;
for (i = 0; i < signature->element_count; ++i)
{
struct vkd3d_shader_signature_element *d = &signature->elements[i];
struct signature_element *e = &src->elements[i];
d->semantic_name = e->semantic_name;
d->semantic_index = e->semantic_index;
d->stream_index = e->stream_index;
d->sysval_semantic = e->sysval_semantic;
d->component_type = e->component_type;
d->register_index = e->register_index;
if (e->register_count > 1)
FIXME("Arrayed elements are not supported yet.\n");
d->mask = e->mask;
d->used_mask = e->used_mask;
d->min_precision = e->min_precision;
}
return true;
}
void shader_signature_cleanup(struct shader_signature *signature)
{
vkd3d_free(signature->elements);
signature->elements = NULL;
}
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature, char **messages)
{
struct vkd3d_shader_message_context message_context;
struct shader_signature shader_signature;
int ret;
TRACE("dxbc {%p, %zu}, signature %p, messages %p.\n", dxbc->code, dxbc->size, signature, messages);
@ -1413,13 +1457,17 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
*messages = NULL;
vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_INFO);
ret = shader_parse_input_signature(dxbc, &message_context, signature);
ret = shader_parse_input_signature(dxbc, &message_context, &shader_signature);
vkd3d_shader_message_context_trace_messages(&message_context);
if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&message_context);
if (!vkd3d_shader_signature_from_shader_signature(signature, &shader_signature))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
shader_signature_cleanup(&shader_signature);
return ret;
}

View File

@ -775,13 +775,35 @@ enum vkd3d_shader_input_sysval_semantic
VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22,
};
struct signature_element
{
const char *semantic_name;
unsigned int semantic_index;
unsigned int stream_index;
enum vkd3d_shader_sysval_semantic sysval_semantic;
enum vkd3d_shader_component_type component_type;
unsigned int register_index;
unsigned int register_count;
unsigned int mask;
unsigned int used_mask;
enum vkd3d_shader_minimum_precision min_precision;
};
struct shader_signature
{
struct signature_element *elements;
unsigned int element_count;
};
void shader_signature_cleanup(struct shader_signature *signature);
struct vkd3d_shader_desc
{
const uint32_t *byte_code;
size_t byte_code_size;
struct vkd3d_shader_signature input_signature;
struct vkd3d_shader_signature output_signature;
struct vkd3d_shader_signature patch_constant_signature;
struct shader_signature input_signature;
struct shader_signature output_signature;
struct shader_signature patch_constant_signature;
};
struct vkd3d_shader_register_semantic
@ -1136,7 +1158,7 @@ void free_shader_desc(struct vkd3d_shader_desc *desc);
int shader_extract_from_dxbc(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_desc *desc);
int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_signature *signature);
struct vkd3d_shader_message_context *message_context, struct shader_signature *signature);
struct vkd3d_glsl_generator;
@ -1350,7 +1372,7 @@ void shader_normaliser_init(struct vkd3d_shader_normaliser *normaliser,
struct vkd3d_shader_instruction_array *instructions);
enum vkd3d_result shader_normaliser_flatten_hull_shader_phases(struct vkd3d_shader_normaliser *normaliser);
enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser,
const struct vkd3d_shader_signature *input_signature);
const struct shader_signature *input_signature);
void shader_normaliser_destroy(struct vkd3d_shader_normaliser *normaliser);
#endif /* __VKD3D_SHADER_PRIVATE_H */