From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 18 ++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 34 ++++++++++++++++++++++++++++++ tests/hlsl/cast-to-int.shader_test | 4 ++-- tests/hlsl/ceil.shader_test | 8 +++---- tests/hlsl/floor.shader_test | 8 +++---- tests/hlsl/round.shader_test | 8 +++---- tests/hlsl/saturate.shader_test | 4 ++-- 7 files changed, 59 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 69fe6db89..673292aee 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1999,16 +1999,14 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b case HLSL_TYPE_UINT: switch(src_type->base_type) { + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: + /* A compilation pass applies a FLOOR operation to casts to int, so no change is necessary. */ case HLSL_TYPE_INT: case HLSL_TYPE_UINT: write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0); break;
- case HLSL_TYPE_HALF: - case HLSL_TYPE_FLOAT: - hlsl_fixme(ctx, &instr->loc, "SM1 cast from float to integer."); - break; - case HLSL_TYPE_BOOL: hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to integer."); break; @@ -2243,6 +2241,12 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
assert(instr->reg.allocated);
+ if (expr->op == HLSL_OP1_CAST) + { + write_sm1_cast(ctx, buffer, instr); + return; + } + if (instr->data_type->base_type != HLSL_TYPE_FLOAT) { /* These need to be lowered. */ @@ -2256,10 +2260,6 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b write_sm1_unary_op(ctx, buffer, D3DSIO_ABS, &instr->reg, &arg1->reg, 0, 0); break;
- case HLSL_OP1_CAST: - write_sm1_cast(ctx, buffer, instr); - break; - case HLSL_OP1_DSX: write_sm1_unary_op(ctx, buffer, D3DSIO_DSX, &instr->reg, &arg1->reg, 0, 0); break; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1fe141a34..2cfad3133 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2647,6 +2647,39 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) return false; }
+/* Append a FLOOR before a CAST to int or uint (which is written as a mere MOV). */ +static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *arg, *floor, *cast2; + 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 = expr->operands[0].node; + if (instr->data_type->base_type != HLSL_TYPE_INT && instr->data_type->base_type != HLSL_TYPE_UINT) + return false; + if (arg->data_type->base_type != HLSL_TYPE_FLOAT && arg->data_type->base_type != HLSL_TYPE_HALF) + return false; + + /* Check that the argument is not already a FLOOR */ + if (arg->type == HLSL_IR_EXPR && hlsl_ir_expr(arg)->op == HLSL_OP1_FLOOR) + return false; + + if (!(floor = hlsl_new_unary_expr(ctx, HLSL_OP1_FLOOR, arg, &instr->loc))) + return false; + hlsl_block_add_instr(block, floor); + + if (!(cast2 = hlsl_new_cast(ctx, floor, instr->data_type, &instr->loc))) + return false; + hlsl_block_add_instr(block, cast2); + + return true; +} + /* Lower DIV to RCP + MUL. */ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { @@ -4999,6 +5032,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_ternary, body); if (profile->major_version < 4) { + lower_ir(ctx, lower_casts_to_int, body); lower_ir(ctx, lower_division, body); lower_ir(ctx, lower_sqrt, body); lower_ir(ctx, lower_dot, body); diff --git a/tests/hlsl/cast-to-int.shader_test b/tests/hlsl/cast-to-int.shader_test index 9c33f776f..9a6fb58cb 100644 --- a/tests/hlsl/cast-to-int.shader_test +++ b/tests/hlsl/cast-to-int.shader_test @@ -1,4 +1,4 @@ -[pixel shader todo(sm<4)] +[pixel shader] uniform float3 f;
float4 main() : sv_target @@ -10,7 +10,7 @@ float4 main() : sv_target
[test] uniform 0 float4 10.3 11.5 12.8 13.1 -todo(sm<4) draw quad +draw quad probe all rgba (10, 11, 12, 0)
diff --git a/tests/hlsl/ceil.shader_test b/tests/hlsl/ceil.shader_test index 0082c8f4e..73ba77250 100644 --- a/tests/hlsl/ceil.shader_test +++ b/tests/hlsl/ceil.shader_test @@ -21,7 +21,7 @@ uniform 0 float4 -0.5 6.5 7.5 3.4 draw quad probe all rgba (0.0, 7.0, 8.0, 4.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -34,10 +34,10 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo(sm<4) draw quad +draw quad probe all rgba (7.0, 8.0, 0.0, 4.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform int4 u;
float4 main() : sv_target @@ -50,5 +50,5 @@ float4 main() : sv_target
[test] uniform 0 int4 -1 6 7 3 -todo(sm<4) draw quad +draw quad probe all rgba (6.0, 7.0, -1.0, 3.0) 4 diff --git a/tests/hlsl/floor.shader_test b/tests/hlsl/floor.shader_test index dc9e31f79..85abb7f6b 100644 --- a/tests/hlsl/floor.shader_test +++ b/tests/hlsl/floor.shader_test @@ -21,7 +21,7 @@ uniform 0 float4 -0.5 6.5 7.5 3.4 draw quad probe all rgba (-1.0, 6.0, 7.0, 3.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -34,11 +34,11 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo(sm<4) draw quad +draw quad probe all rgba (6.0, 7.0, -1.0, 3.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform int4 u;
float4 main() : sv_target @@ -51,5 +51,5 @@ float4 main() : sv_target
[test] uniform 0 int4 -1 6 7 3 -todo(sm<4) draw quad +draw quad probe all rgba (6.0, 7.0, -1.0, 3.0) 4 diff --git a/tests/hlsl/round.shader_test b/tests/hlsl/round.shader_test index 7b4c68cb7..b9234b010 100644 --- a/tests/hlsl/round.shader_test +++ b/tests/hlsl/round.shader_test @@ -13,7 +13,7 @@ probe all rgba (0.0, -7.0, 8.0, 3.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -26,12 +26,12 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.4 -6.6 7.6 3.4 -todo(sm<4) draw quad +draw quad probe all rgba (-7.0, 8.0, 0.0, 3.0) 4
-[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -42,5 +42,5 @@ float4 main() : sv_target
[test] uniform 0 float4 -1 0 2 10 -todo(sm<4) draw quad +draw quad probe all rgba (-1.0, 0.0, 2.0, 10.0) 4 diff --git a/tests/hlsl/saturate.shader_test b/tests/hlsl/saturate.shader_test index 6852015b2..2ed83cf66 100644 --- a/tests/hlsl/saturate.shader_test +++ b/tests/hlsl/saturate.shader_test @@ -11,7 +11,7 @@ uniform 0 float4 0.7 -0.1 0.0 0.0 todo(sm>=6) draw quad probe all rgba (0.7, 0.0, 1.0, 0.0)
-[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -22,5 +22,5 @@ float4 main() : sv_target
[test] uniform 0 float4 -2 0 2 -1 -todo(sm<4 | sm>=6) draw quad +todo(sm>=6) draw quad probe all rgba (0.0, 0.0, 1.0, 0.0)