From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 50 ++++++++++++-------------- libs/vkd3d-shader/hlsl.h | 19 ++++++---- libs/vkd3d-shader/hlsl.y | 62 +++++++++++++++++--------------- libs/vkd3d-shader/hlsl_codegen.c | 4 ++- 4 files changed, 70 insertions(+), 65 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 256e466a..f62057b8 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1200,8 +1200,9 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc return loop; }
-struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) +struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) { struct hlsl_ir_function_decl *decl;
@@ -1209,7 +1210,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl return NULL; list_init(&decl->body.instrs); decl->return_type = return_type; - decl->parameters = parameters; + decl->parameters = *parameters; decl->loc = *loc;
if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) @@ -1336,27 +1337,18 @@ static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hls
static int compare_function_decl_rb(const void *key, const struct rb_entry *entry) { - const struct list *params = key; const struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, const struct hlsl_ir_function_decl, entry); - int decl_params_count = decl->parameters ? list_count(decl->parameters) : 0; - int params_count = params ? list_count(params) : 0; - struct list *p1cur, *p2cur; + const struct hlsl_func_parameters *parameters = key; + size_t i; int r;
- if ((r = vkd3d_u32_compare(params_count, decl_params_count))) + if ((r = vkd3d_u32_compare(parameters->count, decl->parameters.count))) return r;
- p1cur = params ? list_head(params) : NULL; - p2cur = decl->parameters ? list_head(decl->parameters) : NULL; - while (p1cur && p2cur) + for (i = 0; i < parameters->count; ++i) { - struct hlsl_ir_var *p1, *p2; - p1 = LIST_ENTRY(p1cur, struct hlsl_ir_var, param_entry); - p2 = LIST_ENTRY(p2cur, struct hlsl_ir_var, param_entry); - if ((r = compare_param_hlsl_types(p1->data_type, p2->data_type))) + if ((r = compare_param_hlsl_types(parameters->vars[i]->data_type, decl->parameters.vars[i]->data_type))) return r; - p1cur = list_next(params, p1cur); - p2cur = list_next(decl->parameters, p2cur); } return 0; } @@ -1655,7 +1647,7 @@ static void dump_ir_call(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffe { const struct hlsl_ir_function_decl *decl = call->decl; struct vkd3d_string_buffer *string; - const struct hlsl_ir_var *param; + size_t i;
if (!(string = hlsl_type_to_string(ctx, decl->return_type))) return; @@ -1663,14 +1655,16 @@ static void dump_ir_call(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffe vkd3d_string_buffer_printf(buffer, "call %s %s(", string->buffer, decl->func->name); hlsl_release_string_buffer(ctx, string);
- LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < decl->parameters.count; ++i) { + const struct hlsl_ir_var *param = decl->parameters.vars[i]; + if (!(string = hlsl_type_to_string(ctx, param->data_type))) return;
- vkd3d_string_buffer_printf(buffer, "%s", string->buffer); - if (list_tail(decl->parameters) != ¶m->param_entry) + if (i) vkd3d_string_buffer_printf(buffer, ", "); + vkd3d_string_buffer_printf(buffer, "%s", string->buffer);
hlsl_release_string_buffer(ctx, string); } @@ -1959,14 +1953,14 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func) { struct vkd3d_string_buffer buffer; - struct hlsl_ir_var *param; + size_t i;
vkd3d_string_buffer_init(&buffer); vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name); vkd3d_string_buffer_printf(&buffer, "Function parameters:\n"); - LIST_FOR_EACH_ENTRY(param, func->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < func->parameters.count; ++i) { - dump_ir_var(ctx, &buffer, param); + dump_ir_var(ctx, &buffer, func->parameters.vars[i]); vkd3d_string_buffer_printf(&buffer, "\n"); } if (func->has_body) @@ -2168,7 +2162,7 @@ static void free_function_decl(struct hlsl_ir_function_decl *decl) hlsl_free_attribute((void *)decl->attrs[i]); vkd3d_free((void *)decl->attrs);
- vkd3d_free(decl->parameters); + vkd3d_free(decl->parameters.vars); hlsl_free_instr_list(&decl->body.instrs); vkd3d_free(decl); } @@ -2200,7 +2194,7 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function { func = RB_ENTRY_VALUE(func_entry, struct hlsl_ir_function, entry); decl->func = func; - if ((old_entry = rb_get(&func->overloads, decl->parameters))) + if ((old_entry = rb_get(&func->overloads, &decl->parameters))) { struct hlsl_ir_function_decl *old_decl = RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry); @@ -2224,7 +2218,7 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function rb_remove(&func->overloads, old_entry); free_function_decl(old_decl); } - rb_put(&func->overloads, decl->parameters, &decl->entry); + rb_put(&func->overloads, &decl->parameters, &decl->entry); vkd3d_free(name); return; } @@ -2232,7 +2226,7 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function func->name = name; rb_init(&func->overloads, compare_function_decl_rb); decl->func = func; - rb_put(&func->overloads, decl->parameters, &decl->entry); + rb_put(&func->overloads, &decl->parameters, &decl->entry); rb_put(&ctx->functions, func->name, &func->entry); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index bb63f827..a3fd1309 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -360,8 +360,6 @@ struct hlsl_ir_var
/* Item entry in hlsl_scope.vars. Specifically hlsl_ctx.globals.vars if the variable is global. */ struct list scope_entry; - /* Item entry in hlsl_ir_function_decl.parameters, if the variable is a function parameter. */ - struct list param_entry; /* Item entry in hlsl_ctx.extern_vars, if the variable is extern. */ struct list extern_entry;
@@ -392,6 +390,13 @@ struct hlsl_ir_var uint32_t is_param : 1; };
+/* Sized array of variables representing a function's parameters. */ +struct hlsl_func_parameters +{ + struct hlsl_ir_var **vars; + size_t count, capacity; +}; + struct hlsl_ir_function { /* Item entry in hlsl_ctx.functions */ @@ -415,9 +420,8 @@ struct hlsl_ir_function_decl
/* Function to which this declaration corresponds. */ struct hlsl_ir_function *func; - /* List containing one variable for each parameter of the function; linked by the - * hlsl_ir_var.param_entry fields. */ - struct list *parameters; + + struct hlsl_func_parameters parameters;
struct hlsl_block body; bool has_body; @@ -1005,8 +1009,9 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, const struct vkd3d_shader_location *loc); -struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, - struct list *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc); +struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, + struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, + const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc); struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc); struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n, const struct vkd3d_shader_location *loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index a4de0edd..00af3f46 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1067,7 +1067,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, DWORD modifiers, struct hlsl_type return true; }
-static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, +static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters, struct parse_parameter *param, const struct vkd3d_shader_location loc) { struct hlsl_ir_var *var; @@ -1088,7 +1088,11 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list, hlsl_free_var(var); return false; } - list_add_tail(list, &var->param_entry); + + if (!hlsl_array_reserve(ctx, (void **)¶meters->vars, ¶meters->capacity, + parameters->count + 1, sizeof(*parameters->vars))) + return false; + parameters->vars[parameters->count++] = var; return true; }
@@ -1105,7 +1109,8 @@ static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string) return reservation; }
-static const struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs, char *name, struct list *params) +static const struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs, + const char *name, const struct hlsl_func_parameters *parameters) { struct hlsl_ir_function *func; struct rb_entry *entry; @@ -1114,7 +1119,7 @@ static const struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs, { func = RB_ENTRY_VALUE(entry, struct hlsl_ir_function, entry);
- if ((entry = rb_get(&func->overloads, params))) + if ((entry = rb_get(&func->overloads, parameters))) return RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); } return NULL; @@ -2224,17 +2229,17 @@ static void find_function_call_exact(struct rb_entry *entry, void *context) { struct hlsl_ir_function_decl *decl = RB_ENTRY_VALUE(entry, struct hlsl_ir_function_decl, entry); struct find_function_call_args *args = context; - const struct hlsl_ir_var *param; - unsigned int i = 0; + unsigned int i;
- LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry) + if (decl->parameters.count != args->params->args_count) + return; + + for (i = 0; i < decl->parameters.count; ++i) { - if (i >= args->params->args_count - || !hlsl_types_are_equal(param->data_type, args->params->args[i++]->data_type)) + if (!hlsl_types_are_equal(decl->parameters.vars[i]->data_type, args->params->args[i]->data_type)) return; } - if (i == args->params->args_count) - args->decl = decl; + args->decl = decl; }
static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, @@ -3000,15 +3005,14 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, if ((decl = find_function_call(ctx, name, args))) { struct hlsl_ir_node *call; - struct hlsl_ir_var *param; unsigned int i;
- assert(args->args_count == list_count(decl->parameters)); + assert(args->args_count == decl->parameters.count);
- i = 0; - LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < decl->parameters.count; ++i) { - struct hlsl_ir_node *arg = args->args[i++]; + struct hlsl_ir_var *param = decl->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i];
if (!hlsl_types_are_equal(arg->data_type, param->data_type)) { @@ -3030,10 +3034,10 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, goto fail; list_add_tail(args->instrs, &call->entry);
- i = 0; - LIST_FOR_EACH_ENTRY(param, decl->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < decl->parameters.count; ++i) { - struct hlsl_ir_node *arg = args->args[i++]; + struct hlsl_ir_var *param = decl->parameters.vars[i]; + struct hlsl_ir_node *arg = args->args[i];
if (param->storage_modifiers & HLSL_STORAGE_OUT) { @@ -3510,6 +3514,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl struct parse_fields fields; struct parse_function function; struct parse_parameter parameter; + struct hlsl_func_parameters parameters; struct parse_initializer initializer; struct parse_array_sizes arrays; struct parse_variable_def *variable_def; @@ -3647,8 +3652,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl %type <list> logicor_expr %type <list> loop_statement %type <list> mul_expr -%type <list> param_list -%type <list> parameters %type <list> postfix_expr %type <list> primary_expr %type <list> relational_expr @@ -3702,6 +3705,9 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
%type <parameter> parameter
+%type <parameters> param_list +%type <parameters> parameters + %type <reg_reservation> register_opt
%type <sampler_dim> texture_type uav_type @@ -3727,7 +3733,7 @@ hlsl_prog: { const struct hlsl_ir_function_decl *decl;
- decl = get_func_decl(&ctx->functions, $2.name, $2.decl->parameters); + decl = get_func_decl(&ctx->functions, $2.name, &$2.decl->parameters); if (decl) { if (decl->has_body && $2.decl->has_body) @@ -4032,7 +4038,7 @@ func_prototype_no_attrs: if ($7.reg_reservation.type) FIXME("Unexpected register reservation for a function.\n");
- if (!($$.decl = hlsl_new_func_decl(ctx, type, $5, &$7.semantic, &@3))) + if (!($$.decl = hlsl_new_func_decl(ctx, type, &$5, &$7.semantic, &@3))) YYABORT; $$.name = $3; ctx->cur_function = $$.decl; @@ -4117,8 +4123,7 @@ register_opt: parameters: scope_start { - if (!($$ = make_empty_list(ctx))) - YYABORT; + memset(&$$, 0, sizeof($$)); } | scope_start param_list { @@ -4128,9 +4133,8 @@ parameters: param_list: parameter { - if (!($$ = make_empty_list(ctx))) - YYABORT; - if (!add_func_parameter(ctx, $$, &$1, @1)) + memset(&$$, 0, sizeof($$)); + if (!add_func_parameter(ctx, &$$, &$1, @1)) { ERR("Error adding function parameter %s.\n", $1.name); YYABORT; @@ -4139,7 +4143,7 @@ param_list: | param_list ',' parameter { $$ = $1; - if (!add_func_parameter(ctx, $$, &$3, @3)) + if (!add_func_parameter(ctx, &$$, &$3, @3)) { hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "Parameter "%s" is already declared.", $3.name); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 4fa860a6..f6f096f1 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2877,8 +2877,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry prepend_uniform_copy(ctx, &body->instrs, var); }
- LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) + for (i = 0; i < entry_func->parameters.count; ++i) { + var = entry_func->parameters.vars[i]; + if (var->data_type->type == HLSL_CLASS_OBJECT || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) { prepend_uniform_copy(ctx, &body->instrs, var);