From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 33 +++++++++++++++++++++ libs/vkd3d-shader/hlsl_codegen.c | 50 ++++++++++++++++++++++++++++++++ tests/hlsl-clip.shader_test | 18 ++++++------ 3 files changed, 92 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index c35f8ca0..1e0e7a98 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1834,6 +1834,35 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } }
+static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) +{ + const struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); + + switch (jump->type) + { + case HLSL_IR_JUMP_TEXKILL: + { + struct hlsl_reg *reg = &jump->condition.node->reg; + + struct sm1_instruction instr = + { + .opcode = VKD3D_SM1_OP_TEXKILL, + + .dst.type = D3DSPR_TEMP, + .dst.reg = reg->id, + .dst.writemask = reg->writemask, + .has_dst = 1, + }; + + write_sm1_instruction(ctx, buffer, &instr); + break; + } + + default: + hlsl_fixme(ctx, &jump->node.loc, "Jump type %s.\n", hlsl_jump_type_to_string(jump->type)); + } +} + static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { const struct hlsl_ir_load *load = hlsl_ir_load(instr); @@ -2028,6 +2057,10 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b write_sm1_expr(ctx, buffer, instr); break;
+ case HLSL_IR_JUMP: + write_sm1_jump(ctx, buffer, instr); + break; + case HLSL_IR_LOAD: write_sm1_load(ctx, buffer, instr); break; diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 06d005af..36a62f5f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2584,6 +2584,52 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static bool lower_texkill(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *zero, *bool_false, *or, *cmp, *load; + struct hlsl_ir_jump *jump; + unsigned int i, count; + struct list instrs; + + if (instr->type != HLSL_IR_JUMP) + return false; + jump = hlsl_ir_jump(instr); + if (jump->type != HLSL_IR_JUMP_TEXKILL) + return false; + + list_init(&instrs); + + if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &instr->loc))) + return false; + list_add_tail(&instrs, &zero->entry); + + if (!(cmp = hlsl_add_binary_comparison_expr(ctx, &instrs, HLSL_OP2_LESS, jump->condition.node, zero, &instr->loc))) + return false; + + if (!(bool_false = hlsl_new_bool_constant(ctx, false, &instr->loc))) + return false; + list_add_tail(&instrs, &bool_false->entry); + + or = bool_false; + + count = hlsl_type_component_count(cmp->data_type); + for (i = 0; i < count; ++i) + { + if (!(load = hlsl_add_load_component(ctx, &instrs, cmp, i, &instr->loc))) + return false; + + if (!(or = hlsl_add_binary_logical_expr(ctx, &instrs, HLSL_OP2_LOGIC_OR, or, load, &instr->loc))) + return false; + } + + list_move_tail(&instr->entry, &instrs); + hlsl_src_remove(&jump->condition); + hlsl_src_from_node(&jump->condition, or); + jump->type = HLSL_IR_JUMP_DISCARD; + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -4058,6 +4104,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point "%s" is missing a [numthreads] attribute.", entry_func->func->name);
+ if (profile->major_version >= 4) + { + hlsl_transform_ir(ctx, lower_texkill, body, NULL); + } hlsl_transform_ir(ctx, lower_broadcasts, body, NULL); while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); do diff --git a/tests/hlsl-clip.shader_test b/tests/hlsl-clip.shader_test index d6c8b06d..f9859e1b 100644 --- a/tests/hlsl-clip.shader_test +++ b/tests/hlsl-clip.shader_test @@ -1,4 +1,4 @@ -[pixel shader todo] +[pixel shader] uniform float4 x;
float4 main() : sv_target @@ -9,14 +9,14 @@ float4 main() : sv_target
[test] uniform 0 float4 1 2 3 4 -todo draw quad -todo probe all rgba (1, 2, 3, 4) +draw quad +probe all rgba (1, 2, 3, 4) uniform 0 float4 9 8 7 6 -todo draw quad -todo probe all rgba (9, 8, 7, 6) +draw quad +probe all rgba (9, 8, 7, 6) uniform 0 float4 -1 8 7 6 -todo draw quad -todo probe all rgba (9, 8, 7, 6) +draw quad +probe all rgba (9, 8, 7, 6) uniform 0 float4 9 0 7 6 -todo draw quad -todo probe all rgba (9, 0, 7, 6) +draw quad +probe all rgba (9, 0, 7, 6)