Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- v3: * Fix optimization passes order. * Rename lower_cast_to_bool() to lower_casts_to_bool(). --- libs/vkd3d-shader/hlsl_codegen.c | 32 +++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_constant_ops.c | 9 ++------ libs/vkd3d-shader/hlsl_sm4.c | 3 ++- 3 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2b05264c..72c00430 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -750,6 +750,37 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi return true; }
+static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_type *type = instr->data_type, *arg_type; + struct hlsl_ir_constant *zero; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_CAST) + return false; + arg_type = expr->operands[0].node->data_type; + if (type->type > HLSL_CLASS_VECTOR || arg_type->type > HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_BOOL) + return false; + + /* Narrowing casts should have already been lowered. */ + assert(type->dimx == arg_type->dimx); + + zero = hlsl_new_constant(ctx, arg_type, &instr->loc); + if (!zero) + return false; + list_add_before(&instr->entry, &zero->node.entry); + + expr->op = HLSL_OP2_NEQUAL; + hlsl_src_from_node(&expr->operands[1], &zero->node); + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -1655,6 +1686,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry } while (progress); transform_ir(ctx, lower_narrowing_casts, body, NULL); + transform_ir(ctx, lower_casts_to_bool, body, NULL); do { progress = transform_ir(ctx, hlsl_fold_constants, body, NULL); diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index e282dbd4..5cac4bde 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -27,7 +27,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct int32_t i; double d; float f; - bool b;
if (dst->node.data_type->dimx != src->node.data_type->dimx || dst->node.data_type->dimy != src->node.data_type->dimy) @@ -47,7 +46,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct i = src->value[k].f; f = src->value[k].f; d = src->value[k].f; - b = !!src->value[k].f; break;
case HLSL_TYPE_DOUBLE: @@ -55,7 +53,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct i = src->value[k].d; f = src->value[k].d; d = src->value[k].d; - b = !!src->value[k].d; break;
case HLSL_TYPE_INT: @@ -63,7 +60,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct i = src->value[k].i; f = src->value[k].i; d = src->value[k].i; - b = !!src->value[k].i; break;
case HLSL_TYPE_UINT: @@ -71,7 +67,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct i = src->value[k].u; f = src->value[k].u; d = src->value[k].u; - b = !!src->value[k].u; break;
case HLSL_TYPE_BOOL: @@ -79,7 +74,6 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct i = !!src->value[k].u; f = !!src->value[k].u; d = !!src->value[k].u; - b = !!src->value[k].u; break;
default: @@ -107,7 +101,8 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct break;
case HLSL_TYPE_BOOL: - dst->value[k].u = b ? ~0u : 0; + /* Casts to bool should have already been lowered. */ + assert(0); break;
default: diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 872118c1..f3530084 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1540,7 +1540,8 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_BOOL: - hlsl_fixme(ctx, &expr->node.loc, "SM4 cast to bool.\n"); + /* Casts to bool should have already been lowered. */ + assert(0); break;
default:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index f3530084..90026fb6 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1808,6 +1808,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_MUL, &expr->node, arg1, arg2); break;
+ case HLSL_TYPE_INT: case HLSL_TYPE_UINT: /* Using IMUL instead of UMUL because we're taking the low * bits, and the native compiler generates IMUL. */
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 90026fb6..11a59804 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1608,6 +1608,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: write_sm4_unary_op(buffer, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); break;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 11a59804..bbd43299 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1668,6 +1668,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, write_sm4_binary_op(buffer, VKD3D_SM4_OP_DIV, &expr->node, arg1, arg2); break;
+ case HLSL_TYPE_UINT: + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_UDIV, &expr->node, 0, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 %s division expression.", dst_type_string->buffer); }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Makefile.am | 1 - libs/vkd3d-shader/hlsl_sm4.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am index f49f9642..2c049cb5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -318,7 +318,6 @@ SHADER_TEST_LOG_COMPILER = tests/shader_runner XFAIL_TESTS = \ tests/arithmetic-float.shader_test \ tests/arithmetic-int.shader_test \ - tests/arithmetic-uint.shader_test \ tests/bitwise.shader_test \ tests/cast-to-float.shader_test \ tests/cast-to-half.shader_test \ diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index bbd43299..73d94cf2 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1806,6 +1806,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, } break;
+ case HLSL_OP2_MOD: + switch (dst_type->base_type) + { + case HLSL_TYPE_UINT: + write_sm4_binary_op_with_two_destinations(buffer, VKD3D_SM4_OP_UDIV, &expr->node, 1, arg1, arg2); + break; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s modulus expression.", dst_type_string->buffer); + } + break; + case HLSL_OP2_MUL: switch (dst_type->base_type) {
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 73d94cf2..12fe319d 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1763,6 +1763,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx,
case HLSL_OP2_LSHIFT: assert(type_is_integer(dst_type)); + assert(dst_type->base_type != HLSL_TYPE_BOOL); write_sm4_binary_op(buffer, VKD3D_SM4_OP_ISHL, &expr->node, arg1, arg2); break;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Makefile.am | 1 - libs/vkd3d-shader/hlsl_sm4.c | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am index 2c049cb5..f08bb926 100644 --- a/Makefile.am +++ b/Makefile.am @@ -318,7 +318,6 @@ SHADER_TEST_LOG_COMPILER = tests/shader_runner XFAIL_TESTS = \ tests/arithmetic-float.shader_test \ tests/arithmetic-int.shader_test \ - tests/bitwise.shader_test \ tests/cast-to-float.shader_test \ tests/cast-to-half.shader_test \ tests/cast-to-int.shader_test \ diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 12fe319d..f00ec815 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1864,6 +1864,13 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break; }
+ case HLSL_OP2_RSHIFT: + assert(type_is_integer(dst_type)); + assert(dst_type->base_type != HLSL_TYPE_BOOL); + write_sm4_binary_op(buffer, dst_type->base_type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, + &expr->node, arg1, arg2); + break; + default: hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); }
On Wed, Apr 6, 2022 at 3:57 PM Giovanni Mascellani gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
v3:
- Fix optimization passes order.
- Rename lower_cast_to_bool() to lower_casts_to_bool().
libs/vkd3d-shader/hlsl_codegen.c | 32 +++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl_constant_ops.c | 9 ++------ libs/vkd3d-shader/hlsl_sm4.c | 3 ++- 3 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 872118c1..f3530084 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1540,7 +1540,8 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_BOOL:
hlsl_fixme(ctx, &expr->node.loc, "SM4 cast to bool.\n");
/* Casts to bool should have already been lowered. */
assert(0); break; default:
So, this is fine of course, but I really think it would be nicer with the comment "inside" the assert:
assert(!"Casts to bool should have already been lowered.");
This patch also conflicts (pretty trivially) with mine from earlier today, I'll probably resend it after going through the series.