From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl_codegen.c | 3 ++- libs/vkd3d-shader/hlsl_constant_ops.c | 31 ++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 28b2ff1b..3c1dd08d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -800,7 +800,8 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl_deref *deref); struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref);
-bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); +bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context);
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1a5e9055..bc7f0a62 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1946,7 +1946,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry transform_ir(ctx, lower_casts_to_bool, body, NULL); do { - progress = transform_ir(ctx, hlsl_fold_constants, body, NULL); + progress = transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); + progress |= transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL); progress |= copy_propagation_execute(ctx, body); progress |= transform_ir(ctx, remove_trivial_swizzles, body, NULL); } diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index d8787c21..64067397 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -369,7 +369,7 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
-bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; struct hlsl_ir_expr *expr; @@ -447,3 +447,32 @@ bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void } return success; } + +bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_constant *value, *res; + struct hlsl_ir_swizzle *swizzle; + unsigned int i, swizzle_bits; + + if (instr->type != HLSL_IR_SWIZZLE) + return false; + swizzle = hlsl_ir_swizzle(instr); + if (swizzle->val.node->type != HLSL_IR_CONSTANT) + return false; + value = hlsl_ir_constant(swizzle->val.node); + + if (!(res = hlsl_alloc(ctx, sizeof(*res)))) + return false; + init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc); + + swizzle_bits = swizzle->swizzle; + for (i = 0; i < swizzle->node.data_type->dimx; ++i) + { + res->value[i] = value->value[swizzle_bits & 3]; + swizzle_bits >>= 2; + } + + list_add_before(&swizzle->node.entry, &res->node.entry); + hlsl_replace_node(&swizzle->node, &res->node); + return true; +}
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 64067397..95bed02a 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -369,6 +369,35 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
+static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + dst->value[k].i = max(src1->value[k].i, src2->value[k].i); + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = max(src1->value[k].u, src2->value[k].u); + break; + + default: + FIXME("Fold max for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -430,6 +459,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_mod(ctx, res, arg1, arg2); break;
+ case HLSL_OP2_MAX: + success = fold_max(ctx, res, arg1, arg2); + break; + default: FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); success = false;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 95bed02a..01f394b8 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -398,6 +398,35 @@ static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
+static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + dst->value[k].i = min(src1->value[k].i, src2->value[k].i); + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = min(src1->value[k].u, src2->value[k].u); + break; + + default: + FIXME("Fold min for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -463,6 +492,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_max(ctx, res, arg1, arg2); break;
+ case HLSL_OP2_MIN: + success = fold_min(ctx, res, arg1, arg2); + break; + default: FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); success = false;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 01f394b8..bea9864e 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -427,6 +427,32 @@ static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
+static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u ^ src2->value[k].u; + break; + + default: + FIXME("Fold bit xor for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -496,6 +522,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_min(ctx, res, arg1, arg2); break;
+ case HLSL_OP2_BIT_XOR: + success = fold_bit_xor(ctx, res, arg1, arg2); + break; + default: FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); success = false;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index bea9864e..33dc7001 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -453,6 +453,32 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
+static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u & src2->value[k].u; + break; + + default: + FIXME("Fold bit and for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -526,6 +552,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_bit_xor(ctx, res, arg1, arg2); break;
+ case HLSL_OP2_BIT_AND: + success = fold_bit_and(ctx, res, arg1, arg2); + break; + default: FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); success = false;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 33dc7001..20384180 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -479,6 +479,32 @@ static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, return true; }
+static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < dst->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u | src2->value[k].u; + break; + + default: + FIXME("Fold bit or for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; @@ -556,6 +582,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_bit_and(ctx, res, arg1, arg2); break;
+ case HLSL_OP2_BIT_OR: + success = fold_bit_or(ctx, res, arg1, arg2); + break; + default: FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); success = false;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com