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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
|
static void check_invalid_in_out_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers,
|
||||||
unsigned int modifiers, const struct vkd3d_shader_location *modifiers_loc, struct list *var_list)
|
const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
struct parse_variable_def *v, *v_next;
|
modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT);
|
||||||
struct hlsl_ir_function_decl *func;
|
if (modifiers)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
struct vkd3d_string_buffer *string;
|
struct vkd3d_string_buffer *string;
|
||||||
|
|
||||||
if ((string = hlsl_modifiers_to_string(ctx, invalid_modifiers)))
|
if ((string = hlsl_modifiers_to_string(ctx, modifiers)))
|
||||||
hlsl_error(ctx, modifiers_loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
||||||
"Modifiers '%s' are not allowed on non-parameter variables.", string->buffer);
|
"Modifiers '%s' are not allowed on non-parameter variables.", string->buffer);
|
||||||
hlsl_release_string_buffer(ctx, string);
|
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;
|
bool unbounded_res_array = false;
|
||||||
|
struct hlsl_ir_var *var;
|
||||||
|
struct hlsl_type *type;
|
||||||
|
bool local = true;
|
||||||
|
char *var_name;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
assert(basic_type);
|
||||||
|
|
||||||
|
if (basic_type->class == HLSL_CLASS_MATRIX)
|
||||||
|
assert(basic_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
|
||||||
|
|
||||||
type = basic_type;
|
type = basic_type;
|
||||||
|
|
||||||
if (shader_is_sm_5_1(ctx) && type->class == HLSL_CLASS_OBJECT)
|
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)
|
if (v->arrays.count == 1)
|
||||||
{
|
{
|
||||||
hlsl_fixme(ctx, &v->loc, "Unbounded resource arrays.");
|
hlsl_fixme(ctx, &v->loc, "Unbounded resource arrays.");
|
||||||
free_parse_variable_def(v);
|
return;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
else
|
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,
|
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
"Only innermost array size can be implicit.");
|
"Only innermost array size can be implicit.");
|
||||||
free_parse_initializer(&v->initializer);
|
|
||||||
v->initializer.args_count = 0;
|
v->initializer.args_count = 0;
|
||||||
}
|
}
|
||||||
else if (elem_components == 0)
|
else if (elem_components == 0)
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
"Cannot declare an implicit size array of a size 0 type.");
|
"Cannot declare an implicit size array of a size 0 type.");
|
||||||
free_parse_initializer(&v->initializer);
|
|
||||||
v->initializer.args_count = 0;
|
v->initializer.args_count = 0;
|
||||||
}
|
}
|
||||||
else if (size == 0)
|
else if (size == 0)
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
|
||||||
"Implicit size arrays need to be initialized.");
|
"Implicit size arrays need to be initialized.");
|
||||||
free_parse_initializer(&v->initializer);
|
|
||||||
v->initializer.args_count = 0;
|
v->initializer.args_count = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (size % elem_components != 0)
|
else if (size % elem_components != 0)
|
||||||
{
|
{
|
||||||
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
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.",
|
"Cannot initialize implicit size array with %u components, expected a multiple of %u.",
|
||||||
size, elem_components);
|
size, elem_components);
|
||||||
free_parse_initializer(&v->initializer);
|
|
||||||
v->initializer.args_count = 0;
|
v->initializer.args_count = 0;
|
||||||
}
|
}
|
||||||
else
|
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]);
|
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);
|
if (!(new_semantic.name = vkd3d_strdup(v->semantic.name)))
|
||||||
continue;
|
{
|
||||||
|
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;
|
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,
|
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER,
|
||||||
"Const variable \"%s\" is missing an initializer.", var->name);
|
"Const variable \"%s\" is missing an initializer.", var->name);
|
||||||
hlsl_free_var(var);
|
hlsl_free_var(var);
|
||||||
free_parse_initializer(&v->initializer);
|
return;
|
||||||
vkd3d_free(v);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hlsl_add_var(ctx, var, local))
|
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);
|
"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_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name);
|
||||||
hlsl_free_var(var);
|
hlsl_free_var(var);
|
||||||
free_parse_initializer(&v->initializer);
|
return;
|
||||||
vkd3d_free(v);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
type = var->data_type;
|
||||||
|
|
||||||
if (v->initializer.args_count)
|
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,
|
hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
|
||||||
"Expected %u components in initializer, but got %u.",
|
"Expected %u components in initializer, but got %u.",
|
||||||
hlsl_type_component_count(type), size);
|
hlsl_type_component_count(type), size);
|
||||||
free_parse_initializer(&v->initializer);
|
free_parse_variable_def(v);
|
||||||
vkd3d_free(v);
|
|
||||||
continue;
|
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]);
|
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);
|
hlsl_block_add_block(&ctx->static_initializers, v->initializer.instrs);
|
||||||
else
|
else
|
||||||
list_move_tail(statements_list, &v->initializer.instrs->instrs);
|
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)
|
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))
|
if (type_has_object_components(var->data_type, false))
|
||||||
{
|
{
|
||||||
vkd3d_free(v);
|
free_parse_variable_def(v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(zero = hlsl_new_uint_constant(ctx, 0, &var->loc)))
|
if (!(zero = hlsl_new_uint_constant(ctx, 0, &var->loc)))
|
||||||
{
|
{
|
||||||
vkd3d_free(v);
|
free_parse_variable_def(v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hlsl_block_add_instr(&ctx->static_initializers, zero);
|
hlsl_block_add_instr(&ctx->static_initializers, zero);
|
||||||
|
|
||||||
if (!(cast = add_cast(ctx, &ctx->static_initializers.instrs, zero, var->data_type, &var->loc)))
|
if (!(cast = add_cast(ctx, &ctx->static_initializers.instrs, zero, var->data_type, &var->loc)))
|
||||||
{
|
{
|
||||||
vkd3d_free(v);
|
free_parse_variable_def(v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(store = hlsl_new_simple_store(ctx, var, cast)))
|
if (!(store = hlsl_new_simple_store(ctx, var, cast)))
|
||||||
{
|
{
|
||||||
vkd3d_free(v);
|
free_parse_variable_def(v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
hlsl_block_add_instr(&ctx->static_initializers, store);
|
hlsl_block_add_instr(&ctx->static_initializers, store);
|
||||||
}
|
}
|
||||||
vkd3d_free(v);
|
free_parse_variable_def(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
vkd3d_free(var_list);
|
vkd3d_free(var_list);
|
||||||
return statements_list;
|
return statements_list;
|
||||||
}
|
}
|
||||||
@ -4667,6 +4687,7 @@ preproc_directive:
|
|||||||
struct_declaration:
|
struct_declaration:
|
||||||
var_modifiers struct_spec variables_def_optional ';'
|
var_modifiers struct_spec variables_def_optional ';'
|
||||||
{
|
{
|
||||||
|
struct parse_variable_def *v, *v_next;
|
||||||
struct hlsl_type *type;
|
struct hlsl_type *type;
|
||||||
unsigned int modifiers = $1;
|
unsigned int modifiers = $1;
|
||||||
|
|
||||||
@ -4682,7 +4703,24 @@ struct_declaration:
|
|||||||
|
|
||||||
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
||||||
YYABORT;
|
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:
|
struct_spec:
|
||||||
@ -5526,12 +5564,22 @@ type_spec:
|
|||||||
declaration:
|
declaration:
|
||||||
var_modifiers type variables_def ';'
|
var_modifiers type variables_def ';'
|
||||||
{
|
{
|
||||||
|
struct parse_variable_def *v, *v_next;
|
||||||
struct hlsl_type *type;
|
struct hlsl_type *type;
|
||||||
unsigned int modifiers = $1;
|
unsigned int modifiers = $1;
|
||||||
|
|
||||||
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1)))
|
||||||
YYABORT;
|
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:
|
variables_def_optional:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user