Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9efc3dadd..6f8bece9f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1201,7 +1201,7 @@ unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref) if (offset_node->type != HLSL_IR_CONSTANT) { FIXME("Dereference with non-constant offset of type %s.\n", hlsl_node_type_to_string(offset_node->type)); - offset_node = NULL; + return 0; }
return hlsl_ir_constant(offset_node)->value[0].u;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index e9eac555a..b8d147a01 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1083,6 +1083,17 @@ static struct list *append_unop(struct list *list, struct hlsl_ir_node *node) return list; }
+static struct list *add_unary_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *expr; + + if (!(expr = hlsl_new_unary_expr(ctx, op, node_from_list(instrs), loc))) + return NULL; + list_add_tail(instrs, &expr->entry); + return instrs; +} + static struct list *add_binary_expr(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) { @@ -3033,7 +3044,7 @@ unary_expr: if ($1 == UNARY_OP_PLUS) $$ = $2; else - $$ = append_unop($2, hlsl_new_unary_expr(ctx, ops[$1], node_from_list($2), @1)); + $$ = add_unary_expr(ctx, $2, ops[$1], @1); }
/* var_modifiers is necessary to avoid shift/reduce conflicts. */
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 23/09/21 23:47, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index e9eac555a..b8d147a01 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1083,6 +1083,17 @@ static struct list *append_unop(struct list *list, struct hlsl_ir_node *node) return list; }
+static struct list *add_unary_expr(struct hlsl_ctx *ctx, struct list *instrs,
enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc)
+{
- struct hlsl_ir_node *expr;
- if (!(expr = hlsl_new_unary_expr(ctx, op, node_from_list(instrs), loc)))
return NULL;
- list_add_tail(instrs, &expr->entry);
- return instrs;
+}
- static struct list *add_binary_expr(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) {
@@ -3033,7 +3044,7 @@ unary_expr: if ($1 == UNARY_OP_PLUS) $$ = $2; else
$$ = append_unop($2, hlsl_new_unary_expr(ctx, ops[$1], node_from_list($2), @1));
$$ = add_unary_expr(ctx, $2, ops[$1], @1); } /* var_modifiers is necessary to avoid shift/reduce conflicts. */
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 51 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 37 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b8d147a01..42a6768cc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -80,14 +80,6 @@ struct parse_if_body struct list *else_instrs; };
-enum parse_unary_op -{ - UNARY_OP_PLUS, - UNARY_OP_MINUS, - UNARY_OP_LOGICNOT, - UNARY_OP_BITNOT, -}; - enum parse_assign_op { ASSIGN_OP_ASSIGN, @@ -1798,7 +1790,6 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type struct parse_array_sizes arrays; struct parse_variable_def *variable_def; struct parse_if_body if_body; - enum parse_unary_op unary_op; enum parse_assign_op assign_op; struct hlsl_reg_reservation reg_reservation; struct parse_colon_attribute colon_attribute; @@ -1987,8 +1978,6 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type %type <type> type %type <type> typedef_type
-%type <unary_op> unary_op - %type <variable_def> type_spec %type <variable_def> variable_def
@@ -3037,16 +3026,22 @@ unary_expr: } $$ = $2; } - | unary_op unary_expr + | '+' unary_expr { - static const enum hlsl_ir_expr_op ops[] = {0, HLSL_OP1_NEG, HLSL_OP1_LOGIC_NOT, HLSL_OP1_BIT_NOT}; - - if ($1 == UNARY_OP_PLUS) - $$ = $2; - else - $$ = add_unary_expr(ctx, $2, ops[$1], @1); + $$ = $2; + } + | '-' unary_expr + { + $$ = add_unary_expr(ctx, $2, HLSL_OP1_NEG, @1); + } + | '~' unary_expr + { + $$ = add_unary_expr(ctx, $2, HLSL_OP1_BIT_NOT, @1); + } + | '!' unary_expr + { + $$ = add_unary_expr(ctx, $2, HLSL_OP1_LOGIC_NOT, @1); } - /* var_modifiers is necessary to avoid shift/reduce conflicts. */ | '(' var_modifiers type arrays ')' unary_expr { @@ -3082,24 +3077,6 @@ unary_expr: $$ = append_unop($6, &hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3)->node); }
-unary_op: - '+' - { - $$ = UNARY_OP_PLUS; - } - | '-' - { - $$ = UNARY_OP_MINUS; - } - | '!' - { - $$ = UNARY_OP_LOGICNOT; - } - | '~' - { - $$ = UNARY_OP_BITNOT; - } - mul_expr: unary_expr | mul_expr '*' unary_expr
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Though notice that technically, like for C, unary plus promotes bool to int. This might become significant one day, when we have function call overloading. OTOH, I really hope we never find shaders depending on that, and many fine and not so fine points of type handling are not implemented correctly yet any way.
Il 23/09/21 23:47, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 51 +++++++++++----------------------------- 1 file changed, 14 insertions(+), 37 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b8d147a01..42a6768cc 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -80,14 +80,6 @@ struct parse_if_body struct list *else_instrs; };
-enum parse_unary_op -{
- UNARY_OP_PLUS,
- UNARY_OP_MINUS,
- UNARY_OP_LOGICNOT,
- UNARY_OP_BITNOT,
-};
- enum parse_assign_op { ASSIGN_OP_ASSIGN,
@@ -1798,7 +1790,6 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type struct parse_array_sizes arrays; struct parse_variable_def *variable_def; struct parse_if_body if_body;
- enum parse_unary_op unary_op; enum parse_assign_op assign_op; struct hlsl_reg_reservation reg_reservation; struct parse_colon_attribute colon_attribute;
@@ -1987,8 +1978,6 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type %type <type> type %type <type> typedef_type
-%type <unary_op> unary_op
- %type <variable_def> type_spec %type <variable_def> variable_def
@@ -3037,16 +3026,22 @@ unary_expr: } $$ = $2; }
- | unary_op unary_expr
- | '+' unary_expr {
static const enum hlsl_ir_expr_op ops[] = {0, HLSL_OP1_NEG, HLSL_OP1_LOGIC_NOT, HLSL_OP1_BIT_NOT};
if ($1 == UNARY_OP_PLUS)
$$ = $2;
else
$$ = add_unary_expr(ctx, $2, ops[$1], @1);
$$ = $2;
}
- | '-' unary_expr
{
$$ = add_unary_expr(ctx, $2, HLSL_OP1_NEG, @1);
}
- | '~' unary_expr
{
$$ = add_unary_expr(ctx, $2, HLSL_OP1_BIT_NOT, @1);
}
- | '!' unary_expr
{
$$ = add_unary_expr(ctx, $2, HLSL_OP1_LOGIC_NOT, @1); }
/* var_modifiers is necessary to avoid shift/reduce conflicts. */ | '(' var_modifiers type arrays ')' unary_expr {
@@ -3082,24 +3077,6 @@ unary_expr: $$ = append_unop($6, &hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3)->node); }
-unary_op:
'+'
{
$$ = UNARY_OP_PLUS;
}
- | '-'
{
$$ = UNARY_OP_MINUS;
}
- | '!'
{
$$ = UNARY_OP_LOGICNOT;
}
- | '~'
{
$$ = UNARY_OP_BITNOT;
}
- mul_expr: unary_expr | mul_expr '*' unary_expr
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 42a6768cc..941f49cfe 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1069,12 +1069,6 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, return expr; }
-static struct list *append_unop(struct list *list, struct hlsl_ir_node *node) -{ - list_add_tail(list, &node->entry); - return list; -} - static struct list *add_unary_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) { @@ -2934,7 +2928,8 @@ postfix_expr: hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle "%s".", $3); YYABORT; } - $$ = append_unop($1, &swizzle->node); + list_add_tail($1, &swizzle->node.entry); + $$ = $1; } else { @@ -3047,6 +3042,7 @@ unary_expr: { struct hlsl_type *src_type = node_from_list($6)->data_type; struct hlsl_type *dst_type; + struct hlsl_ir_expr *cast; unsigned int i;
if ($2) @@ -3074,7 +3070,13 @@ unary_expr: YYABORT; }
- $$ = append_unop($6, &hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3)->node); + if (!(cast = hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3))) + { + hlsl_free_instr_list($6); + YYABORT; + } + list_add_tail($6, &cast->node.entry); + $$ = $6; }
mul_expr:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 23/09/21 23:47, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 42a6768cc..941f49cfe 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1069,12 +1069,6 @@ static struct hlsl_ir_expr *add_expr(struct hlsl_ctx *ctx, struct list *instrs, return expr; }
-static struct list *append_unop(struct list *list, struct hlsl_ir_node *node) -{
- list_add_tail(list, &node->entry);
- return list;
-}
- static struct list *add_unary_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct vkd3d_shader_location loc) {
@@ -2934,7 +2928,8 @@ postfix_expr: hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle "%s".", $3); YYABORT; }
$$ = append_unop($1, &swizzle->node);
list_add_tail($1, &swizzle->node.entry);
$$ = $1; } else {
@@ -3047,6 +3042,7 @@ unary_expr: { struct hlsl_type *src_type = node_from_list($6)->data_type; struct hlsl_type *dst_type;
struct hlsl_ir_expr *cast; unsigned int i; if ($2)
@@ -3074,7 +3070,13 @@ unary_expr: YYABORT; }
$$ = append_unop($6, &hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3)->node);
if (!(cast = hlsl_new_cast(ctx, node_from_list($6), dst_type, &@3)))
{
hlsl_free_instr_list($6);
YYABORT;
}
list_add_tail($6, &cast->node.entry);
$$ = $6; }
mul_expr:
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 941f49cfe..19745e725 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1973,6 +1973,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type %type <type> typedef_type
%type <variable_def> type_spec +%type <variable_def> variable_decl %type <variable_def> variable_def
%% @@ -2546,7 +2547,7 @@ variables_def: list_add_tail($$, &$3->entry); }
-variable_def: +variable_decl: any_identifier arrays colon_attribute { $$ = hlsl_alloc(ctx, sizeof(*$$)); @@ -2556,15 +2557,13 @@ variable_def: $$->semantic = $3.semantic; $$->reg_reservation = $3.reg_reservation; } - | any_identifier arrays colon_attribute '=' complex_initializer + +variable_def: + variable_decl + | variable_decl '=' complex_initializer { - $$ = hlsl_alloc(ctx, sizeof(*$$)); - $$->loc = @1; - $$->name = $1; - $$->arrays = $2; - $$->semantic = $3.semantic; - $$->reg_reservation = $3.reg_reservation; - $$->initializer = $5; + $$ = $1; + $$->initializer = $3; }
arrays:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 23/09/21 23:47, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 941f49cfe..19745e725 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1973,6 +1973,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type %type <type> typedef_type
%type <variable_def> type_spec +%type <variable_def> variable_decl %type <variable_def> variable_def
%% @@ -2546,7 +2547,7 @@ variables_def: list_add_tail($$, &$3->entry); }
-variable_def: +variable_decl: any_identifier arrays colon_attribute { $$ = hlsl_alloc(ctx, sizeof(*$$)); @@ -2556,15 +2557,13 @@ variable_def: $$->semantic = $3.semantic; $$->reg_reservation = $3.reg_reservation; }
- | any_identifier arrays colon_attribute '=' complex_initializer
+variable_def:
variable_decl
- | variable_decl '=' complex_initializer {
$$ = hlsl_alloc(ctx, sizeof(*$$));
$$->loc = @1;
$$->name = $1;
$$->arrays = $2;
$$->semantic = $3.semantic;
$$->reg_reservation = $3.reg_reservation;
$$->initializer = $5;
$$ = $1;
$$->initializer = $3; }
arrays:
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl.y | 64 +++++++- tests/hlsl-state-block-syntax.shader_test | 173 ++++++++++++++++++++++ 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 tests/hlsl-state-block-syntax.shader_test
diff --git a/Makefile.am b/Makefile.am index 4a2bf8e18..bc33e0f60 100644 --- a/Makefile.am +++ b/Makefile.am @@ -74,6 +74,7 @@ vkd3d_shader_tests = \ tests/hlsl-return-implicit-conversion.shader_test \ tests/hlsl-return-void.shader_test \ tests/hlsl-shape.shader_test \ + tests/hlsl-state-block-syntax.shader_test \ tests/hlsl-static-initializer.shader_test \ tests/hlsl-storage-qualifiers.shader_test \ tests/hlsl-struct-assignment.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 27afeedd4..abc870f4f 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -469,6 +469,8 @@ struct hlsl_ctx size_t count, size; } constant_defs; uint32_t temp_count; + + uint32_t in_state_block : 1; };
enum hlsl_error_level diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 19745e725..420156e66 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2558,6 +2558,23 @@ variable_decl: $$->reg_reservation = $3.reg_reservation; }
+state: + any_identifier '=' expr ';' + { + vkd3d_free($1); + hlsl_free_instr_list($3); + } + +state_block_start: + %empty + { + ctx->in_state_block = 1; + } + +state_block: + %empty + | state_block state + variable_def: variable_decl | variable_decl '=' complex_initializer @@ -2565,6 +2582,11 @@ variable_def: $$ = $1; $$->initializer = $3; } + | variable_decl '{' state_block_start state_block '}' + { + $$ = $1; + ctx->in_state_block = 0; + }
arrays: %empty @@ -2827,7 +2849,10 @@ primary_expr: init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_FLOAT], @1); c->value[0].f = $1; if (!($$ = make_list(ctx, &c->node))) + { + hlsl_free_instr(&c->node); YYABORT; + } } | C_INTEGER { @@ -2838,7 +2863,10 @@ primary_expr: init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1); c->value[0].i = $1; if (!($$ = make_list(ctx, &c->node))) + { + hlsl_free_instr(&c->node); YYABORT; + } } | boolean { @@ -2849,7 +2877,10 @@ primary_expr: init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_BOOL], @1); c->value[0].b = $1; if (!($$ = make_list(ctx, &c->node))) + { + hlsl_free_instr(&c->node); YYABORT; + } } | VAR_IDENTIFIER { @@ -2861,13 +2892,13 @@ primary_expr: hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable "%s" is not defined.", $1); YYABORT; } - if ((load = hlsl_new_var_load(ctx, var, @1))) + if (!(load = hlsl_new_var_load(ctx, var, @1))) + YYABORT; + if (!($$ = make_list(ctx, &load->node))) { - if (!($$ = make_list(ctx, &load->node))) - YYABORT; + hlsl_free_instr(&load->node); + YYABORT; } - else - $$ = NULL; } | '(' expr ')' { @@ -2878,6 +2909,29 @@ primary_expr: if (!($$ = add_call(ctx, $1, &$3, @1))) YYABORT; } + | NEW_IDENTIFIER + { + if (ctx->in_state_block) + { + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + if (!(var = hlsl_new_var(ctx, $1, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1, NULL, 0, NULL))) + YYABORT; + if (!(load = hlsl_new_var_load(ctx, var, @1))) + YYABORT; + if (!($$ = make_list(ctx, &load->node))) + { + hlsl_free_instr(&load->node); + YYABORT; + } + } + else + { + hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Identifier "%s" is not declared.\n", $1); + YYABORT; + } + }
postfix_expr: primary_expr diff --git a/tests/hlsl-state-block-syntax.shader_test b/tests/hlsl-state-block-syntax.shader_test new file mode 100644 index 000000000..26853bf40 --- /dev/null +++ b/tests/hlsl-state-block-syntax.shader_test @@ -0,0 +1,173 @@ +[pixel shader fail] +sampler s +{ + foo = float; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s = sampler_state +{ + foo = float; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s +{ + 2 = 3; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s +{ + 2; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s +{ + foo; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s +{ + foo = bar +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s {} + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f {} = 1; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f = 1 {}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +sampler s = sampler_state; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f {} : register(c1); + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f +{ + foo = (sampler)2; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f +{ + foo = (faketype)2; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f +{ + foo = (sampler)bar; +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +float f +{ + foo = bar(); +}; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader] +float u : register(c1) {}; +float4 main() : sv_target +{ + float zero = 0; + float a {}; + float b + { + foo = bar; + foo = bar; + foo = (int)2; + foo = (int)bar; + foo = float4(bar, baz, qux, xyzzy); + foo = zero++; + }; + float c {}, d = 1, e; + struct {int a;} s {foo = bar;}; + return float4(0, 1, zero, 1); +} + +[test] +draw quad +probe all rgba (0, 1, 0, 1)
On Thu, Sep 23, 2021 at 11:47 PM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Makefile.am | 1 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl.y | 64 +++++++- tests/hlsl-state-block-syntax.shader_test | 173 ++++++++++++++++++++++ 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 tests/hlsl-state-block-syntax.shader_test
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 19745e725..420156e66 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y
@@ -2878,6 +2909,29 @@ primary_expr: if (!($$ = add_call(ctx, $1, &$3, @1))) YYABORT; }
- | NEW_IDENTIFIER
{
if (ctx->in_state_block)
{
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
if (!(var = hlsl_new_var(ctx, $1, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1, NULL, 0, NULL)))
YYABORT;
if (!(load = hlsl_new_var_load(ctx, var, @1)))
YYABORT;
if (!($$ = make_list(ctx, &load->node)))
{
hlsl_free_instr(&load->node);
YYABORT;
}
}
This leaks var on error. Actually, does it also leak it on success? We usually store the variables into scopes and go through the scopes when we want to free them, but that's not the case here.
diff --git a/tests/hlsl-state-block-syntax.shader_test b/tests/hlsl-state-block-syntax.shader_test new file mode 100644 index 000000000..26853bf40 --- /dev/null +++ b/tests/hlsl-state-block-syntax.shader_test @@ -0,0 +1,173 @@ +[pixel shader fail] +sampler s +{
- foo = float;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s = sampler_state +{
- foo = float;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s +{
- 2 = 3;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s +{
- 2;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s +{
- foo;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s +{
- foo = bar
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s {}
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f {} = 1;
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f = 1 {};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +sampler s = sampler_state;
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f {} : register(c1);
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f +{
- foo = (sampler)2;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f +{
- foo = (faketype)2;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f +{
- foo = (sampler)bar;
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader fail] +float f +{
- foo = bar();
+};
+float4 main() : sv_target +{
- return float4(0, 0, 0, 0);
+}
+[pixel shader] +float u : register(c1) {}; +float4 main() : sv_target +{
- float zero = 0;
- float a {};
- float b
- {
foo = bar;
foo = bar;
foo = (int)2;
foo = (int)bar;
foo = float4(bar, baz, qux, xyzzy);
foo = zero++;
- };
- float c {}, d = 1, e;
- struct {int a;} s {foo = bar;};
- return float4(0, 1, zero, 1);
+}
+[test] +draw quad +probe all rgba (0, 1, 0, 1)
Hmm, that's something...
Hi,
Il 25/09/21 14:09, Matteo Bruni ha scritto:
- | NEW_IDENTIFIER
{
if (ctx->in_state_block)
{
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
if (!(var = hlsl_new_var(ctx, $1, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1, NULL, 0, NULL)))
YYABORT;
if (!(load = hlsl_new_var_load(ctx, var, @1)))
YYABORT;
if (!($$ = make_list(ctx, &load->node)))
{
hlsl_free_instr(&load->node);
YYABORT;
}
}
This leaks var on error.
Also, the node is doubly freed in the error path (because make_list already frees the node when it fails). Maybe the outer hlsl_free_instr was meant to free the variable instead (though the variable must also be freed when hlsl_new_var_load fails).
That said, I didn't know about this strange HLSL feature, so I don't know what the intended behavior would be. Does anybody have a link? Searching for "hlsl state block" didn't help much.
Thanks, Giovanni.
On 9/27/21 5:20 AM, Giovanni Mascellani wrote:
Hi,
Il 25/09/21 14:09, Matteo Bruni ha scritto:
- | NEW_IDENTIFIER
{
if (ctx->in_state_block)
{
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
if (!(var = hlsl_new_var(ctx, $1, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1, NULL, 0, NULL)))
YYABORT;
if (!(load = hlsl_new_var_load(ctx, var, @1)))
YYABORT;
if (!($$ = make_list(ctx, &load->node)))
{
hlsl_free_instr(&load->node);
YYABORT;
}
}
This leaks var on error.
Also, the node is doubly freed in the error path (because make_list already frees the node when it fails). Maybe the outer hlsl_free_instr was meant to free the variable instead (though the variable must also be freed when hlsl_new_var_load fails).
That said, I didn't know about this strange HLSL feature, so I don't know what the intended behavior would be. Does anybody have a link? Searching for "hlsl state block" didn't help much.
The terminology might be invented by me, but the construct is demonstrated at [1]. It's meant for effects, but the documentation on that page doesn't make that clear, to the effect that I've seen it used in regular shaders as well. In that case it's basically just ignored, including all instructions with side effects (as the tests show).
[1] https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl...
On 9/27/21 05:20, Giovanni Mascellani wrote:
Also, the node is doubly freed in the error path (because make_list already frees the node when it fails). Maybe the outer hlsl_free_instr was meant to free the variable instead (though the variable must also be freed when hlsl_new_var_load fails).
Evidently I wrote make_list() to free the node as a convenience, but then never made use of that, since all of the current users do the same thing. I'm not even sure which behaviour to keep (on the one hand, convenience, on the other, I don't like functions which free their input parameters when failing...)
On 9/25/21 07:09, Matteo Bruni wrote:
On Thu, Sep 23, 2021 at 11:47 PM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Makefile.am | 1 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl.y | 64 +++++++- tests/hlsl-state-block-syntax.shader_test | 173 ++++++++++++++++++++++ 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 tests/hlsl-state-block-syntax.shader_test
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 19745e725..420156e66 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y
@@ -2878,6 +2909,29 @@ primary_expr: if (!($$ = add_call(ctx, $1, &$3, @1))) YYABORT; }
- | NEW_IDENTIFIER
{
if (ctx->in_state_block)
{
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
if (!(var = hlsl_new_var(ctx, $1, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1, NULL, 0, NULL)))
YYABORT;
if (!(load = hlsl_new_var_load(ctx, var, @1)))
YYABORT;
if (!($$ = make_list(ctx, &load->node)))
{
hlsl_free_instr(&load->node);
YYABORT;
}
}
This leaks var on error. Actually, does it also leak it on success? We usually store the variables into scopes and go through the scopes when we want to free them, but that's not the case here.
Indeed; I think this should be hlsl_new_synthetic_var(). Not sure what I was doing here...
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 23/09/21 23:47, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9efc3dadd..6f8bece9f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1201,7 +1201,7 @@ unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref) if (offset_node->type != HLSL_IR_CONSTANT) { FIXME("Dereference with non-constant offset of type %s.\n", hlsl_node_type_to_string(offset_node->type));
offset_node = NULL;
return 0; } return hlsl_ir_constant(offset_node)->value[0].u;