-- v9: vkd3d-shader/hlsl: Handle 'texkill' discard type for sm4+. vkd3d-shader/hlsl: Parse clip() function. tests: Add some tests for clip(). vkd3d-shader/hlsl: Add a parameter for jump nodes and use it for 'discard'.
From: Nikolay Sivov nsivov@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 10 ++++++---- libs/vkd3d-shader/hlsl.h | 4 +++- libs/vkd3d-shader/hlsl.y | 13 +++++++++---- libs/vkd3d-shader/hlsl_codegen.c | 11 +++++++++-- libs/vkd3d-shader/tpf.c | 8 +------- 5 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index ba5bcfbf..6f10bf16 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1432,7 +1432,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v }
struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, - const struct vkd3d_shader_location *loc) + struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc) { struct hlsl_ir_jump *jump;
@@ -1440,6 +1440,7 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type return NULL; init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); jump->type = type; + hlsl_src_from_node(&jump->condition, condition); return &jump->node; }
@@ -1585,9 +1586,9 @@ static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_ma return dst; }
-static struct hlsl_ir_node *clone_jump(struct hlsl_ctx *ctx, struct hlsl_ir_jump *src) +static struct hlsl_ir_node *clone_jump(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_jump *src) { - return hlsl_new_jump(ctx, src->type, &src->node.loc); + return hlsl_new_jump(ctx, src->type, map_instr(map, src->condition.node), &src->node.loc); }
static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_load *src) @@ -1728,7 +1729,7 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, return clone_index(ctx, map, hlsl_ir_index(instr));
case HLSL_IR_JUMP: - return clone_jump(ctx, hlsl_ir_jump(instr)); + return clone_jump(ctx, map, hlsl_ir_jump(instr));
case HLSL_IR_LOAD: return clone_load(ctx, map, hlsl_ir_load(instr)); @@ -2703,6 +2704,7 @@ static void free_ir_if(struct hlsl_ir_if *if_node)
static void free_ir_jump(struct hlsl_ir_jump *jump) { + hlsl_src_remove(&jump->condition); vkd3d_free(jump); }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index a797ef6a..bae37744 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -566,6 +566,8 @@ struct hlsl_ir_jump { struct hlsl_ir_node node; enum hlsl_ir_jump_type type; + /* Argument used for HLSL_IR_JUMP_DISCARD. */ + struct hlsl_src condition; };
struct hlsl_ir_swizzle @@ -1120,7 +1122,7 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, - enum hlsl_ir_jump_type type, const struct vkd3d_shader_location *loc); + enum hlsl_ir_jump_type type, struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc);
void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 0e07fe57..1058a559 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -421,7 +421,7 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_lis
hlsl_block_init(&then_block);
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, &condition->loc))) + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &condition->loc))) return false; hlsl_block_add_instr(&then_block, jump);
@@ -656,7 +656,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct list *instrs, hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Void functions cannot return a value."); }
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_RETURN, loc))) + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_RETURN, NULL, loc))) return false; list_add_tail(instrs, &jump->entry);
@@ -5736,11 +5736,16 @@ jump_statement: discard_statement: KW_DISCARD ';' { - struct hlsl_ir_node *discard; + struct hlsl_ir_node *discard, *c;
if (!($$ = make_empty_list(ctx))) YYABORT; - if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD, &@1))) + + if (!(c = hlsl_new_uint_constant(ctx, ~0u, &@1))) + return false; + list_add_tail($$, &c->entry); + + if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD, c, &@1))) return false; list_add_tail($$, &discard->entry); } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 96b4cb66..ba624afc 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -666,7 +666,7 @@ static void insert_early_return_break(struct hlsl_ctx *ctx, return; list_add_after(&cf_instr->entry, &load->node.entry);
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, &cf_instr->loc))) + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &cf_instr->loc))) return; hlsl_block_add_instr(&then_block, jump);
@@ -2849,8 +2849,15 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop index->idx.node->last_read = last_read; break; } - case HLSL_IR_CONSTANT: case HLSL_IR_JUMP: + { + struct hlsl_ir_jump *jump = hlsl_ir_jump(instr); + + if (jump->condition.node) + jump->condition.node->last_read = last_read; + break; + } + case HLSL_IR_CONSTANT: break; } } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index d066b13e..14acef22 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4782,17 +4782,11 @@ static void write_sm4_jump(struct hlsl_ctx *ctx,
case HLSL_IR_JUMP_DISCARD: { - struct sm4_register *reg = &instr.srcs[0].reg; - instr.opcode = VKD3D_SM4_OP_DISCARD | VKD3D_SM4_CONDITIONAL_NZ;
memset(&instr.srcs[0], 0, sizeof(*instr.srcs)); - instr.srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; instr.src_count = 1; - reg->type = VKD3D_SM4_RT_IMMCONST; - reg->dim = VKD3D_SM4_DIMENSION_SCALAR; - reg->immconst_uint[0] = ~0u; - + sm4_src_from_node(&instr.srcs[0], jump->condition.node, VKD3DSP_WRITEMASK_ALL); break; }
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- Makefile.am | 1 + tests/hlsl-clip.shader_test | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/hlsl-clip.shader_test
diff --git a/Makefile.am b/Makefile.am index 92c6d079..9b506e44 100644 --- a/Makefile.am +++ b/Makefile.am @@ -80,6 +80,7 @@ vkd3d_shader_tests = \ tests/hlsl-attributes.shader_test \ tests/hlsl-bool-cast.shader_test \ tests/hlsl-clamp.shader_test \ + tests/hlsl-clip.shader_test \ tests/hlsl-comma.shader_test \ tests/hlsl-cross.shader_test \ tests/hlsl-d3dcolor-to-ubyte4.shader_test \ diff --git a/tests/hlsl-clip.shader_test b/tests/hlsl-clip.shader_test new file mode 100644 index 00000000..d6c8b06d --- /dev/null +++ b/tests/hlsl-clip.shader_test @@ -0,0 +1,22 @@ +[pixel shader todo] +uniform float4 x; + +float4 main() : sv_target +{ + clip(x); + return x; +} + +[test] +uniform 0 float4 1 2 3 4 +todo draw quad +todo 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) +uniform 0 float4 -1 8 7 6 +todo draw quad +todo 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)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 17 +++++++++++------ libs/vkd3d-shader/hlsl.h | 5 +++-- libs/vkd3d-shader/hlsl.y | 31 ++++++++++++++++++++++++++++++- libs/vkd3d-shader/tpf.c | 2 +- 4 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6f10bf16..15a95a8e 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2147,10 +2147,11 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) { static const char * const names[] = { - "HLSL_IR_JUMP_BREAK", - "HLSL_IR_JUMP_CONTINUE", - "HLSL_IR_JUMP_DISCARD", - "HLSL_IR_JUMP_RETURN", + [HLSL_IR_JUMP_BREAK] = "HLSL_IR_JUMP_BREAK", + [HLSL_IR_JUMP_CONTINUE] = "HLSL_IR_JUMP_CONTINUE", + [HLSL_IR_JUMP_DISCARD_NEG] = "HLSL_IR_JUMP_DISCARD_NEG", + [HLSL_IR_JUMP_DISCARD_NZ] = "HLSL_IR_JUMP_DISCARD_NZ", + [HLSL_IR_JUMP_RETURN] = "HLSL_IR_JUMP_RETURN", };
assert(type < ARRAY_SIZE(names)); @@ -2419,8 +2420,12 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i vkd3d_string_buffer_printf(buffer, "continue"); break;
- case HLSL_IR_JUMP_DISCARD: - vkd3d_string_buffer_printf(buffer, "discard"); + case HLSL_IR_JUMP_DISCARD_NEG: + vkd3d_string_buffer_printf(buffer, "discard_neg"); + break; + + case HLSL_IR_JUMP_DISCARD_NZ: + vkd3d_string_buffer_printf(buffer, "discard_nz"); break;
case HLSL_IR_JUMP_RETURN: diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index bae37744..727e4ee9 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -558,7 +558,8 @@ enum hlsl_ir_jump_type { HLSL_IR_JUMP_BREAK, HLSL_IR_JUMP_CONTINUE, - HLSL_IR_JUMP_DISCARD, + HLSL_IR_JUMP_DISCARD_NEG, + HLSL_IR_JUMP_DISCARD_NZ, HLSL_IR_JUMP_RETURN, };
@@ -566,7 +567,7 @@ struct hlsl_ir_jump { struct hlsl_ir_node node; enum hlsl_ir_jump_type type; - /* Argument used for HLSL_IR_JUMP_DISCARD. */ + /* Argument used for HLSL_IR_JUMP_DISCARD_NZ and HLSL_IR_JUMP_DISCARD_NEG. */ struct hlsl_src condition; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 1058a559..9de2d7f1 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2544,6 +2544,34 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, max, params->args[2], loc); }
+static bool intrinsic_clip(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *condition, *jump; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + + condition = params->args[0]; + + if (ctx->profile->major_version < 4 && hlsl_type_component_count(condition->data_type) > 4) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, condition->data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Argument type cannot exceed 4 components, got type "%s".", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD_NEG, condition, loc))) + return false; + list_add_tail(params->instrs, &jump->entry); + + return true; +} + static bool intrinsic_cos(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3482,6 +3510,7 @@ intrinsic_functions[] = {"asfloat", 1, true, intrinsic_asfloat}, {"asuint", -1, true, intrinsic_asuint}, {"clamp", 3, true, intrinsic_clamp}, + {"clip", 1, true, intrinsic_clip}, {"cos", 1, true, intrinsic_cos}, {"cross", 2, true, intrinsic_cross}, {"ddx", 1, true, intrinsic_ddx}, @@ -5745,7 +5774,7 @@ discard_statement: return false; list_add_tail($$, &c->entry);
- if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD, c, &@1))) + if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD_NZ, c, &@1))) return false; list_add_tail($$, &discard->entry); } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 14acef22..9a4e1160 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4780,7 +4780,7 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, instr.opcode = VKD3D_SM4_OP_BREAK; break;
- case HLSL_IR_JUMP_DISCARD: + case HLSL_IR_JUMP_DISCARD_NZ: { instr.opcode = VKD3D_SM4_OP_DISCARD | VKD3D_SM4_CONDITIONAL_NZ;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/d3dbc.c | 33 ++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl.y | 23 ++++++------- libs/vkd3d-shader/hlsl_codegen.c | 59 ++++++++++++++++++++++++++++++++ tests/hlsl-clip.shader_test | 18 +++++----- 5 files changed, 113 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index c35f8ca0..76e06333 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_DISCARD_NEG: + { + 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.h b/libs/vkd3d-shader/hlsl.h index 727e4ee9..28c7c691 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1135,6 +1135,8 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_add_load_component(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *var_instr, unsigned int comp, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9de2d7f1..07a47a7f 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -273,9 +273,6 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ return hlsl_types_are_componentwise_equal(ctx, src, dst); }
-static struct hlsl_ir_node *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, - unsigned int comp, const struct vkd3d_shader_location *loc); - static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { @@ -333,7 +330,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx);
- if (!(component_load = add_load_component(ctx, instrs, node, src_idx, loc))) + if (!(component_load = hlsl_add_load_component(ctx, instrs, node, src_idx, loc))) return NULL;
if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, loc))) @@ -663,7 +660,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct list *instrs, return true; }
-static struct hlsl_ir_node *add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, +struct hlsl_ir_node *hlsl_add_load_component(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *var_instr, unsigned int comp, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *load, *store; @@ -1284,7 +1281,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, { if (operands[j]) { - if (!(load = add_load_component(ctx, instrs, operands[j], i, loc))) + if (!(load = hlsl_add_load_component(ctx, instrs, operands[j], i, loc))) return NULL;
cell_operands[j] = load; @@ -1779,7 +1776,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in return NULL; list_add_tail(instrs, &cell->entry);
- if (!(load = add_load_component(ctx, instrs, rhs, k++, &rhs->loc))) + if (!(load = hlsl_add_load_component(ctx, instrs, rhs, k++, &rhs->loc))) return NULL;
if (!hlsl_init_deref_from_index_chain(ctx, &deref, cell)) @@ -1868,7 +1865,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_type *dst_comp_type; struct hlsl_block block;
- if (!(load = add_load_component(ctx, instrs, src, k, &src->loc))) + if (!(load = hlsl_add_load_component(ctx, instrs, src, k, &src->loc))) return;
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index); @@ -2405,7 +2402,7 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, count = hlsl_type_component_count(arg->data_type); for (i = 0; i < count; ++i) { - if (!(load = add_load_component(ctx, params->instrs, arg, i, loc))) + if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, i, loc))) return false;
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, load, mul, loc))) @@ -2449,7 +2446,7 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, count = hlsl_type_component_count(arg->data_type); for (i = 0; i < count; ++i) { - if (!(load = add_load_component(ctx, params->instrs, arg, i, loc))) + if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, i, loc))) return false;
if (!(or = add_binary_bitwise_expr(ctx, params->instrs, HLSL_OP2_BIT_OR, or, load, loc))) @@ -3062,10 +3059,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, { struct hlsl_ir_node *value1, *value2, *mul;
- if (!(value1 = add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) + if (!(value1 = hlsl_add_load_component(ctx, params->instrs, cast1, j * cast1->data_type->dimx + k, loc))) return false;
- if (!(value2 = add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) + if (!(value2 = hlsl_add_load_component(ctx, params->instrs, cast2, k * cast2->data_type->dimx + i, loc))) return false;
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, value1, value2, loc))) @@ -3421,7 +3418,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { struct hlsl_block block;
- if (!(load = add_load_component(ctx, params->instrs, arg, j * arg->data_type->dimx + i, loc))) + if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, j * arg->data_type->dimx + i, loc))) return false;
if (!hlsl_new_store_component(ctx, &block, &var_deref, i * var->data_type->dimx + j, load)) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index ba624afc..e755c256 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2584,6 +2584,61 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *zero, *bool_false, *or, *cmp, *load; + static const struct hlsl_constant_value zero_value; + struct hlsl_type *arg_type, *cmp_type; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + 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_DISCARD_NEG) + return false; + + list_init(&instrs); + + arg_type = jump->condition.node->data_type; + if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc))) + return false; + list_add_tail(&instrs, &zero->entry); + + operands[0] = jump->condition.node; + operands[1] = zero; + cmp_type = hlsl_get_numeric_type(ctx, arg_type->class, HLSL_TYPE_BOOL, arg_type->dimx, arg_type->dimy); + if (!(cmp = hlsl_new_expr(ctx, HLSL_OP2_LESS, operands, cmp_type, &instr->loc))) + return false; + list_add_tail(&instrs, &cmp->entry); + + if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) + return false; + list_add_tail(&instrs, &bool_false->entry); + + or = bool_false; + + count = hlsl_type_component_count(cmp_type); + for (i = 0; i < count; ++i) + { + if (!(load = hlsl_add_load_component(ctx, &instrs, cmp, i, &instr->loc))) + return false; + + if (!(or = hlsl_new_binary_expr(ctx, HLSL_OP2_LOGIC_OR, or, load))) + return NULL; + list_add_tail(&instrs, &or->entry); + } + + list_move_tail(&instr->entry, &instrs); + hlsl_src_remove(&jump->condition); + hlsl_src_from_node(&jump->condition, or); + jump->type = HLSL_IR_JUMP_DISCARD_NZ; + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -4058,6 +4113,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_discard_neg, 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)
On Tue Jun 13 17:38:41 2023 +0000, Zebediah Figura wrote:
Yes, I mean the type conversion logic. In this case I think it should just be a matter of creating a zero constant with the same type as the input; we do that elsewhere in several places anyway.
Thanks, it makes sense now that I see it.
This merge request was approved by Zebediah Figura.
This merge request was approved by Henri Verbeet.