diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 75f10a18..14ff9c4e 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -1290,6 +1290,9 @@ static bool state_block_contains_state(const char *name, unsigned int start, str for (i = start; i < block->count; ++i) { + if (block->entries[i]->is_function_call) + continue; + if (!ascii_strcasecmp(block->entries[i]->name, name)) return true; } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index fdd013dd..65e5ab17 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -507,22 +507,31 @@ struct hlsl_ir_var * name[lhs_index] = args[0] * - or - * name[lhs_index] = {args[0], args[1], ...}; + * + * This struct also represents function call syntax: + * name(args[0], args[1], ...) */ struct hlsl_state_block_entry { - /* For assignments, the name in the lhs. */ + /* Whether this entry is a function call. */ + bool is_function_call; + + /* For assignments, the name in the lhs. + * For functions, the name of the function. */ char *name; /* Resolved format-specific property identifier. */ unsigned int name_id; - /* Whether the lhs in the assignment is indexed and, in that case, its index. */ + /* For assignments, whether the lhs of an assignment is indexed and, in + * that case, its index. */ bool lhs_has_index; unsigned int lhs_index; - /* Instructions present in the rhs. */ + /* Instructions present in the rhs or the function arguments. */ struct hlsl_block *instrs; - /* For assignments, arguments of the rhs initializer. */ + /* For assignments, arguments of the rhs initializer. + * For function calls, the arguments themselves. */ struct hlsl_src *args; unsigned int args_count; }; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ba617346..7cba28cd 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -7379,6 +7379,32 @@ state_block: hlsl_src_from_node(&entry->args[i], $5.args[i]); vkd3d_free($5.args); + $$ = $1; + state_block_add_entry($$, entry); + } + | state_block any_identifier '(' func_arguments ')' ';' + { + struct hlsl_state_block_entry *entry; + unsigned int i; + + if (!(entry = hlsl_alloc(ctx, sizeof(*entry)))) + YYABORT; + + entry->is_function_call = true; + + entry->name = $2; + entry->lhs_has_index = false; + entry->lhs_index = 0; + + entry->instrs = $4.instrs; + + entry->args_count = $4.args_count; + if (!(entry->args = hlsl_alloc(ctx, sizeof(*entry->args) * entry->args_count))) + YYABORT; + for (i = 0; i < entry->args_count; ++i) + hlsl_src_from_node(&entry->args[i], $4.args[i]); + vkd3d_free($4.args); + $$ = $1; state_block_add_entry($$, entry); } diff --git a/tests/hlsl/state-block-function-syntax.shader_test b/tests/hlsl/state-block-function-syntax.shader_test index 53279a36..a615ca8e 100644 --- a/tests/hlsl/state-block-function-syntax.shader_test +++ b/tests/hlsl/state-block-function-syntax.shader_test @@ -1,6 +1,6 @@ % Unlike assignment syntax, only these names are allowed. % The parameter count is also checked. -[pixel shader todo] +[pixel shader] sampler sam { SetBlendState(foo, bar, baz); // 3 parameters @@ -27,7 +27,7 @@ sampler sam float4 main() : sv_target { return 0; } -[pixel shader fail(sm<6)] +[pixel shader fail(sm<6) todo] sampler sam { SetSomeotherState(); @@ -37,7 +37,7 @@ float4 main() : sv_target { return 0; } % It is allowed to use functions together with assignment syntax. -[pixel shader todo] +[pixel shader] sampler sam { SetDepthStencilState(foo, bar); @@ -48,7 +48,7 @@ float4 main() : sv_target { return 0; } % Test complex expression on the arguments, including function calls. -[pixel shader todo] +[pixel shader] float4 addition(float4 a, float4 b) { return a + b; @@ -63,7 +63,7 @@ float4 main() : sv_target { return 0; } % Test the same thing on technique passes -[pixel shader todo] +[pixel shader] technique tech1 { pass pass1