-- v8: vkd3d-shader/hlsl: Handle 'texkill' jump type. vkd3d-shader/hlsl: Parse clip() function. tests: Add some tests for clip(). vkd3d-shader: Make some helpers available from hlsl.c. 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 f439c9f3..9001a75d 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 7c4e74dc..c3e76927 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 @@ -1121,7 +1123,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 209428f7..f2ecd364 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);
@@ -5731,11 +5731,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 4317604b..d2fab7c8 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 --- libs/vkd3d-shader/hlsl.c | 436 ++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 19 ++ libs/vkd3d-shader/hlsl.y | 593 +++++---------------------------------- 3 files changed, 532 insertions(+), 516 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9001a75d..e4fa5c89 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1457,6 +1457,442 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, return &loop->node; }
+enum hlsl_base_type hlsl_expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) +{ + if (t1 > HLSL_TYPE_LAST_SCALAR || t2 > HLSL_TYPE_LAST_SCALAR) { + FIXME("Unexpected base type.\n"); + return HLSL_TYPE_FLOAT; + } + if (t1 == t2) + return t1 == HLSL_TYPE_BOOL ? HLSL_TYPE_INT : t1; + if (t1 == HLSL_TYPE_DOUBLE || t2 == HLSL_TYPE_DOUBLE) + return HLSL_TYPE_DOUBLE; + if (t1 == HLSL_TYPE_FLOAT || t2 == HLSL_TYPE_FLOAT + || t1 == HLSL_TYPE_HALF || t2 == HLSL_TYPE_HALF) + return HLSL_TYPE_FLOAT; + if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) + return HLSL_TYPE_UINT; + return HLSL_TYPE_INT; +} + +static bool hlsl_expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) +{ + if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) + return false; + + /* Scalar vars can be converted to pretty much everything */ + if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) + return true; + + if (t1->class == HLSL_CLASS_VECTOR && t2->class == HLSL_CLASS_VECTOR) + return true; + + if (t1->class == HLSL_CLASS_MATRIX || t2->class == HLSL_CLASS_MATRIX) + { + /* Matrix-vector conversion is apparently allowed if either they have the same components + count or the matrix is nx1 or 1xn */ + if (t1->class == HLSL_CLASS_VECTOR || t2->class == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) + return true; + + return (t1->class == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1)) + || (t2->class == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1)); + } + + /* Both matrices */ + if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) + || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy)) + return true; + } + + return false; +} + +bool hlsl_expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, + const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) +{ + if (t1->class > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, t1))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (t2->class > HLSL_CLASS_LAST_NUMERIC) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, t2))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (!hlsl_expr_compatible_data_types(t1, t2)) + { + struct vkd3d_string_buffer *t1_string = hlsl_type_to_string(ctx, t1); + struct vkd3d_string_buffer *t2_string = hlsl_type_to_string(ctx, t2); + + if (t1_string && t2_string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Expression data types "%s" and "%s" are incompatible.", + t1_string->buffer, t2_string->buffer); + hlsl_release_string_buffer(ctx, t1_string); + hlsl_release_string_buffer(ctx, t2_string); + return false; + } + + if (t1->dimx == 1 && t1->dimy == 1) + { + *type = t2->class; + *dimx = t2->dimx; + *dimy = t2->dimy; + } + else if (t2->dimx == 1 && t2->dimy == 1) + { + *type = t1->class; + *dimx = t1->dimx; + *dimy = t1->dimy; + } + else if (t1->class == HLSL_CLASS_MATRIX && t2->class == HLSL_CLASS_MATRIX) + { + *type = HLSL_CLASS_MATRIX; + *dimx = min(t1->dimx, t2->dimx); + *dimy = min(t1->dimy, t2->dimy); + } + else + { + if (t1->dimx * t1->dimy <= t2->dimx * t2->dimy) + { + *type = t1->class; + *dimx = t1->dimx; + *dimy = t1->dimy; + } + else + { + *type = t2->class; + *dimx = t2->dimx; + *dimy = t2->dimy; + } + } + + return true; +} + +static bool hlsl_types_are_componentwise_equal(struct hlsl_ctx *ctx, struct hlsl_type *src, + struct hlsl_type *dst) +{ + unsigned int k, count = hlsl_type_component_count(src); + + if (count != hlsl_type_component_count(dst)) + return false; + + for (k = 0; k < count; ++k) + { + struct hlsl_type *src_comp_type, *dst_comp_type; + + src_comp_type = hlsl_type_get_component_type(ctx, src, k); + dst_comp_type = hlsl_type_get_component_type(ctx, dst, k); + + if (!hlsl_types_are_equal(src_comp_type, dst_comp_type)) + return false; + } + return true; +} + +bool hlsl_implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) +{ + if ((src->class <= HLSL_CLASS_LAST_NUMERIC) != (dst->class <= HLSL_CLASS_LAST_NUMERIC)) + return false; + + if (src->class <= HLSL_CLASS_LAST_NUMERIC) + { + /* Scalar vars can be converted to any other numeric data type */ + if (src->dimx == 1 && src->dimy == 1) + return true; + /* The other way around is true too */ + if (dst->dimx == 1 && dst->dimy == 1) + return true; + + if (src->class == HLSL_CLASS_MATRIX || dst->class == HLSL_CLASS_MATRIX) + { + if (src->class == HLSL_CLASS_MATRIX && dst->class == HLSL_CLASS_MATRIX) + return src->dimx >= dst->dimx && src->dimy >= dst->dimy; + + /* Matrix-vector conversion is apparently allowed if they have + * the same components count, or if the matrix is 1xN or Nx1 + * and we are reducing the component count */ + if (src->class == HLSL_CLASS_VECTOR || dst->class == HLSL_CLASS_VECTOR) + { + if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) + return true; + + if ((src->class == HLSL_CLASS_VECTOR || src->dimx == 1 || src->dimy == 1) && + (dst->class == HLSL_CLASS_VECTOR || dst->dimx == 1 || dst->dimy == 1)) + return hlsl_type_component_count(src) >= hlsl_type_component_count(dst); + } + + return false; + } + else + { + return src->dimx >= dst->dimx; + } + } + + return hlsl_types_are_componentwise_equal(ctx, src, dst); +} + +struct hlsl_ir_node *hlsl_add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *src_type = node->data_type; + + if (hlsl_types_are_equal(src_type, dst_type)) + return node; + + if (!hlsl_implicit_compatible_data_types(ctx, src_type, dst_type)) + { + struct vkd3d_string_buffer *src_string, *dst_string; + + src_string = hlsl_type_to_string(ctx, src_type); + dst_string = hlsl_type_to_string(ctx, dst_type); + if (src_string && dst_string) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); + hlsl_release_string_buffer(ctx, src_string); + hlsl_release_string_buffer(ctx, dst_string); + return NULL; + } + + if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", + src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); + + return hlsl_add_cast(ctx, instrs, node, dst_type, loc); +} + +struct hlsl_ir_node *hlsl_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) +{ + struct hlsl_type *src_type = node->data_type; + struct hlsl_ir_node *cast; + + if (hlsl_types_are_equal(src_type, dst_type)) + return node; + + if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR) + { + unsigned int src_comp_count = hlsl_type_component_count(src_type); + unsigned int dst_comp_count = hlsl_type_component_count(dst_type); + struct hlsl_deref var_deref; + bool broadcast, matrix_cast; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + unsigned int dst_idx; + + broadcast = src_type->class <= HLSL_CLASS_LAST_NUMERIC && src_type->dimx == 1 && src_type->dimy == 1; + matrix_cast = !broadcast && dst_comp_count != src_comp_count + && src_type->class == HLSL_CLASS_MATRIX && dst_type->class == HLSL_CLASS_MATRIX; + assert(src_comp_count >= dst_comp_count || broadcast); + if (matrix_cast) + { + assert(dst_type->dimx <= src_type->dimx); + assert(dst_type->dimy <= src_type->dimy); + } + + if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, loc))) + return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) + { + struct hlsl_ir_node *component_load; + struct hlsl_type *dst_comp_type; + struct hlsl_block block; + unsigned int src_idx; + + if (broadcast) + { + src_idx = 0; + } + else if (matrix_cast) + { + unsigned int x = dst_idx % dst_type->dimx, y = dst_idx / dst_type->dimx; + + src_idx = y * src_type->dimx + x; + } + else + { + src_idx = dst_idx; + } + + dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx); + + 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))) + return NULL; + list_add_tail(instrs, &cast->entry); + + if (!hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, cast)) + return NULL; + list_move_tail(instrs, &block.instrs); + } + + if (!(load = hlsl_new_var_load(ctx, var, loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + else + { + if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) + return NULL; + list_add_tail(instrs, &cast->entry); + return cast; + } +} + +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; + struct hlsl_block block; + struct hlsl_ir_var *var; + struct hlsl_deref src; + + if (!(var = hlsl_new_synthetic_var(ctx, "deref", var_instr->data_type, &var_instr->loc))) + return NULL; + + if (!(store = hlsl_new_simple_store(ctx, var, var_instr))) + return NULL; + list_add_tail(instrs, &store->entry); + + hlsl_init_simple_deref_from_var(&src, var); + if (!(load = hlsl_new_load_component(ctx, &block, &src, comp, loc))) + return NULL; + list_move_tail(instrs, &block.instrs); + + return load; +} + +struct hlsl_ir_node *hlsl_add_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *expr; + unsigned int i; + + if (type->class == HLSL_CLASS_MATRIX) + { + struct hlsl_type *scalar_type; + struct hlsl_ir_load *var_load; + struct hlsl_deref var_deref; + struct hlsl_ir_node *load; + struct hlsl_ir_var *var; + + scalar_type = hlsl_get_scalar_type(ctx, type->base_type); + + if (!(var = hlsl_new_synthetic_var(ctx, "split_op", type, loc))) + return NULL; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < type->dimy * type->dimx; ++i) + { + struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL }; + struct hlsl_block block; + unsigned int j; + + for (j = 0; j < HLSL_MAX_OPERANDS; j++) + { + if (operands[j]) + { + if (!(load = hlsl_add_load_component(ctx, instrs, operands[j], i, loc))) + return NULL; + + cell_operands[j] = load; + } + } + + if (!(value = hlsl_add_expr(ctx, instrs, op, cell_operands, scalar_type, loc))) + return NULL; + + if (!hlsl_new_store_component(ctx, &block, &var_deref, i, value)) + return NULL; + list_move_tail(instrs, &block.instrs); + } + + if (!(var_load = hlsl_new_var_load(ctx, var, loc))) + return NULL; + list_add_tail(instrs, &var_load->node.entry); + + return &var_load->node; + } + + if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) + return NULL; + list_add_tail(instrs, &expr->entry); + + return expr; +} + +struct hlsl_ir_node *hlsl_add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *common_type, *return_type; + enum hlsl_base_type base = hlsl_expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_type_class type; + unsigned int dimx, dimy; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + if (!hlsl_expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); + return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); + + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = hlsl_add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return hlsl_add_expr(ctx, instrs, op, args, return_type, loc); +} + +struct hlsl_ir_node *hlsl_add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *common_type; + enum hlsl_type_class type; + unsigned int dimx, dimy; + + if (!hlsl_expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + return NULL; + + common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); + + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + return NULL; + + if (!(args[1] = hlsl_add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + return NULL; + + return hlsl_add_expr(ctx, instrs, op, args, common_type, loc); +} + struct clone_instr_map { struct diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c3e76927..853f5544 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1125,6 +1125,25 @@ struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, cons struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc);
+enum hlsl_base_type hlsl_expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2); +bool hlsl_expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, + const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy); +struct hlsl_ir_node *hlsl_add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc); +bool hlsl_implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst); +struct hlsl_ir_node *hlsl_add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_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); +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_add_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, + const struct vkd3d_shader_location *loc); void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var);
struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index f2ecd364..7169ce31 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -171,27 +171,6 @@ static bool hlsl_types_are_componentwise_compatible(struct hlsl_ctx *ctx, struct return true; }
-static bool hlsl_types_are_componentwise_equal(struct hlsl_ctx *ctx, struct hlsl_type *src, - struct hlsl_type *dst) -{ - unsigned int k, count = hlsl_type_component_count(src); - - if (count != hlsl_type_component_count(dst)) - return false; - - for (k = 0; k < count; ++k) - { - struct hlsl_type *src_comp_type, *dst_comp_type; - - src_comp_type = hlsl_type_get_component_type(ctx, src, k); - dst_comp_type = hlsl_type_get_component_type(ctx, dst, k); - - if (!hlsl_types_are_equal(src_comp_type, dst_comp_type)) - return false; - } - return true; -} - static bool type_contains_only_numerics(struct hlsl_type *type) { unsigned int i; @@ -230,165 +209,6 @@ static bool explicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ return hlsl_types_are_componentwise_compatible(ctx, src, dst); }
-static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_type *src, struct hlsl_type *dst) -{ - if ((src->class <= HLSL_CLASS_LAST_NUMERIC) != (dst->class <= HLSL_CLASS_LAST_NUMERIC)) - return false; - - if (src->class <= HLSL_CLASS_LAST_NUMERIC) - { - /* Scalar vars can be converted to any other numeric data type */ - if (src->dimx == 1 && src->dimy == 1) - return true; - /* The other way around is true too */ - if (dst->dimx == 1 && dst->dimy == 1) - return true; - - if (src->class == HLSL_CLASS_MATRIX || dst->class == HLSL_CLASS_MATRIX) - { - if (src->class == HLSL_CLASS_MATRIX && dst->class == HLSL_CLASS_MATRIX) - return src->dimx >= dst->dimx && src->dimy >= dst->dimy; - - /* Matrix-vector conversion is apparently allowed if they have - * the same components count, or if the matrix is 1xN or Nx1 - * and we are reducing the component count */ - if (src->class == HLSL_CLASS_VECTOR || dst->class == HLSL_CLASS_VECTOR) - { - if (hlsl_type_component_count(src) == hlsl_type_component_count(dst)) - return true; - - if ((src->class == HLSL_CLASS_VECTOR || src->dimx == 1 || src->dimy == 1) && - (dst->class == HLSL_CLASS_VECTOR || dst->dimx == 1 || dst->dimy == 1)) - return hlsl_type_component_count(src) >= hlsl_type_component_count(dst); - } - - return false; - } - else - { - return src->dimx >= dst->dimx; - } - } - - 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) -{ - struct hlsl_type *src_type = node->data_type; - struct hlsl_ir_node *cast; - - if (hlsl_types_are_equal(src_type, dst_type)) - return node; - - if (src_type->class > HLSL_CLASS_VECTOR || dst_type->class > HLSL_CLASS_VECTOR) - { - unsigned int src_comp_count = hlsl_type_component_count(src_type); - unsigned int dst_comp_count = hlsl_type_component_count(dst_type); - struct hlsl_deref var_deref; - bool broadcast, matrix_cast; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - unsigned int dst_idx; - - broadcast = src_type->class <= HLSL_CLASS_LAST_NUMERIC && src_type->dimx == 1 && src_type->dimy == 1; - matrix_cast = !broadcast && dst_comp_count != src_comp_count - && src_type->class == HLSL_CLASS_MATRIX && dst_type->class == HLSL_CLASS_MATRIX; - assert(src_comp_count >= dst_comp_count || broadcast); - if (matrix_cast) - { - assert(dst_type->dimx <= src_type->dimx); - assert(dst_type->dimy <= src_type->dimy); - } - - if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, loc))) - return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) - { - struct hlsl_ir_node *component_load; - struct hlsl_type *dst_comp_type; - struct hlsl_block block; - unsigned int src_idx; - - if (broadcast) - { - src_idx = 0; - } - else if (matrix_cast) - { - unsigned int x = dst_idx % dst_type->dimx, y = dst_idx / dst_type->dimx; - - src_idx = y * src_type->dimx + x; - } - else - { - src_idx = dst_idx; - } - - 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))) - return NULL; - - if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, loc))) - return NULL; - list_add_tail(instrs, &cast->entry); - - if (!hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, cast)) - return NULL; - list_move_tail(instrs, &block.instrs); - } - - if (!(load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - list_add_tail(instrs, &load->node.entry); - - return &load->node; - } - else - { - if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - list_add_tail(instrs, &cast->entry); - return cast; - } -} - -static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs, - struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) -{ - struct hlsl_type *src_type = node->data_type; - - if (hlsl_types_are_equal(src_type, dst_type)) - return node; - - if (!implicit_compatible_data_types(ctx, src_type, dst_type)) - { - struct vkd3d_string_buffer *src_string, *dst_string; - - src_string = hlsl_type_to_string(ctx, src_type); - dst_string = hlsl_type_to_string(ctx, dst_type); - if (src_string && dst_string) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); - hlsl_release_string_buffer(ctx, src_string); - hlsl_release_string_buffer(ctx, dst_string); - return NULL; - } - - if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) - hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", - src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); - - return add_cast(ctx, instrs, node, dst_type, loc); -} - static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, const struct vkd3d_shader_location *loc) { @@ -637,7 +457,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct list *instrs, { struct hlsl_ir_node *store;
- if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, loc))) + if (!(return_value = hlsl_add_implicit_conversion(ctx, instrs, return_value, return_type, loc))) return false;
if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value))) @@ -663,29 +483,6 @@ 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, - unsigned int comp, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *load, *store; - struct hlsl_block block; - struct hlsl_ir_var *var; - struct hlsl_deref src; - - if (!(var = hlsl_new_synthetic_var(ctx, "deref", var_instr->data_type, &var_instr->loc))) - return NULL; - - if (!(store = hlsl_new_simple_store(ctx, var, var_instr))) - return NULL; - list_add_tail(instrs, &store->entry); - - hlsl_init_simple_deref_from_var(&src, var); - if (!(load = hlsl_new_load_component(ctx, &block, &src, comp, loc))) - return NULL; - list_move_tail(instrs, &block.instrs); - - return load; -} - static bool add_record_access(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location *loc) { @@ -731,7 +528,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h return false; }
- if (!(index = add_implicit_conversion(ctx, instrs, index, + if (!(index = hlsl_add_implicit_conversion(ctx, instrs, index, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc))) return false;
@@ -1099,7 +896,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str struct hlsl_ir_node *node; unsigned int ret = 0;
- if (!add_implicit_conversion(ctx, &block->instrs, node_from_list(&block->instrs), + if (!hlsl_add_implicit_conversion(ctx, &block->instrs, node_from_list(&block->instrs), hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)) return 0;
@@ -1120,194 +917,6 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str return ret; }
-static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) -{ - if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) - return false; - - /* Scalar vars can be converted to pretty much everything */ - if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) - return true; - - if (t1->class == HLSL_CLASS_VECTOR && t2->class == HLSL_CLASS_VECTOR) - return true; - - if (t1->class == HLSL_CLASS_MATRIX || t2->class == HLSL_CLASS_MATRIX) - { - /* Matrix-vector conversion is apparently allowed if either they have the same components - count or the matrix is nx1 or 1xn */ - if (t1->class == HLSL_CLASS_VECTOR || t2->class == HLSL_CLASS_VECTOR) - { - if (hlsl_type_component_count(t1) == hlsl_type_component_count(t2)) - return true; - - return (t1->class == HLSL_CLASS_MATRIX && (t1->dimx == 1 || t1->dimy == 1)) - || (t2->class == HLSL_CLASS_MATRIX && (t2->dimx == 1 || t2->dimy == 1)); - } - - /* Both matrices */ - if ((t1->dimx >= t2->dimx && t1->dimy >= t2->dimy) - || (t1->dimx <= t2->dimx && t1->dimy <= t2->dimy)) - return true; - } - - return false; -} - -static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) -{ - if (t1 > HLSL_TYPE_LAST_SCALAR || t2 > HLSL_TYPE_LAST_SCALAR) { - FIXME("Unexpected base type.\n"); - return HLSL_TYPE_FLOAT; - } - if (t1 == t2) - return t1 == HLSL_TYPE_BOOL ? HLSL_TYPE_INT : t1; - if (t1 == HLSL_TYPE_DOUBLE || t2 == HLSL_TYPE_DOUBLE) - return HLSL_TYPE_DOUBLE; - if (t1 == HLSL_TYPE_FLOAT || t2 == HLSL_TYPE_FLOAT - || t1 == HLSL_TYPE_HALF || t2 == HLSL_TYPE_HALF) - return HLSL_TYPE_FLOAT; - if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) - return HLSL_TYPE_UINT; - return HLSL_TYPE_INT; -} - -static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, - const struct vkd3d_shader_location *loc, enum hlsl_type_class *type, unsigned int *dimx, unsigned int *dimy) -{ - if (t1->class > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, t1))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - if (t2->class > HLSL_CLASS_LAST_NUMERIC) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, t2))) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression of type "%s" cannot be used in a numeric expression.", string->buffer); - hlsl_release_string_buffer(ctx, string); - return false; - } - - if (!expr_compatible_data_types(t1, t2)) - { - struct vkd3d_string_buffer *t1_string = hlsl_type_to_string(ctx, t1); - struct vkd3d_string_buffer *t2_string = hlsl_type_to_string(ctx, t2); - - if (t1_string && t2_string) - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Expression data types "%s" and "%s" are incompatible.", - t1_string->buffer, t2_string->buffer); - hlsl_release_string_buffer(ctx, t1_string); - hlsl_release_string_buffer(ctx, t2_string); - return false; - } - - if (t1->dimx == 1 && t1->dimy == 1) - { - *type = t2->class; - *dimx = t2->dimx; - *dimy = t2->dimy; - } - else if (t2->dimx == 1 && t2->dimy == 1) - { - *type = t1->class; - *dimx = t1->dimx; - *dimy = t1->dimy; - } - else if (t1->class == HLSL_CLASS_MATRIX && t2->class == HLSL_CLASS_MATRIX) - { - *type = HLSL_CLASS_MATRIX; - *dimx = min(t1->dimx, t2->dimx); - *dimy = min(t1->dimy, t2->dimy); - } - else - { - if (t1->dimx * t1->dimy <= t2->dimx * t2->dimy) - { - *type = t1->class; - *dimx = t1->dimx; - *dimy = t1->dimy; - } - else - { - *type = t2->class; - *dimx = t2->dimx; - *dimy = t2->dimy; - } - } - - return true; -} - -static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], - struct hlsl_type *type, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *expr; - unsigned int i; - - if (type->class == HLSL_CLASS_MATRIX) - { - struct hlsl_type *scalar_type; - struct hlsl_ir_load *var_load; - struct hlsl_deref var_deref; - struct hlsl_ir_node *load; - struct hlsl_ir_var *var; - - scalar_type = hlsl_get_scalar_type(ctx, type->base_type); - - if (!(var = hlsl_new_synthetic_var(ctx, "split_op", type, loc))) - return NULL; - hlsl_init_simple_deref_from_var(&var_deref, var); - - for (i = 0; i < type->dimy * type->dimx; ++i) - { - struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL }; - struct hlsl_block block; - unsigned int j; - - for (j = 0; j < HLSL_MAX_OPERANDS; j++) - { - if (operands[j]) - { - if (!(load = add_load_component(ctx, instrs, operands[j], i, loc))) - return NULL; - - cell_operands[j] = load; - } - } - - if (!(value = add_expr(ctx, instrs, op, cell_operands, scalar_type, loc))) - return NULL; - - if (!hlsl_new_store_component(ctx, &block, &var_deref, i, value)) - return NULL; - list_move_tail(instrs, &block.instrs); - } - - if (!(var_load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - list_add_tail(instrs, &var_load->node.entry); - - return &var_load->node; - } - - if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) - return NULL; - list_add_tail(instrs, &expr->entry); - - return expr; -} - static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) { const struct hlsl_type *type = instr->data_type; @@ -1334,7 +943,7 @@ static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru { struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg};
- return add_expr(ctx, instrs, op, args, arg->data_type, loc); + return hlsl_add_expr(ctx, instrs, op, args, arg->data_type, loc); }
static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, @@ -1354,20 +963,20 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL, arg->data_type->dimx, arg->data_type->dimy);
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg, bool_type, loc))) + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg, bool_type, loc))) return NULL;
- return add_expr(ctx, instrs, op, args, bool_type, loc); + return hlsl_add_expr(ctx, instrs, op, args, bool_type, loc); }
static struct hlsl_type *get_common_numeric_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *arg1, const struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_base_type base = hlsl_expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); enum hlsl_type_class type; unsigned int dimx, dimy;
- if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + if (!hlsl_expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) return NULL;
return hlsl_get_numeric_type(ctx, type, base, dimx, dimy); @@ -1382,13 +991,13 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str
common_type = get_common_numeric_type(ctx, arg1, arg2, loc);
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) return NULL;
- if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + if (!(args[1] = hlsl_add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) return NULL;
- return add_expr(ctx, instrs, op, args, common_type, loc); + return hlsl_add_expr(ctx, instrs, op, args, common_type, loc); }
static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, @@ -1424,31 +1033,6 @@ static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct l return list1; }
-static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_type *common_type, *return_type; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); - enum hlsl_type_class type; - unsigned int dimx, dimy; - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); - return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, return_type, loc); -} - static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) { @@ -1456,33 +1040,10 @@ static struct list *add_binary_comparison_expr_merge(struct hlsl_ctx *ctx, struc
list_move_tail(list1, list2); vkd3d_free(list2); - add_binary_comparison_expr(ctx, list1, op, arg1, arg2, loc); + hlsl_add_binary_comparison_expr(ctx, list1, op, arg1, arg2, loc); return list1; }
-static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct list *instrs, - enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_type *common_type; - enum hlsl_type_class type; - unsigned int dimx, dimy; - - if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) - return NULL; - - common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); - - if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - - return add_expr(ctx, instrs, op, args, common_type, loc); -} - static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) { @@ -1490,7 +1051,7 @@ static struct list *add_binary_logical_expr_merge(struct hlsl_ctx *ctx, struct l
list_move_tail(list1, list2); vkd3d_free(list2); - add_binary_logical_expr(ctx, list1, op, arg1, arg2, loc); + hlsl_add_binary_logical_expr(ctx, list1, op, arg1, arg2, loc);
return list1; } @@ -1511,19 +1072,19 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct l if (base == HLSL_TYPE_BOOL) base = HLSL_TYPE_INT;
- if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) + if (!hlsl_expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) return NULL;
return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy);
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, return_type, loc))) + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg1, return_type, loc))) return NULL;
- if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, integer_type, loc))) + if (!(args[1] = hlsl_add_implicit_conversion(ctx, instrs, arg2, integer_type, loc))) return NULL;
- return add_expr(ctx, instrs, op, args, return_type, loc); + return hlsl_add_expr(ctx, instrs, op, args, return_type, loc); }
static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, @@ -1541,7 +1102,7 @@ static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct lis static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_base_type base = hlsl_expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; struct hlsl_type *common_type, *ret_type; enum hlsl_ir_expr_op op; @@ -1584,13 +1145,13 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct lis common_type = hlsl_get_vector_type(ctx, base, dim); ret_type = hlsl_get_scalar_type(ctx, base);
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) + if (!(args[0] = hlsl_add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) return NULL;
- if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) + if (!(args[1] = hlsl_add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) return NULL;
- return add_expr(ctx, instrs, op, args, ret_type, loc); + return hlsl_add_expr(ctx, instrs, op, args, ret_type, loc); }
static enum hlsl_ir_expr_op op_from_assignment(enum parse_assign_op op) @@ -1674,7 +1235,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in if (lhs_type->class <= HLSL_CLASS_LAST_NUMERIC) writemask = (1 << lhs_type->dimx) - 1;
- if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc))) + if (!(rhs = hlsl_add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc))) return NULL;
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX) @@ -1774,7 +1335,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)) @@ -1863,12 +1424,12 @@ 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);
- if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc))) + if (!(conv = hlsl_add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc))) return;
if (!hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv)) @@ -2184,7 +1745,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t } list_add_tail(&ctx->static_initializers, &zero->entry);
- if (!(cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc))) + if (!(cast = hlsl_add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc))) { vkd3d_free(v); continue; @@ -2239,7 +1800,7 @@ static void find_function_call_compatible(struct rb_entry *entry, void *context)
for (i = 0; i < decl->parameters.count; ++i) { - if (!implicit_compatible_data_types(args->ctx, args->params->args[i]->data_type, + if (!hlsl_implicit_compatible_data_types(args->ctx, args->params->args[i]->data_type, decl->parameters.vars[i]->data_type)) return; } @@ -2281,7 +1842,7 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, return arg;
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - return add_implicit_conversion(ctx, params->instrs, arg, type, loc); + return hlsl_add_implicit_conversion(ctx, params->instrs, arg, type, loc); }
static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, @@ -2293,7 +1854,7 @@ static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *p { struct hlsl_ir_node *new_arg;
- if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc))) + if (!(new_arg = hlsl_add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc))) return false; params->args[i] = new_arg; } @@ -2314,7 +1875,7 @@ static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx * { struct hlsl_type *arg_type = params->args[i]->data_type;
- base = expr_common_base_type(base, arg_type->base_type); + base = hlsl_expr_common_base_type(base, arg_type->base_type);
if (arg_type->class == HLSL_CLASS_VECTOR) { @@ -2400,14 +1961,14 @@ 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))) return false; }
- return !!add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, mul, zero, loc); + return !!hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, mul, zero, loc); }
static bool intrinsic_any(struct hlsl_ctx *ctx, @@ -2431,7 +1992,7 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false;
- return !!add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, dot, zero, loc); + return !!hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_NEQUAL, dot, zero, loc); } else if (arg->data_type->base_type == HLSL_TYPE_BOOL) { @@ -2444,7 +2005,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))) @@ -2486,7 +2047,7 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_FLOAT);
operands[0] = params->args[0]; - return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); + return hlsl_add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); }
static bool intrinsic_asuint(struct hlsl_ctx *ctx, @@ -2522,7 +2083,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_UINT);
operands[0] = params->args[0]; - return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); + return hlsl_add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); }
static bool intrinsic_clamp(struct hlsl_ctx *ctx, @@ -2566,10 +2127,10 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx,
cast_type = hlsl_get_vector_type(ctx, base, 3);
- if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) + if (!(arg1_cast = hlsl_add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) return false;
- if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) + if (!(arg2_cast = hlsl_add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) return false;
if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) @@ -2721,7 +2282,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer if (!(neg_frac = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, frac, loc))) return false;
- if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) + if (!(ge = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) return false;
if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) @@ -2875,13 +2436,13 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, list_move_tail(params->instrs, &block.instrs);
/* Specular component. */ - if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_h, zero, loc))) + if (!(n_h_neg = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_h, zero, loc))) return false;
- if (!(n_l_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_l, zero, loc))) + if (!(n_l_neg = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_l, zero, loc))) return false;
- if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) + if (!(specular_or = hlsl_add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) return false;
if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) @@ -2970,7 +2531,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_base_type base = hlsl_expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; unsigned int i, j, k, vect_count = 0; struct hlsl_deref var_deref; @@ -3008,10 +2569,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, ret_type = hlsl_get_scalar_type(ctx, base); }
- if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) + if (!(cast1 = hlsl_add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) return false;
- if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) + if (!(cast2 = hlsl_add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) return false;
if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc))) @@ -3029,10 +2590,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))) @@ -3059,7 +2620,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, return false; list_add_tail(params->instrs, &load->node.entry);
- return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); + return !!hlsl_add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); }
static bool intrinsic_normalize(struct hlsl_ctx *ctx, @@ -3168,18 +2729,18 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx,
/* Check if 0 < arg, cast bool to int */
- if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) + if (!(lt = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) return false;
- if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) + if (!(op1 = hlsl_add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) return false;
/* Check if arg < 0, cast bool to int and invert (meaning true is -1) */
- if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc))) + if (!(lt = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc))) return false;
- if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) + if (!(op2 = hlsl_add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) return false;
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc))) @@ -3278,13 +2839,13 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false;
- if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, + if (!(ge = hlsl_add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, params->args[1], params->args[0], loc))) return false;
type = ge->data_type; type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); + return !!hlsl_add_implicit_conversion(ctx, params->instrs, ge, type, loc); }
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params, @@ -3319,7 +2880,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * hlsl_release_string_buffer(ctx, string); }
- if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + if (!(coords = hlsl_add_implicit_conversion(ctx, params->instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) coords = params->args[1];
@@ -3388,7 +2949,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)) @@ -3544,7 +3105,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, { struct hlsl_ir_node *cast;
- if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) + if (!(cast = hlsl_add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) goto fail; args->args[i] = cast; arg = cast; @@ -3756,7 +3317,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } if (multisampled) { - if (!(load_params.sample_index = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.sample_index = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc))) return false; } @@ -3764,7 +3325,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru assert(offset_dim); if (params->args_count > 1 + multisampled) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[1 + multisampled], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -3774,7 +3335,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru }
/* +1 for the mipmap level for non-multisampled textures */ - if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[0], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc))) return false;
@@ -3824,13 +3385,13 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
if (offset_dim && params->args_count > 2) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -3894,17 +3455,17 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
- if (!(load_params.cmp = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.cmp = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) load_params.cmp = params->args[2];
if (offset_dim && params->args_count > 3) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -3992,7 +3553,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st } else if (offset_dim && params->args_count > 2) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4017,7 +3578,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false;
@@ -4073,17 +3634,17 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.coords = params->args[1];
- if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.lod = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) load_params.lod = params->args[2];
if (offset_dim && params->args_count > 3) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[3], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -4140,21 +3701,21 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1], + if (!(load_params.coords = hlsl_add_implicit_conversion(ctx, instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.coords = params->args[1];
- if (!(load_params.ddx = add_implicit_conversion(ctx, instrs, params->args[2], + if (!(load_params.ddx = hlsl_add_implicit_conversion(ctx, instrs, params->args[2], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.ddx = params->args[2];
- if (!(load_params.ddy = add_implicit_conversion(ctx, instrs, params->args[3], + if (!(load_params.ddy = hlsl_add_implicit_conversion(ctx, instrs, params->args[3], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) load_params.ddy = params->args[3];
if (offset_dim && params->args_count > 4) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[4], + if (!(load_params.texel_offset = hlsl_add_implicit_conversion(ctx, instrs, params->args[4], hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } @@ -6118,7 +5679,7 @@ unary_expr: YYABORT; }
- if (!add_cast(ctx, $6, node_from_list($6), dst_type, &@3)) + if (!hlsl_add_cast(ctx, $6, node_from_list($6), dst_type, &@3)) { hlsl_free_instr_list($6); YYABORT; @@ -6248,10 +5809,10 @@ conditional_expr: if (!(common_type = get_common_numeric_type(ctx, first, second, &@3))) YYABORT;
- if (!(first = add_implicit_conversion(ctx, $1, first, common_type, &@3))) + if (!(first = hlsl_add_implicit_conversion(ctx, $1, first, common_type, &@3))) YYABORT;
- if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5))) + if (!(second = hlsl_add_implicit_conversion(ctx, $1, second, common_type, &@5))) YYABORT;
if (!hlsl_add_conditional(ctx, $1, cond, first, second))
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 | 13 +++++++++---- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 29 +++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index e4fa5c89..568676c4 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2583,10 +2583,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_TEXKILL] = "HLSL_IR_JUMP_TEXKILL", + [HLSL_IR_JUMP_DISCARD] = "HLSL_IR_JUMP_DISCARD", + [HLSL_IR_JUMP_RETURN] = "HLSL_IR_JUMP_RETURN", };
assert(type < ARRAY_SIZE(names)); @@ -2855,6 +2856,10 @@ 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_TEXKILL: + vkd3d_string_buffer_printf(buffer, "texkill"); + break; + case HLSL_IR_JUMP_DISCARD: vkd3d_string_buffer_printf(buffer, "discard"); break; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 853f5544..f68f5773 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -558,6 +558,7 @@ enum hlsl_ir_jump_type { HLSL_IR_JUMP_BREAK, HLSL_IR_JUMP_CONTINUE, + HLSL_IR_JUMP_TEXKILL, HLSL_IR_JUMP_DISCARD, 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 and HLSL_IR_JUMP_TEXKILL. */ struct hlsl_src condition; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 7169ce31..5a61d7f8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2100,6 +2100,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_TEXKILL, 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) { @@ -3038,6 +3066,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},
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: 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 d2fab7c8..982139ec 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)
I don't think we want the frontend casting logic to live or be used anywhere outside of the frontend. If we're generating instructions after parsing, they should already have the right types.
I would prefer names like DISCARD_NZ and DISCARD_NEG rather than DISCARD and TEXKILL.
On Tue Jun 13 10:01:40 2023 +0000, Zebediah Figura wrote:
I don't think we want the frontend casting logic to live or be used anywhere outside of the frontend. If we're generating instructions after parsing, they should already have the right types. I would prefer names like DISCARD_NZ and DISCARD_NEG rather than DISCARD and TEXKILL.
By casting you mean deferring turning texkill to discard_nz in a first place? Or having higher level calls that do type conversion in codegen.c, like hlsl_add_binary_comparison_expr()?
On Tue Jun 13 10:01:39 2023 +0000, Nikolay Sivov wrote:
By casting you mean deferring turning texkill to discard_nz in a first place? Or having higher level calls that do type conversion in codegen.c, like hlsl_add_binary_comparison_expr()?
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.