vkd3d-shader/hlsl: Parse function attributes.

This commit is contained in:
Zebediah Figura 2021-08-16 14:52:10 -05:00 committed by Alexandre Julliard
parent da56f41ceb
commit d6799bd5d3
Notes: Alexandre Julliard 2022-11-08 23:05:16 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Francisco Casas (@fcasas)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/43
7 changed files with 164 additions and 35 deletions

View File

@ -1180,7 +1180,7 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc
} }
struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, 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, struct vkd3d_shader_location loc) struct list *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc)
{ {
struct hlsl_ir_function_decl *decl; struct hlsl_ir_function_decl *decl;
@ -1189,11 +1189,11 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hl
list_init(&decl->body.instrs); list_init(&decl->body.instrs);
decl->return_type = return_type; decl->return_type = return_type;
decl->parameters = parameters; decl->parameters = parameters;
decl->loc = loc; decl->loc = *loc;
if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void))
{ {
if (!(decl->return_var = hlsl_new_synthetic_var(ctx, "retval", return_type, &loc))) if (!(decl->return_var = hlsl_new_synthetic_var(ctx, "retval", return_type, loc)))
{ {
vkd3d_free(decl); vkd3d_free(decl);
return NULL; return NULL;
@ -2086,8 +2086,25 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
} }
} }
void hlsl_free_attribute(struct hlsl_attribute *attr)
{
unsigned int i;
for (i = 0; i < attr->args_count; ++i)
hlsl_src_remove(&attr->args[i]);
hlsl_free_instr_list(&attr->instrs);
vkd3d_free((void *)attr->name);
vkd3d_free(attr);
}
static void free_function_decl(struct hlsl_ir_function_decl *decl) static void free_function_decl(struct hlsl_ir_function_decl *decl)
{ {
unsigned int i;
for (i = 0; i < decl->attr_count; ++i)
hlsl_free_attribute((void *)decl->attrs[i]);
vkd3d_free((void *)decl->attrs);
vkd3d_free(decl->parameters); vkd3d_free(decl->parameters);
hlsl_free_instr_list(&decl->body.instrs); hlsl_free_instr_list(&decl->body.instrs);
vkd3d_free(decl); vkd3d_free(decl);
@ -2135,6 +2152,7 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function
{ {
struct hlsl_ir_function_decl *old_decl = struct hlsl_ir_function_decl *old_decl =
RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry); RB_ENTRY_VALUE(old_entry, struct hlsl_ir_function_decl, entry);
unsigned int i;
if (!decl->has_body) if (!decl->has_body)
{ {
@ -2142,6 +2160,15 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function
vkd3d_free(name); vkd3d_free(name);
return; return;
} }
for (i = 0; i < decl->attr_count; ++i)
hlsl_free_attribute((void *)decl->attrs[i]);
vkd3d_free((void *)decl->attrs);
decl->attr_count = old_decl->attr_count;
decl->attrs = old_decl->attrs;
old_decl->attr_count = 0;
old_decl->attrs = NULL;
rb_remove(&func->overloads, old_entry); rb_remove(&func->overloads, old_entry);
free_function_decl(old_decl); free_function_decl(old_decl);
} }

View File

@ -212,6 +212,15 @@ struct hlsl_src
struct list entry; struct list entry;
}; };
struct hlsl_attribute
{
const char *name;
struct list instrs;
struct vkd3d_shader_location loc;
unsigned int args_count;
struct hlsl_src args[];
};
#define HLSL_STORAGE_EXTERN 0x00000001 #define HLSL_STORAGE_EXTERN 0x00000001
#define HLSL_STORAGE_NOINTERPOLATION 0x00000002 #define HLSL_STORAGE_NOINTERPOLATION 0x00000002
#define HLSL_MODIFIER_PRECISE 0x00000004 #define HLSL_MODIFIER_PRECISE 0x00000004
@ -279,6 +288,8 @@ struct hlsl_ir_function_decl
struct list *parameters; struct list *parameters;
struct hlsl_block body; struct hlsl_block body;
bool has_body; bool has_body;
unsigned int attr_count;
const struct hlsl_attribute *const *attrs;
}; };
struct hlsl_ir_if struct hlsl_ir_if
@ -741,6 +752,7 @@ void hlsl_cleanup_deref(struct hlsl_deref *deref);
void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new); void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
void hlsl_free_attribute(struct hlsl_attribute *attr);
void hlsl_free_instr(struct hlsl_ir_node *node); void hlsl_free_instr(struct hlsl_ir_node *node);
void hlsl_free_instr_list(struct list *list); void hlsl_free_instr_list(struct list *list);
void hlsl_free_type(struct hlsl_type *type); void hlsl_free_type(struct hlsl_type *type);
@ -771,7 +783,7 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op
struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx,
float f, const struct vkd3d_shader_location *loc); 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 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, struct vkd3d_shader_location loc); struct list *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_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, struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n,
const struct vkd3d_shader_location *loc); const struct vkd3d_shader_location *loc);

View File

@ -102,6 +102,12 @@ enum parse_assign_op
ASSIGN_OP_XOR, ASSIGN_OP_XOR,
}; };
struct parse_attribute_list
{
unsigned int count;
const struct hlsl_attribute **attrs;
};
} }
%code provides %code provides
@ -3036,6 +3042,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
struct hlsl_semantic semantic; struct hlsl_semantic semantic;
enum hlsl_buffer_type buffer_type; enum hlsl_buffer_type buffer_type;
enum hlsl_sampler_dim sampler_dim; enum hlsl_sampler_dim sampler_dim;
struct hlsl_attribute *attr;
struct parse_attribute_list attr_list;
} }
%token KW_BLENDSTATE %token KW_BLENDSTATE
@ -3185,6 +3193,10 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
%type <assign_op> assign_op %type <assign_op> assign_op
%type <attr> attribute
%type <attr_list> attribute_list
%type <boolval> boolean %type <boolval> boolean
%type <buffer_type> buffer_type %type <buffer_type> buffer_type
@ -3196,6 +3208,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
%type <function> func_declaration %type <function> func_declaration
%type <function> func_prototype %type <function> func_prototype
%type <function> func_prototype_no_attrs
%type <initializer> complex_initializer %type <initializer> complex_initializer
%type <initializer> complex_initializer_list %type <initializer> complex_initializer_list
@ -3435,6 +3448,68 @@ field:
YYABORT; YYABORT;
} }
attribute:
'[' any_identifier ']'
{
if (!($$ = hlsl_alloc(ctx, offsetof(struct hlsl_attribute, args[0]))))
{
vkd3d_free($2);
YYABORT;
}
$$->name = $2;
list_init(&$$->instrs);
$$->loc = @$;
$$->args_count = 0;
}
| '[' any_identifier '(' initializer_expr_list ')' ']'
{
unsigned int i;
if (!($$ = hlsl_alloc(ctx, offsetof(struct hlsl_attribute, args[$4.args_count]))))
{
vkd3d_free($2);
free_parse_initializer(&$4);
YYABORT;
}
$$->name = $2;
list_init(&$$->instrs);
list_move_tail(&$$->instrs, $4.instrs);
vkd3d_free($4.instrs);
$$->loc = @$;
$$->args_count = $4.args_count;
for (i = 0; i < $4.args_count; ++i)
hlsl_src_from_node(&$$->args[i], $4.args[i]);
}
attribute_list:
attribute
{
$$.count = 1;
if (!($$.attrs = hlsl_alloc(ctx, sizeof(*$$.attrs))))
{
hlsl_free_attribute($1);
YYABORT;
}
$$.attrs[0] = $1;
}
| attribute_list attribute
{
const struct hlsl_attribute **new_array;
$$ = $1;
if (!(new_array = vkd3d_realloc($$.attrs, ($$.count + 1) * sizeof(*$$.attrs))))
{
unsigned int i;
for (i = 0; i < $$.count; ++i)
hlsl_free_attribute((void *)$$.attrs[i]);
vkd3d_free($$.attrs);
YYABORT;
}
$$.attrs = new_array;
$$.attrs[$$.count++] = $2;
}
func_declaration: func_declaration:
func_prototype compound_statement func_prototype compound_statement
{ {
@ -3450,7 +3525,7 @@ func_declaration:
hlsl_pop_scope(ctx); hlsl_pop_scope(ctx);
} }
func_prototype: func_prototype_no_attrs:
/* var_modifiers is necessary to avoid shift/reduce conflicts. */ /* var_modifiers is necessary to avoid shift/reduce conflicts. */
var_modifiers type var_identifier '(' parameters ')' colon_attribute var_modifiers type var_identifier '(' parameters ')' colon_attribute
{ {
@ -3483,12 +3558,21 @@ func_prototype:
if ($7.reg_reservation.type) if ($7.reg_reservation.type)
FIXME("Unexpected register reservation for a function.\n"); 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; YYABORT;
$$.name = $3; $$.name = $3;
ctx->cur_function = $$.decl; ctx->cur_function = $$.decl;
} }
func_prototype:
func_prototype_no_attrs
| attribute_list func_prototype_no_attrs
{
$2.decl->attr_count = $1.count;
$2.decl->attrs = $1.attrs;
$$ = $2;
}
compound_statement: compound_statement:
'{' '}' '{' '}'
{ {

View File

@ -2539,6 +2539,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
{ {
struct hlsl_block *const body = &entry_func->body; struct hlsl_block *const body = &entry_func->body;
struct hlsl_ir_var *var; struct hlsl_ir_var *var;
unsigned int i;
bool progress; bool progress;
list_move_head(&body->instrs, &ctx->static_initializers); list_move_head(&body->instrs, &ctx->static_initializers);
@ -2576,6 +2577,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
append_output_var_copy(ctx, &body->instrs, entry_func->return_var); append_output_var_copy(ctx, &body->instrs, entry_func->return_var);
} }
for (i = 0; i < entry_func->attr_count; ++i)
hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE,
"Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name);
transform_ir(ctx, lower_broadcasts, body, NULL); transform_ir(ctx, lower_broadcasts, body, NULL);
while (transform_ir(ctx, fold_redundant_casts, body, NULL)); while (transform_ir(ctx, fold_redundant_casts, body, NULL));
do do

View File

@ -122,6 +122,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE = 5302,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,

View File

@ -2,17 +2,17 @@
% we need to get the parsing syntax right. Most of the following tests which % we need to get the parsing syntax right. Most of the following tests which
% succeed print warnings. % succeed print warnings.
[pixel shader todo] [pixel shader]
[numthreads] [numthreads]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[ numthreads ] [ numthreads ]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[numthreads(1)] [numthreads(1)]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
@ -55,12 +55,12 @@ float4 main() : sv_target { return 0; }
[numthreads(float2(1))] [numthreads(float2(1))]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[not_a_real_attribute_name] [not_a_real_attribute_name]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
uniform float4 f; uniform float4 f;
@ -72,27 +72,27 @@ float4 main() : sv_target { return 0; }
[one, two] [one, two]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[one][two] [one][two]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader fail] [pixel shader fail todo]
[one][one] [one][one]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader fail] [pixel shader fail todo]
[one][one(1)] [one][one(1)]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[one][One] [one][One]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
[numthreads] [numthreads]
float4 main(); float4 main();
@ -100,7 +100,7 @@ float4 main();
[numthreads] [numthreads]
float4 main() : sv_target { return 0; } float4 main() : sv_target { return 0; }
[pixel shader todo] [pixel shader]
/* Expressions with side effects are forbidden in attributes—see /* Expressions with side effects are forbidden in attributes—see
* hlsl-numthreads.shader_test for an example—but not if the attribute is * hlsl-numthreads.shader_test for an example—but not if the attribute is

View File

@ -8,52 +8,52 @@ shader model >= 5.0
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads] [numthreads]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, 1)] [numthreads(1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, 1, 1, 1)] [numthreads(1, 1, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(0, 1, 1)] [numthreads(0, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, 0, 1)] [numthreads(1, 0, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, 1, 0)] [numthreads(1, 1, 0)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(-1, 1, 1)] [numthreads(-1, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, -1, 1)] [numthreads(1, -1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, 1, -1)] [numthreads(1, 1, -1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(1, -1, -1)] [numthreads(1, -1, -1)]
void main() {} void main() {}
@ -68,12 +68,12 @@ void main() {}
[numthreads(int(1), 1, 1)] [numthreads(int(1), 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(float(1), 1, 1)] [numthreads(float(1), 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[numthreads(uint1(1), 1, 1)] [numthreads(uint1(1), 1, 1)]
void main() {} void main() {}
@ -103,7 +103,7 @@ void main() {}
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
[NumThreads(1, 1, 1)] [NumThreads(1, 1, 1)]
void main() {} void main() {}
@ -115,21 +115,21 @@ void main();
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
void main() {} void main() {}
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void main(); void main();
[compute shader fail] [compute shader fail todo]
void main(); void main();
[numthreads(1, 1, 1)] [numthreads(1, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
/* Expressions with side effects are forbidden in attributes (but not if the /* Expressions with side effects are forbidden in attributes (but not if the
* attribute is ignored). */ * attribute is ignored). */
@ -139,14 +139,14 @@ static int x = 1;
[numthreads(x++, 1, 1)] [numthreads(x++, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
static int x = 1; static int x = 1;
[numthreads(++x, 1, 1)] [numthreads(++x, 1, 1)]
void main() {} void main() {}
[compute shader fail] [compute shader fail todo]
static int x = 1; static int x = 1;