mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Split declare_vars().
Basically, declare_vars() is separated in three functions: 1. check_invalid_in_out_modifiers(), which is to be called once per declaration and emits an error when in or out modifiers are used for these non-parameter variables. 2. declare_var(), which now handles one variable at the time and doesn't free any memory. 3. initialize_vars(), which takes care of preparing the initialization instructions of several variables and frees their struct parse_variable_def, using exclusively free_parse_variable_def(). This allows to declare variables individually before the initializer of the next variable in the same declaration is parsed, which is used in the following patches. Also, simplifies memory management.
This commit is contained in:
parent
396edae281
commit
a34cf2e64e
Notes:
Alexandre Julliard
2023-07-04 23:25:04 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/250
@ -1949,47 +1949,38 @@ static bool type_has_numeric_components(struct hlsl_type *type)
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
|
||||
unsigned int modifiers, const struct vkd3d_shader_location *modifiers_loc, struct list *var_list)
|
||||
static void check_invalid_in_out_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct parse_variable_def *v, *v_next;
|
||||
struct hlsl_ir_function_decl *func;
|
||||
unsigned int invalid_modifiers;
|
||||
struct list *statements_list;
|
||||
struct hlsl_ir_var *var;
|
||||
struct hlsl_type *type;
|
||||
bool local = true;
|
||||
|
||||
if (basic_type->class == HLSL_CLASS_MATRIX)
|
||||
assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
|
||||
if (!(statements_list = make_empty_list(ctx)))
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
|
||||
free_parse_variable_def(v);
|
||||
vkd3d_free(var_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!var_list)
|
||||
return statements_list;
|
||||
|
||||
invalid_modifiers = modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT);
|
||||
if (invalid_modifiers)
|
||||
modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT);
|
||||
if (modifiers)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
|
||||
if ((string = hlsl_modifiers_to_string(ctx, invalid_modifiers)))
|
||||
hlsl_error(ctx, modifiers_loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
||||
if ((string = hlsl_modifiers_to_string(ctx, modifiers)))
|
||||
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
||||
"Modifiers '%s' are not allowed on non-parameter variables.", string->buffer);
|
||||
hlsl_release_string_buffer(ctx, string);
|
||||
}
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
|
||||
{
|
||||
static void declare_var(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
|
||||
unsigned int modifiers, const struct vkd3d_shader_location *modifiers_loc, struct parse_variable_def *v)
|
||||
{
|
||||
struct hlsl_ir_function_decl *func;
|
||||
struct hlsl_semantic new_semantic;
|
||||
bool unbounded_res_array = false;
|
||||
struct hlsl_ir_var *var;
|
||||
struct hlsl_type *type;
|
||||
bool local = true;
|
||||
char *var_name;
|
||||
unsigned int i;
|
||||
|
||||
assert(basic_type);
|
||||
|
||||
if (basic_type->class == HLSL_CLASS_MATRIX)
|
||||
assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||
|
||||
type = basic_type;
|
||||
|
||||
if (shader_is_sm_5_1(ctx) && type->class == HLSL_CLASS_OBJECT)
|
||||
@ -2003,8 +1994,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
if (v->arrays.count == 1)
|
||||
{
|
||||
hlsl_fixme(ctx, &v->loc, "Unbounded resource arrays.");
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2025,30 +2015,25 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
{
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Only innermost array size can be implicit.");
|
||||
free_parse_initializer(&v->initializer);
|
||||
v->initializer.args_count = 0;
|
||||
}
|
||||
else if (elem_components == 0)
|
||||
{
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Cannot declare an implicit size array of a size 0 type.");
|
||||
free_parse_initializer(&v->initializer);
|
||||
v->initializer.args_count = 0;
|
||||
}
|
||||
else if (size == 0)
|
||||
{
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||
"Implicit size arrays need to be initialized.");
|
||||
free_parse_initializer(&v->initializer);
|
||||
v->initializer.args_count = 0;
|
||||
|
||||
}
|
||||
else if (size % elem_components != 0)
|
||||
{
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||
"Cannot initialize implicit size array with %u components, expected a multiple of %u.",
|
||||
size, elem_components);
|
||||
free_parse_initializer(&v->initializer);
|
||||
v->initializer.args_count = 0;
|
||||
}
|
||||
else
|
||||
@ -2059,12 +2044,25 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]);
|
||||
}
|
||||
}
|
||||
vkd3d_free(v->arrays.sizes);
|
||||
|
||||
if (!(var = hlsl_new_var(ctx, v->name, type, &v->loc, &v->semantic, modifiers, &v->reg_reservation)))
|
||||
if (!(var_name = vkd3d_strdup(v->name)))
|
||||
return;
|
||||
|
||||
new_semantic = v->semantic;
|
||||
if (v->semantic.name)
|
||||
{
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
if (!(new_semantic.name = vkd3d_strdup(v->semantic.name)))
|
||||
{
|
||||
vkd3d_free(var_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(var = hlsl_new_var(ctx, var_name, type, &v->loc, &new_semantic, modifiers, &v->reg_reservation)))
|
||||
{
|
||||
hlsl_cleanup_semantic(&new_semantic);
|
||||
vkd3d_free(var_name);
|
||||
return;
|
||||
}
|
||||
|
||||
var->buffer = ctx->cur_buffer;
|
||||
@ -2137,9 +2135,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER,
|
||||
"Const variable \"%s\" is missing an initializer.", var->name);
|
||||
hlsl_free_var(var);
|
||||
free_parse_initializer(&v->initializer);
|
||||
vkd3d_free(v);
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hlsl_add_var(ctx, var, local))
|
||||
@ -2150,10 +2146,36 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
"Variable \"%s\" was already declared in this scope.", var->name);
|
||||
hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
|
||||
hlsl_free_var(var);
|
||||
free_parse_initializer(&v->initializer);
|
||||
vkd3d_free(v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
||||
{
|
||||
struct parse_variable_def *v, *v_next;
|
||||
struct list *statements_list;
|
||||
struct hlsl_ir_var *var;
|
||||
struct hlsl_type *type;
|
||||
|
||||
if (!(statements_list = make_empty_list(ctx)))
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
|
||||
{
|
||||
free_parse_variable_def(v);
|
||||
}
|
||||
vkd3d_free(var_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
|
||||
{
|
||||
/* If this fails, the variable failed to be declared. */
|
||||
if (!(var = hlsl_get_var(ctx->cur_scope, v->name)))
|
||||
{
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
type = var->data_type;
|
||||
|
||||
if (v->initializer.args_count)
|
||||
{
|
||||
@ -2168,8 +2190,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||
"Expected %u components in initializer, but got %u.",
|
||||
hlsl_type_component_count(type), size);
|
||||
free_parse_initializer(&v->initializer);
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2188,12 +2209,10 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
add_assignment(ctx, block_to_list(v->initializer.instrs), &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]);
|
||||
}
|
||||
|
||||
if (modifiers & HLSL_STORAGE_STATIC)
|
||||
if (var->storage_modifiers & HLSL_STORAGE_STATIC)
|
||||
hlsl_block_add_block(&ctx->static_initializers, v->initializer.instrs);
|
||||
else
|
||||
list_move_tail(statements_list, &v->initializer.instrs->instrs);
|
||||
vkd3d_free(v->initializer.args);
|
||||
vkd3d_free(v->initializer.instrs);
|
||||
}
|
||||
else if (var->storage_modifiers & HLSL_STORAGE_STATIC)
|
||||
{
|
||||
@ -2203,32 +2222,33 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
|
||||
|
||||
if (type_has_object_components(var->data_type, false))
|
||||
{
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(zero = hlsl_new_uint_constant(ctx, 0, &var->loc)))
|
||||
{
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
hlsl_block_add_instr(&ctx->static_initializers, zero);
|
||||
|
||||
if (!(cast = add_cast(ctx, &ctx->static_initializers.instrs, zero, var->data_type, &var->loc)))
|
||||
{
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, var, cast)))
|
||||
{
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
continue;
|
||||
}
|
||||
hlsl_block_add_instr(&ctx->static_initializers, store);
|
||||
}
|
||||
vkd3d_free(v);
|
||||
free_parse_variable_def(v);
|
||||
}
|
||||
|
||||
vkd3d_free(var_list);
|
||||
return statements_list;
|
||||
}
|
||||
@ -4667,6 +4687,7 @@ preproc_directive:
|
||||
struct_declaration:
|
||||
var_modifiers struct_spec variables_def_optional ';'
|
||||
{
|
||||
struct parse_variable_def *v, *v_next;
|
||||
struct hlsl_type *type;
|
||||
unsigned int modifiers = $1;
|
||||
|
||||
@ -4682,7 +4703,24 @@ struct_declaration:
|
||||
|
||||
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
||||
YYABORT;
|
||||
$$ = declare_vars(ctx, type, modifiers, &@1, $3);
|
||||
|
||||
check_invalid_in_out_modifiers(ctx, modifiers, &@1);
|
||||
|
||||
if ($3)
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
|
||||
{
|
||||
declare_var(ctx, type, modifiers, &@1, v);
|
||||
}
|
||||
|
||||
if (!($$ = initialize_vars(ctx, $3)))
|
||||
YYABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($$ = make_empty_list(ctx)))
|
||||
YYABORT;
|
||||
}
|
||||
}
|
||||
|
||||
struct_spec:
|
||||
@ -5526,12 +5564,22 @@ type_spec:
|
||||
declaration:
|
||||
var_modifiers type variables_def ';'
|
||||
{
|
||||
struct parse_variable_def *v, *v_next;
|
||||
struct hlsl_type *type;
|
||||
unsigned int modifiers = $1;
|
||||
|
||||
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
||||
YYABORT;
|
||||
$$ = declare_vars(ctx, type, modifiers, &@1, $3);
|
||||
|
||||
check_invalid_in_out_modifiers(ctx, modifiers, &@1);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $3, struct parse_variable_def, entry)
|
||||
{
|
||||
declare_var(ctx, type, modifiers, &@1, v);
|
||||
}
|
||||
|
||||
if (!($$ = initialize_vars(ctx, $3)))
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
variables_def_optional:
|
||||
|
Loading…
x
Reference in New Issue
Block a user