Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 103 +++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 57 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e4070572..9f50d2fc 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1033,64 +1033,53 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl
static const char *debug_expr_op(const struct hlsl_ir_expr *expr) { - static const char * const op_names[] = + static const char *const op_names[] = { - "~", - "!", - "-", - "abs", - "sign", - "rcp", - "rsq", - "sqrt", - "nrm", - "exp2", - "log2", - - "cast", - - "fract", - - "sin", - "cos", - "sin_reduced", - "cos_reduced", - - "dsx", - "dsy", - - "sat", - - "+", - "*", - "/", - - "%", - - "<", - ">", - "<=", - ">=", - "==", - "!=", - - "&&", - "||", - - "<<", - ">>", - "&", - "|", - "^", - - "dot", - "crs", - "min", - "max", - - "pow", - - "lerp", + [HLSL_IR_UNOP_ABS] = "abs", + [HLSL_IR_UNOP_BIT_NOT] = "~", + [HLSL_IR_UNOP_CAST] = "cast", + [HLSL_IR_UNOP_COS] = "cos", + [HLSL_IR_UNOP_COS_REDUCED] = "cos_reduced", + [HLSL_IR_UNOP_DSX] = "dsx", + [HLSL_IR_UNOP_DSY] = "dsy", + [HLSL_IR_UNOP_EXP2] = "exp2", + [HLSL_IR_UNOP_FRACT] = "fract", + [HLSL_IR_UNOP_LOG2] = "log2", + [HLSL_IR_UNOP_LOGIC_NOT] = "!", + [HLSL_IR_UNOP_NEG] = "-", + [HLSL_IR_UNOP_NRM] = "nrm", + [HLSL_IR_UNOP_RCP] = "rcp", + [HLSL_IR_UNOP_RSQ] = "rsq", + [HLSL_IR_UNOP_SAT] = "sat", + [HLSL_IR_UNOP_SIGN] = "sign", + [HLSL_IR_UNOP_SIN] = "sin", + [HLSL_IR_UNOP_SIN_REDUCED] = "sin_reduced", + [HLSL_IR_UNOP_SQRT] = "sqrt", + + [HLSL_IR_BINOP_ADD] = "+", + [HLSL_IR_BINOP_BIT_AND] = "&", + [HLSL_IR_BINOP_BIT_OR] = "|", + [HLSL_IR_BINOP_BIT_XOR] = "^", + [HLSL_IR_BINOP_CRS] = "crs", + [HLSL_IR_BINOP_DIV] = "/", + [HLSL_IR_BINOP_DOT] = "dot", + [HLSL_IR_BINOP_EQUAL] = "==", + [HLSL_IR_BINOP_GEQUAL] = ">=", + [HLSL_IR_BINOP_GREATER] = ">", + [HLSL_IR_BINOP_LEQUAL] = "<=", + [HLSL_IR_BINOP_LESS] = "<", + [HLSL_IR_BINOP_LOGIC_AND] = "&&", + [HLSL_IR_BINOP_LOGIC_OR] = "||", + [HLSL_IR_BINOP_LSHIFT] = "<<", + [HLSL_IR_BINOP_MAX] = "max", + [HLSL_IR_BINOP_MIN] = "min", + [HLSL_IR_BINOP_MOD] = "%", + [HLSL_IR_BINOP_MUL] = "*", + [HLSL_IR_BINOP_NEQUAL] = "!=", + [HLSL_IR_BINOP_POW] = "pow", + [HLSL_IR_BINOP_RSHIFT] = ">>", + + [HLSL_IR_TEROP_LERP] = "lerp", };
return op_names[expr->op];
For the sake of simplicity and clarity, especially in the interest of allowing us to have expressions with larger numbers of terms.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- In specific, it is my plan to encode e.g. SampleGrad as HLSL_OP6_SAMPLE_GRAD.
libs/vkd3d-shader/hlsl.c | 92 ++++++++++++++-------------- libs/vkd3d-shader/hlsl.h | 101 ++++++++++++++----------------- libs/vkd3d-shader/hlsl.y | 55 +++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 20 +++--- libs/vkd3d-shader/hlsl_sm1.c | 20 +++--- 5 files changed, 138 insertions(+), 150 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9f50d2fc..62dc535d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -439,7 +439,7 @@ struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *no { struct hlsl_ir_node *cast;
- cast = hlsl_new_unary_expr(ctx, HLSL_IR_UNOP_CAST, node, *loc); + cast = hlsl_new_unary_expr(ctx, HLSL_OP1_CAST, node, *loc); if (cast) cast->data_type = type; return hlsl_ir_expr(cast); @@ -1035,51 +1035,51 @@ static const char *debug_expr_op(const struct hlsl_ir_expr *expr) { static const char *const op_names[] = { - [HLSL_IR_UNOP_ABS] = "abs", - [HLSL_IR_UNOP_BIT_NOT] = "~", - [HLSL_IR_UNOP_CAST] = "cast", - [HLSL_IR_UNOP_COS] = "cos", - [HLSL_IR_UNOP_COS_REDUCED] = "cos_reduced", - [HLSL_IR_UNOP_DSX] = "dsx", - [HLSL_IR_UNOP_DSY] = "dsy", - [HLSL_IR_UNOP_EXP2] = "exp2", - [HLSL_IR_UNOP_FRACT] = "fract", - [HLSL_IR_UNOP_LOG2] = "log2", - [HLSL_IR_UNOP_LOGIC_NOT] = "!", - [HLSL_IR_UNOP_NEG] = "-", - [HLSL_IR_UNOP_NRM] = "nrm", - [HLSL_IR_UNOP_RCP] = "rcp", - [HLSL_IR_UNOP_RSQ] = "rsq", - [HLSL_IR_UNOP_SAT] = "sat", - [HLSL_IR_UNOP_SIGN] = "sign", - [HLSL_IR_UNOP_SIN] = "sin", - [HLSL_IR_UNOP_SIN_REDUCED] = "sin_reduced", - [HLSL_IR_UNOP_SQRT] = "sqrt", - - [HLSL_IR_BINOP_ADD] = "+", - [HLSL_IR_BINOP_BIT_AND] = "&", - [HLSL_IR_BINOP_BIT_OR] = "|", - [HLSL_IR_BINOP_BIT_XOR] = "^", - [HLSL_IR_BINOP_CRS] = "crs", - [HLSL_IR_BINOP_DIV] = "/", - [HLSL_IR_BINOP_DOT] = "dot", - [HLSL_IR_BINOP_EQUAL] = "==", - [HLSL_IR_BINOP_GEQUAL] = ">=", - [HLSL_IR_BINOP_GREATER] = ">", - [HLSL_IR_BINOP_LEQUAL] = "<=", - [HLSL_IR_BINOP_LESS] = "<", - [HLSL_IR_BINOP_LOGIC_AND] = "&&", - [HLSL_IR_BINOP_LOGIC_OR] = "||", - [HLSL_IR_BINOP_LSHIFT] = "<<", - [HLSL_IR_BINOP_MAX] = "max", - [HLSL_IR_BINOP_MIN] = "min", - [HLSL_IR_BINOP_MOD] = "%", - [HLSL_IR_BINOP_MUL] = "*", - [HLSL_IR_BINOP_NEQUAL] = "!=", - [HLSL_IR_BINOP_POW] = "pow", - [HLSL_IR_BINOP_RSHIFT] = ">>", - - [HLSL_IR_TEROP_LERP] = "lerp", + [HLSL_OP1_ABS] = "abs", + [HLSL_OP1_BIT_NOT] = "~", + [HLSL_OP1_CAST] = "cast", + [HLSL_OP1_COS] = "cos", + [HLSL_OP1_COS_REDUCED] = "cos_reduced", + [HLSL_OP1_DSX] = "dsx", + [HLSL_OP1_DSY] = "dsy", + [HLSL_OP1_EXP2] = "exp2", + [HLSL_OP1_FRACT] = "fract", + [HLSL_OP1_LOG2] = "log2", + [HLSL_OP1_LOGIC_NOT] = "!", + [HLSL_OP1_NEG] = "-", + [HLSL_OP1_NRM] = "nrm", + [HLSL_OP1_RCP] = "rcp", + [HLSL_OP1_RSQ] = "rsq", + [HLSL_OP1_SAT] = "sat", + [HLSL_OP1_SIGN] = "sign", + [HLSL_OP1_SIN] = "sin", + [HLSL_OP1_SIN_REDUCED] = "sin_reduced", + [HLSL_OP1_SQRT] = "sqrt", + + [HLSL_OP2_ADD] = "+", + [HLSL_OP2_BIT_AND] = "&", + [HLSL_OP2_BIT_OR] = "|", + [HLSL_OP2_BIT_XOR] = "^", + [HLSL_OP2_CRS] = "crs", + [HLSL_OP2_DIV] = "/", + [HLSL_OP2_DOT] = "dot", + [HLSL_OP2_EQUAL] = "==", + [HLSL_OP2_GEQUAL] = ">=", + [HLSL_OP2_GREATER] = ">", + [HLSL_OP2_LEQUAL] = "<=", + [HLSL_OP2_LESS] = "<", + [HLSL_OP2_LOGIC_AND] = "&&", + [HLSL_OP2_LOGIC_OR] = "||", + [HLSL_OP2_LSHIFT] = "<<", + [HLSL_OP2_MAX] = "max", + [HLSL_OP2_MIN] = "min", + [HLSL_OP2_MOD] = "%", + [HLSL_OP2_MUL] = "*", + [HLSL_OP2_NEQUAL] = "!=", + [HLSL_OP2_POW] = "pow", + [HLSL_OP2_RSHIFT] = ">>", + + [HLSL_OP3_LERP] = "lerp", };
return op_names[expr->op]; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3b0e5207..4a4af5d1 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -275,62 +275,51 @@ struct hlsl_ir_loop
enum hlsl_ir_expr_op { - HLSL_IR_UNOP_BIT_NOT = 0, - HLSL_IR_UNOP_LOGIC_NOT, - HLSL_IR_UNOP_NEG, - HLSL_IR_UNOP_ABS, - HLSL_IR_UNOP_SIGN, - HLSL_IR_UNOP_RCP, - HLSL_IR_UNOP_RSQ, - HLSL_IR_UNOP_SQRT, - HLSL_IR_UNOP_NRM, - HLSL_IR_UNOP_EXP2, - HLSL_IR_UNOP_LOG2, - - HLSL_IR_UNOP_CAST, - - HLSL_IR_UNOP_FRACT, - - HLSL_IR_UNOP_SIN, - HLSL_IR_UNOP_COS, - HLSL_IR_UNOP_SIN_REDUCED, /* Reduced range [-pi, pi] */ - HLSL_IR_UNOP_COS_REDUCED, /* Reduced range [-pi, pi] */ - - HLSL_IR_UNOP_DSX, - HLSL_IR_UNOP_DSY, - - HLSL_IR_UNOP_SAT, - - HLSL_IR_BINOP_ADD, - HLSL_IR_BINOP_MUL, - HLSL_IR_BINOP_DIV, - - HLSL_IR_BINOP_MOD, - - HLSL_IR_BINOP_LESS, - HLSL_IR_BINOP_GREATER, - HLSL_IR_BINOP_LEQUAL, - HLSL_IR_BINOP_GEQUAL, - HLSL_IR_BINOP_EQUAL, - HLSL_IR_BINOP_NEQUAL, - - HLSL_IR_BINOP_LOGIC_AND, - HLSL_IR_BINOP_LOGIC_OR, - - HLSL_IR_BINOP_LSHIFT, - HLSL_IR_BINOP_RSHIFT, - HLSL_IR_BINOP_BIT_AND, - HLSL_IR_BINOP_BIT_OR, - HLSL_IR_BINOP_BIT_XOR, - - HLSL_IR_BINOP_DOT, - HLSL_IR_BINOP_CRS, - HLSL_IR_BINOP_MIN, - HLSL_IR_BINOP_MAX, - - HLSL_IR_BINOP_POW, - - HLSL_IR_TEROP_LERP, + HLSL_OP1_ABS, + HLSL_OP1_BIT_NOT, + HLSL_OP1_CAST, + HLSL_OP1_COS, + HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi] */ + HLSL_OP1_DSX, + HLSL_OP1_DSY, + HLSL_OP1_EXP2, + HLSL_OP1_FRACT, + HLSL_OP1_LOG2, + HLSL_OP1_LOGIC_NOT, + HLSL_OP1_NEG, + HLSL_OP1_NRM, + HLSL_OP1_RCP, + HLSL_OP1_RSQ, + HLSL_OP1_SAT, + HLSL_OP1_SIGN, + HLSL_OP1_SIN, + HLSL_OP1_SIN_REDUCED, /* Reduced range [-pi, pi] */ + HLSL_OP1_SQRT, + + HLSL_OP2_ADD, + HLSL_OP2_BIT_AND, + HLSL_OP2_BIT_OR, + HLSL_OP2_BIT_XOR, + HLSL_OP2_CRS, + HLSL_OP2_DIV, + HLSL_OP2_DOT, + HLSL_OP2_EQUAL, + HLSL_OP2_GEQUAL, + HLSL_OP2_GREATER, + HLSL_OP2_LEQUAL, + HLSL_OP2_LESS, + HLSL_OP2_LOGIC_AND, + HLSL_OP2_LOGIC_OR, + HLSL_OP2_LSHIFT, + HLSL_OP2_MAX, + HLSL_OP2_MIN, + HLSL_OP2_MOD, + HLSL_OP2_MUL, + HLSL_OP2_NEQUAL, + HLSL_OP2_POW, + HLSL_OP2_RSHIFT, + + HLSL_OP3_LERP, };
struct hlsl_ir_expr diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2754514d..ade78da6 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -324,7 +324,7 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_lis return true;
condition = node_from_list(cond_list); - if (!(not = hlsl_new_unary_expr(ctx, HLSL_IR_UNOP_LOGIC_NOT, condition, condition->loc))) + if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, condition, condition->loc))) return false; list_add_tail(cond_list, ¬->entry);
@@ -535,7 +535,7 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs, var = src->var; if (src->offset.node) { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_IR_BINOP_ADD, src->offset.node, offset))) + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, src->offset.node, offset))) return NULL; list_add_tail(instrs, &add->entry); offset = add; @@ -604,7 +604,7 @@ static struct hlsl_ir_load *add_array_load(struct hlsl_ctx *ctx, struct list *in if (!(c = hlsl_new_uint_constant(ctx, data_type->reg_size, loc))) return NULL; list_add_tail(instrs, &c->node.entry); - if (!(mul = hlsl_new_binary_expr(ctx, HLSL_IR_BINOP_MUL, index, &c->node))) + if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, index, &c->node))) return NULL; list_add_tail(instrs, &mul->entry); index = mul; @@ -1117,16 +1117,16 @@ static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) static const enum hlsl_ir_expr_op ops[] = { 0, - HLSL_IR_BINOP_ADD, + HLSL_OP2_ADD, 0, - HLSL_IR_BINOP_MUL, - HLSL_IR_BINOP_DIV, - HLSL_IR_BINOP_MOD, - HLSL_IR_BINOP_LSHIFT, - HLSL_IR_BINOP_RSHIFT, - HLSL_IR_BINOP_BIT_AND, - HLSL_IR_BINOP_BIT_OR, - HLSL_IR_BINOP_BIT_XOR, + HLSL_OP2_MUL, + HLSL_OP2_DIV, + HLSL_OP2_MOD, + HLSL_OP2_LSHIFT, + HLSL_OP2_RSHIFT, + HLSL_OP2_BIT_AND, + HLSL_OP2_BIT_OR, + HLSL_OP2_BIT_XOR, };
return ops[op]; @@ -1181,7 +1181,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in struct hlsl_ir_node *args[3] = {rhs}; struct hlsl_ir_expr *expr;
- if (!(expr = add_expr(ctx, instrs, HLSL_IR_UNOP_NEG, args, &rhs->loc))) + if (!(expr = add_expr(ctx, instrs, HLSL_OP1_NEG, args, &rhs->loc))) return NULL; rhs = &expr->node; assign_op = ASSIGN_OP_ADD; @@ -1211,7 +1211,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
while (lhs->type != HLSL_IR_LOAD) { - if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_IR_UNOP_CAST) + if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) { FIXME("Cast on the lhs.\n"); vkd3d_free(store); @@ -2835,8 +2835,7 @@ unary_expr: } | unary_op unary_expr { - enum hlsl_ir_expr_op ops[] = {0, HLSL_IR_UNOP_NEG, - HLSL_IR_UNOP_LOGIC_NOT, HLSL_IR_UNOP_BIT_NOT}; + 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; @@ -2901,31 +2900,31 @@ mul_expr: unary_expr | mul_expr '*' unary_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_MUL, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_MUL, @2); } | mul_expr '/' unary_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_DIV, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_DIV, @2); } | mul_expr '%' unary_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_MOD, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_MOD, @2); }
add_expr: mul_expr | add_expr '+' mul_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_ADD, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_ADD, @2); } | add_expr '-' mul_expr { struct hlsl_ir_node *neg;
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_IR_UNOP_NEG, node_from_list($3), @2))) + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, node_from_list($3), @2))) YYABORT; list_add_tail($3, &neg->entry); - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_ADD, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_ADD, @2); }
shift_expr: @@ -2943,30 +2942,30 @@ relational_expr: shift_expr | relational_expr '<' shift_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_LESS, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_LESS, @2); } | relational_expr '>' shift_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_GREATER, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_GREATER, @2); } | relational_expr OP_LE shift_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_LEQUAL, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_LEQUAL, @2); } | relational_expr OP_GE shift_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_GEQUAL, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_GEQUAL, @2); }
equality_expr: relational_expr | equality_expr OP_EQ relational_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_EQUAL, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_EQUAL, @2); } | equality_expr OP_NE relational_expr { - $$ = add_binary_expr(ctx, $1, $3, HLSL_IR_BINOP_NEQUAL, @2); + $$ = add_binary_expr(ctx, $1, $3, HLSL_OP2_NEQUAL, @2); }
bitand_expr: diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 549636ca..5f23f345 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -250,7 +250,7 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst const struct hlsl_type *src_type = expr->operands[0].node->data_type; const struct hlsl_type *dst_type = expr->node.data_type;
- if (expr->op != HLSL_IR_UNOP_CAST) + if (expr->op != HLSL_OP1_CAST) return false;
if (hlsl_types_are_equal(src_type, dst_type) @@ -297,7 +297,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr offset = &c->node; if (rhs_load->src.offset.node) { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_IR_BINOP_ADD, rhs_load->src.offset.node, &c->node))) + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, rhs_load->src.offset.node, &c->node))) return false; list_add_before(&instr->entry, &add->entry); offset = add; @@ -309,7 +309,7 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr offset = &c->node; if (store->lhs.offset.node) { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_IR_BINOP_ADD, store->lhs.offset.node, &c->node))) + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, store->lhs.offset.node, &c->node))) return false; list_add_before(&instr->entry, &add->entry); offset = add; @@ -358,7 +358,7 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { switch (expr->op) { - case HLSL_IR_UNOP_CAST: + case HLSL_OP1_CAST: if (instr->data_type->dimx != arg1->node.data_type->dimx || instr->data_type->dimy != arg1->node.data_type->dimy) { @@ -400,17 +400,17 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { switch (expr->op) { - case HLSL_IR_UNOP_NEG: + case HLSL_OP1_NEG: for (i = 0; i < instr->data_type->dimx; ++i) res->value.u[i] = -arg1->value.u[i]; break;
- case HLSL_IR_BINOP_ADD: + case HLSL_OP2_ADD: for (i = 0; i < instr->data_type->dimx; ++i) res->value.u[i] = arg1->value.u[i] + arg2->value.u[i]; break;
- case HLSL_IR_BINOP_MUL: + case HLSL_OP2_MUL: for (i = 0; i < instr->data_type->dimx; ++i) res->value.u[i] = arg1->value.u[i] * arg2->value.u[i]; break; @@ -443,13 +443,13 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi if (instr->type != HLSL_IR_EXPR) return false; expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_IR_BINOP_DIV) + if (expr->op != HLSL_OP2_DIV) return false;
- if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_IR_UNOP_RCP, expr->operands[1].node, instr->loc))) + if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, instr->loc))) return false; list_add_before(&expr->node.entry, &rcp->entry); - expr->op = HLSL_IR_BINOP_MUL; + expr->op = HLSL_OP2_MUL; hlsl_src_remove(&expr->operands[1]); hlsl_src_from_node(&expr->operands[1], rcp); return true; diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 8ea663dc..85d54ac2 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -612,19 +612,11 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
switch (expr->op) { - case HLSL_IR_BINOP_ADD: - write_sm1_binary_op(ctx, buffer, D3DSIO_ADD, &instr->reg, &arg1->reg, &arg2->reg); - break; - - case HLSL_IR_BINOP_MUL: - write_sm1_binary_op(ctx, buffer, D3DSIO_MUL, &instr->reg, &arg1->reg, &arg2->reg); - break; - - case HLSL_IR_UNOP_NEG: + case HLSL_OP1_NEG: write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG); break;
- case HLSL_IR_UNOP_RCP: + case HLSL_OP1_RCP: for (i = 0; i < instr->data_type->dimx; ++i) { struct hlsl_reg src = arg1->reg, dst = instr->reg; @@ -635,6 +627,14 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } break;
+ case HLSL_OP2_ADD: + write_sm1_binary_op(ctx, buffer, D3DSIO_ADD, &instr->reg, &arg1->reg, &arg2->reg); + break; + + case HLSL_OP2_MUL: + write_sm1_binary_op(ctx, buffer, D3DSIO_MUL, &instr->reg, &arg1->reg, &arg2->reg); + break; + default: FIXME("Unhandled op %u.\n", expr->op); break;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- For reference: originally the plan was for HLSL_IR_EXPR to only cover "mathematical" expressions, or more specifically, pure expressions that could be transformed and moved around (e.g. hoisted out of a loop) without any problem. In that world statements that don't fall under that banner, like texture sampling instructions, would not be expressions.
My original setup was inspired by the Mesa GLSL frontend (at the time). It looks like NIR also followed along the same line, with what they call ALU instructions covering our expressions and intrinsic instructions basically matching everything that isn't an ALU instruction or a jump (or SSA stuff).
Now, that concept doesn't necessarily need to be preserved in the same form. We probably still need some way to separate "pure" expressions from the rest though. What's your idea in this regard?
On 8/13/21 9:03 AM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
For reference: originally the plan was for HLSL_IR_EXPR to only cover "mathematical" expressions, or more specifically, pure expressions that could be transformed and moved around (e.g. hoisted out of a loop) without any problem. In that world statements that don't fall under that banner, like texture sampling instructions, would not be expressions.
My original setup was inspired by the Mesa GLSL frontend (at the time). It looks like NIR also followed along the same line, with what they call ALU instructions covering our expressions and intrinsic instructions basically matching everything that isn't an ALU instruction or a jump (or SSA stuff).
Now, that concept doesn't necessarily need to be preserved in the same form. We probably still need some way to separate "pure" expressions from the rest though. What's your idea in this regard?
I'm not aware of restrictions that fall on sample/load instructions that don't apply to pure mathematical expressions. What restrictions are you aware of?
On Fri, Aug 13, 2021 at 6:00 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 8/13/21 9:03 AM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
For reference: originally the plan was for HLSL_IR_EXPR to only cover "mathematical" expressions, or more specifically, pure expressions that could be transformed and moved around (e.g. hoisted out of a loop) without any problem. In that world statements that don't fall under that banner, like texture sampling instructions, would not be expressions.
My original setup was inspired by the Mesa GLSL frontend (at the time). It looks like NIR also followed along the same line, with what they call ALU instructions covering our expressions and intrinsic instructions basically matching everything that isn't an ALU instruction or a jump (or SSA stuff).
Now, that concept doesn't necessarily need to be preserved in the same form. We probably still need some way to separate "pure" expressions from the rest though. What's your idea in this regard?
I'm not aware of restrictions that fall on sample/load instructions that don't apply to pure mathematical expressions. What restrictions are you aware of?
Basically, you can't necessarily pull those instructions out of loops or conditionals, duplicate them when flattening conditionals, CSE them out etc. Usually those are problematic only when there are also out-of-pipeline stores (UAVs, shared memory) in the same shader. See https://people.freedesktop.org/~cwabbott0/nir-docs/instructions.html#intrins... for an overview from the NIR perspective. Confusingly, NIR intrinsic instructions are not the same thing as HLSL intrinsic functions (https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl...) as the latter are simply functions predefined in HLSL, which would map to one or more NIR instructions, ALU or otherwise.
Now, maybe we don't need to make any of those "sensitive" transformations and we avoid the entire issue altogether, but it seems reasonable to be defensive and provide some way in the IR or the compiler to distinguish those instructions from the "safe" ones.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 119 +++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 36 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 5f23f345..db340a78 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -264,12 +264,54 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst return false; }
-static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +/* Helper for split_array_copies() and split_struct_copies(). Inserts new + * instructions right before "store". */ +static bool split_copy(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + const struct hlsl_ir_load *load, const unsigned int offset, struct hlsl_type *type) +{ + struct hlsl_ir_node *offset_instr, *add; + struct hlsl_ir_store *split_store; + struct hlsl_ir_load *split_load; + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_uint_constant(ctx, offset, store->node.loc))) + return false; + list_add_before(&store->node.entry, &c->node.entry); + + offset_instr = &c->node; + if (load->src.offset.node) + { + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, load->src.offset.node, &c->node))) + return false; + list_add_before(&store->node.entry, &add->entry); + offset_instr = add; + } + if (!(split_load = hlsl_new_load(ctx, load->src.var, offset_instr, type, store->node.loc))) + return false; + list_add_before(&store->node.entry, &split_load->node.entry); + + offset_instr = &c->node; + if (store->lhs.offset.node) + { + if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, store->lhs.offset.node, &c->node))) + return false; + list_add_before(&store->node.entry, &add->entry); + offset_instr = add; + } + + if (!(split_store = hlsl_new_store(ctx, store->lhs.var, offset_instr, &split_load->node, 0, store->node.loc))) + return false; + list_add_before(&store->node.entry, &split_store->node.entry); + + return true; +} + +static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { - const struct hlsl_struct_field *field; - const struct hlsl_ir_load *rhs_load; const struct hlsl_ir_node *rhs; + struct hlsl_type *element_type; const struct hlsl_type *type; + unsigned int element_size, i; struct hlsl_ir_store *store;
if (instr->type != HLSL_IR_STORE) @@ -278,46 +320,45 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr store = hlsl_ir_store(instr); rhs = store->rhs.node; type = rhs->data_type; - if (type->type != HLSL_CLASS_STRUCT) + if (type->type != HLSL_CLASS_ARRAY) return false; + element_type = type->e.array.type; + element_size = element_type->reg_size;
- rhs_load = hlsl_ir_load(rhs); - - LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + for (i = 0; i < type->e.array.elements_count; ++i) { - struct hlsl_ir_store *field_store; - struct hlsl_ir_node *offset, *add; - struct hlsl_ir_load *field_load; - struct hlsl_ir_constant *c; - - if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, instr->loc))) + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i * element_size, element_type)) return false; - list_add_before(&instr->entry, &c->node.entry); + }
- offset = &c->node; - if (rhs_load->src.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, rhs_load->src.offset.node, &c->node))) - return false; - list_add_before(&instr->entry, &add->entry); - offset = add; - } - if (!(field_load = hlsl_new_load(ctx, rhs_load->src.var, offset, field->type, instr->loc))) - return false; - list_add_before(&instr->entry, &field_load->node.entry); + /* Remove the store instruction, so that we can split structs which contain + * other structs. Although assignments produce a value, we don't allow + * HLSL_IR_STORE to be used as a source. */ + list_remove(&store->node.entry); + hlsl_free_instr(&store->node); + return true; +}
- offset = &c->node; - if (store->lhs.offset.node) - { - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, store->lhs.offset.node, &c->node))) - return false; - list_add_before(&instr->entry, &add->entry); - offset = add; - } +static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + const struct hlsl_struct_field *field; + const struct hlsl_ir_node *rhs; + const struct hlsl_type *type; + struct hlsl_ir_store *store;
- if (!(field_store = hlsl_new_store(ctx, store->lhs.var, offset, &field_load->node, 0, instr->loc))) + if (instr->type != HLSL_IR_STORE) + return false; + + store = hlsl_ir_store(instr); + rhs = store->rhs.node; + type = rhs->data_type; + if (type->type != HLSL_CLASS_STRUCT) + return false; + + LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) + { + if (!split_copy(ctx, store, hlsl_ir_load(rhs), field->reg_offset, field->type)) return false; - list_add_before(&instr->entry, &field_store->node.entry); }
/* Remove the store instruction, so that we can split structs which contain @@ -1151,6 +1192,7 @@ struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { struct hlsl_ir_var *var; + bool progress;
list_move_head(entry_func->body, &ctx->static_initializers);
@@ -1197,7 +1239,12 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun }
while (transform_ir(ctx, fold_redundant_casts, entry_func->body, NULL)); - while (transform_ir(ctx, split_struct_copies, entry_func->body, NULL)); + do + { + progress = transform_ir(ctx, split_array_copies, entry_func->body, NULL); + progress |= transform_ir(ctx, split_struct_copies, entry_func->body, NULL); + } + while (progress); while (transform_ir(ctx, fold_constants, entry_func->body, NULL));
if (ctx->profile->major_version < 4)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 62dc535d..7f12dd20 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1211,9 +1211,6 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, case HLSL_IR_SWIZZLE: dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr)); break; - - default: - vkd3d_string_buffer_printf(buffer, "<No dump function for %s>", hlsl_node_type_to_string(instr->type)); } }
@@ -1361,9 +1358,6 @@ void hlsl_free_instr(struct hlsl_ir_node *node) case HLSL_IR_SWIZZLE: free_ir_swizzle(hlsl_ir_swizzle(node)); break; - - default: - FIXME("Unsupported node type %s.\n", hlsl_node_type_to_string(node->type)); } }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v4 (Matteo): Get rid of the '\n' at the end of the hlsl_fixme() messages.
libs/vkd3d-shader/hlsl.c | 23 ++++++++++++++--- libs/vkd3d-shader/hlsl.h | 3 +++ libs/vkd3d-shader/hlsl.y | 32 +++++++++++++----------- libs/vkd3d-shader/hlsl_sm1.c | 10 +++++--- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 5 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 7f12dd20..3544b9d6 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -55,6 +55,23 @@ void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, va_end(args); }
+void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, const char *fmt, ...) +{ + struct vkd3d_string_buffer *string; + va_list args; + + va_start(args, fmt); + string = hlsl_get_string_buffer(ctx); + vkd3d_string_buffer_printf(string, "Aborting due to not yet implemented feature: "); + vkd3d_string_buffer_vprintf(string, fmt, args); + vkd3d_shader_error(ctx->message_context, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer); + hlsl_release_string_buffer(ctx, string); + va_end(args); + + if (!ctx->result) + ctx->result = VKD3D_ERROR_NOT_IMPLEMENTED; +} + bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var) { struct hlsl_scope *scope = ctx->cur_scope; @@ -1031,7 +1048,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "}"); }
-static const char *debug_expr_op(const struct hlsl_ir_expr *expr) +const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) { static const char *const op_names[] = { @@ -1082,14 +1099,14 @@ static const char *debug_expr_op(const struct hlsl_ir_expr *expr) [HLSL_OP3_LERP] = "lerp", };
- return op_names[expr->op]; + return op_names[op]; }
static void dump_ir_expr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_expr *expr) { unsigned int i;
- vkd3d_string_buffer_printf(buffer, "%s (", debug_expr_op(expr)); + vkd3d_string_buffer_printf(buffer, "%s (", debug_hlsl_expr_op(expr->op)); for (i = 0; i < 3 && expr->operands[i].node; ++i) { dump_src(buffer, &expr->operands[i]); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 4a4af5d1..da309a6b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -590,6 +590,7 @@ static inline void hlsl_release_string_buffer(struct hlsl_ctx *ctx, struct vkd3d vkd3d_string_buffer_release(&ctx->string_buffers, buffer); }
+const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); const char *debug_hlsl_writemask(unsigned int writemask);
@@ -651,6 +652,8 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); +void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, + const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4); void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ade78da6..5f1e9167 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1213,7 +1213,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) { - FIXME("Cast on the lhs.\n"); + hlsl_fixme(ctx, lhs->loc, "Cast on the LHS."); vkd3d_free(store); return NULL; } @@ -1223,7 +1223,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in unsigned int width, s = swizzle->swizzle;
if (lhs->data_type->type == HLSL_CLASS_MATRIX) - FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n"); + hlsl_fixme(ctx, lhs->loc, "Matrix assignment with a writemask.");
if (!invert_swizzle(&s, &writemask, &width)) { @@ -1338,7 +1338,9 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru list_add_tail(list, &store->node.entry); } else - FIXME("Initializing with "mismatched" fields is not supported yet.\n"); + { + hlsl_fixme(ctx, node->loc, "Implicit cast in structure initializer."); + } }
vkd3d_free(initializer->args); @@ -1502,14 +1504,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t } if (v->arrays.count) { - FIXME("Initializing arrays is not supported yet.\n"); + hlsl_fixme(ctx, v->loc, "Array initializer."); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; } if (v->initializer.args_count > 1) { - FIXME("Complex initializers are not supported yet.\n"); + hlsl_fixme(ctx, v->loc, "Complex initializer."); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; @@ -1786,7 +1788,7 @@ hlsl_prog: | hlsl_prog declaration_statement { if (!list_empty($2)) - FIXME("Uniform initializer.\n"); + hlsl_fixme(ctx, @2, "Uniform initializer."); hlsl_free_instr_list($2); } | hlsl_prog preproc_directive @@ -2769,7 +2771,7 @@ postfix_expr: }
if ($2->type == HLSL_CLASS_MATRIX) - FIXME("Matrix constructors are not supported yet.\n"); + hlsl_fixme(ctx, @2, "Matrix constructor.");
sprintf(name, "<constructor-%x>", counter++); if (!(var = hlsl_new_synthetic_var(ctx, name, $2, @2))) @@ -2931,11 +2933,11 @@ shift_expr: add_expr | shift_expr OP_LEFTSHIFT add_expr { - FIXME("Left shift.\n"); + hlsl_fixme(ctx, @$, "Left shift."); } | shift_expr OP_RIGHTSHIFT add_expr { - FIXME("Right shift.\n"); + hlsl_fixme(ctx, @$, "Right shift."); }
relational_expr: @@ -2972,42 +2974,42 @@ bitand_expr: equality_expr | bitand_expr '&' equality_expr { - FIXME("Bitwise AND.\n"); + hlsl_fixme(ctx, @$, "Bitwise AND."); }
bitxor_expr: bitand_expr | bitxor_expr '^' bitand_expr { - FIXME("Bitwise XOR.\n"); + hlsl_fixme(ctx, @$, "Bitwise XOR."); }
bitor_expr: bitxor_expr | bitor_expr '|' bitxor_expr { - FIXME("Bitwise OR.\n"); + hlsl_fixme(ctx, @$, "Bitwise OR."); }
logicand_expr: bitor_expr | logicand_expr OP_AND bitor_expr { - FIXME("Logical AND.\n"); + hlsl_fixme(ctx, @$, "Logical AND."); }
logicor_expr: logicand_expr | logicor_expr OP_OR logicand_expr { - FIXME("Logical OR.\n"); + hlsl_fixme(ctx, @$, "Logical OR."); }
conditional_expr: logicor_expr | logicor_expr '?' expr ':' assignment_expr { - FIXME("Ternary operator.\n"); + hlsl_fixme(ctx, @$, "Ternary operator."); }
assignment_expr: diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 85d54ac2..b9a681a4 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -606,7 +606,8 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
if (instr->data_type->base_type != HLSL_TYPE_FLOAT) { - FIXME("Non-float operations need to be lowered.\n"); + /* These need to be lowered. */ + hlsl_fixme(ctx, instr->loc, "SM1 non-float expression."); return; }
@@ -636,7 +637,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b break;
default: - FIXME("Unhandled op %u.\n", expr->op); + hlsl_fixme(ctx, instr->loc, "SM1 "%s" expression.", debug_hlsl_expr_op(expr->op)); break; } } @@ -765,8 +766,9 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b { if (instr->data_type->type == HLSL_CLASS_MATRIX) { - FIXME("Matrix operations need to be lowered.\n"); - break; + /* These need to be lowered. */ + hlsl_fixme(ctx, instr->loc, "SM1 matrix expression."); + continue; }
assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index a9c4e758..85503800 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -112,6 +112,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN = 5014, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS = 5015, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION = 5016, + VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED = 5017,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 24 +++++++++++++++--- libs/vkd3d-shader/hlsl.h | 3 +++ libs/vkd3d-shader/hlsl.y | 32 +++++++++++++----------- libs/vkd3d-shader/hlsl_sm1.c | 10 +++++--- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 5 files changed, 48 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 7f12dd20..caccf5bb 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -55,6 +55,24 @@ void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, va_end(args); }
+void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, const char *fmt, ...) +{ + struct vkd3d_string_buffer *string; + va_list args; + + va_start(args, fmt); + string = hlsl_get_string_buffer(ctx); + vkd3d_string_buffer_printf(string, "Aborting due to not yet implemented feature: "); + vkd3d_string_buffer_vprintf(string, fmt, args); + string->buffer[--string->content_size] = 0; + vkd3d_shader_error(ctx->message_context, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "%s", string->buffer); + hlsl_release_string_buffer(ctx, string); + va_end(args); + + if (!ctx->result) + ctx->result = VKD3D_ERROR_NOT_IMPLEMENTED; +} + bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var) { struct hlsl_scope *scope = ctx->cur_scope; @@ -1031,7 +1049,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "}"); }
-static const char *debug_expr_op(const struct hlsl_ir_expr *expr) +const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) { static const char *const op_names[] = { @@ -1082,14 +1100,14 @@ static const char *debug_expr_op(const struct hlsl_ir_expr *expr) [HLSL_OP3_LERP] = "lerp", };
- return op_names[expr->op]; + return op_names[op]; }
static void dump_ir_expr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_expr *expr) { unsigned int i;
- vkd3d_string_buffer_printf(buffer, "%s (", debug_expr_op(expr)); + vkd3d_string_buffer_printf(buffer, "%s (", debug_hlsl_expr_op(expr->op)); for (i = 0; i < 3 && expr->operands[i].node; ++i) { dump_src(buffer, &expr->operands[i]); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 4a4af5d1..da309a6b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -590,6 +590,7 @@ static inline void hlsl_release_string_buffer(struct hlsl_ctx *ctx, struct vkd3d vkd3d_string_buffer_release(&ctx->string_buffers, buffer); }
+const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); const char *debug_hlsl_writemask(unsigned int writemask);
@@ -651,6 +652,8 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var
void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); +void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, + const char *fmt, ...) VKD3D_PRINTF_FUNC(3, 4); void hlsl_warning(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error, const char *fmt, ...) VKD3D_PRINTF_FUNC(4, 5); void hlsl_note(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ade78da6..73fc846c 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1213,7 +1213,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in { if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) { - FIXME("Cast on the lhs.\n"); + hlsl_fixme(ctx, lhs->loc, "Cast on the LHS.\n"); vkd3d_free(store); return NULL; } @@ -1223,7 +1223,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in unsigned int width, s = swizzle->swizzle;
if (lhs->data_type->type == HLSL_CLASS_MATRIX) - FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n"); + hlsl_fixme(ctx, lhs->loc, "Matrix assignment with a writemask.\n");
if (!invert_swizzle(&s, &writemask, &width)) { @@ -1338,7 +1338,9 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru list_add_tail(list, &store->node.entry); } else - FIXME("Initializing with "mismatched" fields is not supported yet.\n"); + { + hlsl_fixme(ctx, node->loc, "Implicit cast in structure initializer.\n"); + } }
vkd3d_free(initializer->args); @@ -1502,14 +1504,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t } if (v->arrays.count) { - FIXME("Initializing arrays is not supported yet.\n"); + hlsl_fixme(ctx, v->loc, "Array initializer.\n"); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; } if (v->initializer.args_count > 1) { - FIXME("Complex initializers are not supported yet.\n"); + hlsl_fixme(ctx, v->loc, "Complex initializer.\n"); free_parse_initializer(&v->initializer); vkd3d_free(v); continue; @@ -1786,7 +1788,7 @@ hlsl_prog: | hlsl_prog declaration_statement { if (!list_empty($2)) - FIXME("Uniform initializer.\n"); + hlsl_fixme(ctx, @2, "Uniform initializer.\n"); hlsl_free_instr_list($2); } | hlsl_prog preproc_directive @@ -2769,7 +2771,7 @@ postfix_expr: }
if ($2->type == HLSL_CLASS_MATRIX) - FIXME("Matrix constructors are not supported yet.\n"); + hlsl_fixme(ctx, @2, "Matrix constructor.\n");
sprintf(name, "<constructor-%x>", counter++); if (!(var = hlsl_new_synthetic_var(ctx, name, $2, @2))) @@ -2931,11 +2933,11 @@ shift_expr: add_expr | shift_expr OP_LEFTSHIFT add_expr { - FIXME("Left shift.\n"); + hlsl_fixme(ctx, @$, "Left shift.\n"); } | shift_expr OP_RIGHTSHIFT add_expr { - FIXME("Right shift.\n"); + hlsl_fixme(ctx, @$, "Right shift.\n"); }
relational_expr: @@ -2972,42 +2974,42 @@ bitand_expr: equality_expr | bitand_expr '&' equality_expr { - FIXME("Bitwise AND.\n"); + hlsl_fixme(ctx, @$, "Bitwise AND.\n"); }
bitxor_expr: bitand_expr | bitxor_expr '^' bitand_expr { - FIXME("Bitwise XOR.\n"); + hlsl_fixme(ctx, @$, "Bitwise XOR.\n"); }
bitor_expr: bitxor_expr | bitor_expr '|' bitxor_expr { - FIXME("Bitwise OR.\n"); + hlsl_fixme(ctx, @$, "Bitwise OR.\n"); }
logicand_expr: bitor_expr | logicand_expr OP_AND bitor_expr { - FIXME("Logical AND.\n"); + hlsl_fixme(ctx, @$, "Logical AND.\n"); }
logicor_expr: logicand_expr | logicor_expr OP_OR logicand_expr { - FIXME("Logical OR.\n"); + hlsl_fixme(ctx, @$, "Logical OR.\n"); }
conditional_expr: logicor_expr | logicor_expr '?' expr ':' assignment_expr { - FIXME("Ternary operator.\n"); + hlsl_fixme(ctx, @$, "Ternary operator.\n"); }
assignment_expr: diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 85d54ac2..48a504da 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -606,7 +606,8 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
if (instr->data_type->base_type != HLSL_TYPE_FLOAT) { - FIXME("Non-float operations need to be lowered.\n"); + /* These need to be lowered. */ + hlsl_fixme(ctx, instr->loc, "SM1 non-float expression.\n"); return; }
@@ -636,7 +637,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b break;
default: - FIXME("Unhandled op %u.\n", expr->op); + hlsl_fixme(ctx, instr->loc, "SM1 "%s" expression.\n", debug_hlsl_expr_op(expr->op)); break; } } @@ -765,8 +766,9 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b { if (instr->data_type->type == HLSL_CLASS_MATRIX) { - FIXME("Matrix operations need to be lowered.\n"); - break; + /* These need to be lowered. */ + hlsl_fixme(ctx, instr->loc, "SM1 matrix expression.\n"); + continue; }
assert(instr->data_type->type == HLSL_CLASS_SCALAR || instr->data_type->type == HLSL_CLASS_VECTOR); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index a9c4e758..85503800 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -112,6 +112,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN = 5014, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS = 5015, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION = 5016, + VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED = 5017,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, };