-- v3: vkd3d-shader/hlsl: Pass a location pointer to init_node(). vkd3d-shader/hlsl: Introduce a hlsl_new_expr() helper. vkd3d-shader/hlsl: Write SM4 reinterpret instructions. vkd3d-shader/hlsl: Parse the asuint() intrinsic. tests: Add a test for asuint().
From: Zebediah Figura zfigura@codeweavers.com
--- tests/asuint.shader_test | 55 ++++++++++++++++++++++++++++++++++++++++ tests/shader_runner.c | 12 ++++++--- 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 tests/asuint.shader_test
diff --git a/tests/asuint.shader_test b/tests/asuint.shader_test new file mode 100644 index 00000000..77385515 --- /dev/null +++ b/tests/asuint.shader_test @@ -0,0 +1,55 @@ +[require] +shader model >= 4.0 + +[pixel shader] + +float4 main(uniform float f, uniform int i, uniform uint u, uniform half h) : sv_target +{ + uint4 ret; + + ret.x = asuint(f); + ret.y = asuint(i); + ret.z = asuint(u); + ret.w = asuint(h); + return ret; +} + +[test] +uniform 0 uint4 123 0xc0000000 456 0x7fd69345 +todo draw quad +probe (320,240) rgba (123.0, 3221225472.0, 456.0, 2144768896.0) + + +[pixel shader] + +float4 main(uniform float2x2 m, uniform float4 v) : sv_target +{ + return float4(asuint(m)[0][1], asuint(v).y, 0, 0); +} + +[test] +uniform 0 uint4 11 12 0 0 +uniform 4 uint4 13 14 0 0 +uniform 8 uint4 20 21 22 23 +todo draw quad +probe (320,240) rgba (13.0, 21.0, 0.0, 0.0) + + +[pixel shader fail] + +float4 main() : sv_target +{ + bool b = true; + + return asuint(b); +} + + +[pixel shader fail] + +float4 main() : sv_target +{ + double d = 1.0; + + return asuint(b); +} diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 25986b31..3fb677ce 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -557,7 +557,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) unsigned int offset;
if (!sscanf(line, "%u", &offset)) - fatal_error("Unknown uniform type '%s'.\n", line); + fatal_error("Malformed uniform offset '%s'.\n", line); line = strchr(line, ' ') + 1;
if (match_string(line, "float4", &line)) @@ -576,12 +576,12 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed float constant '%s'.\n", line); set_uniforms(runner, offset, 1, &f); } - else if (match_string(line, "int4", &line)) + else if (match_string(line, "int4", &line) || match_string(line, "uint4", &line)) { int v[4];
- if (sscanf(line, "%d %d %d %d", &v[0], &v[1], &v[2], &v[3]) < 4) - fatal_error("Malformed int4 constant '%s'.\n", line); + if (sscanf(line, "%i %i %i %i", &v[0], &v[1], &v[2], &v[3]) < 4) + fatal_error("Malformed (u)int4 constant '%s'.\n", line); set_uniforms(runner, offset, 4, v); } else if (match_string(line, "int", &line)) @@ -600,6 +600,10 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed uint constant '%s'.\n", line); set_uniforms(runner, offset, 1, &u); } + else + { + fatal_error("Unknown uniform type '%s'.\n", line); + } } else {
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 45 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index c1cd065a..8eac4fe4 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1642,6 +1642,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_NEG] = "-", [HLSL_OP1_NRM] = "nrm", [HLSL_OP1_RCP] = "rcp", + [HLSL_OP1_REINTERPRET] = "reinterpret", [HLSL_OP1_ROUND] = "round", [HLSL_OP1_RSQ] = "rsq", [HLSL_OP1_SAT] = "sat", diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 770a4032..9039e9bc 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -312,6 +312,7 @@ enum hlsl_ir_expr_op HLSL_OP1_NEG, HLSL_OP1_NRM, HLSL_OP1_RCP, + HLSL_OP1_REINTERPRET, HLSL_OP1_ROUND, HLSL_OP1_RSQ, HLSL_OP1_SAT, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index fc3b31a4..bbcc28b0 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2053,6 +2053,50 @@ static bool intrinsic_abs(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); }
+/* Find the type corresponding to the given source type, with the same + * dimensions but a different base type. */ +static struct hlsl_type *convert_numeric_type(const struct hlsl_ctx *ctx, + const struct hlsl_type *type, enum hlsl_base_type base_type) +{ + return hlsl_get_numeric_type(ctx, type->type, base_type, type->dimx, type->dimy); +} + +static bool intrinsic_asuint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *data_type; + + if (params->args_count != 1 && params->args_count != 3) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to function 'asuint': expected 1 or 3, but got %u.", params->args_count); + return false; + } + + if (params->args_count == 3) + { + hlsl_fixme(ctx, loc, "Double-to-integer conversion."); + return false; + } + + data_type = params->args[0]->data_type; + if (data_type->base_type == HLSL_TYPE_BOOL || data_type->base_type == HLSL_TYPE_DOUBLE) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong type for argument 0 of asuint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", + string->buffer); + hlsl_release_string_buffer(ctx, string); + } + 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); +} + static bool intrinsic_clamp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2333,6 +2377,7 @@ intrinsic_functions[] = { /* Note: these entries should be kept in alphabetical order. */ {"abs", 1, true, intrinsic_abs}, + {"asuint", -1, true, intrinsic_asuint}, {"clamp", 3, true, intrinsic_clamp}, {"cross", 2, true, intrinsic_cross}, {"dot", 2, true, intrinsic_dot},
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ tests/asuint.shader_test | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5d763c56..60694300 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1664,6 +1664,10 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, } break;
+ case HLSL_OP1_REINTERPRET: + write_sm4_unary_op(buffer, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); + break; + case HLSL_OP1_ROUND: assert(type_is_float(dst_type)); write_sm4_unary_op(buffer, VKD3D_SM4_OP_ROUND_NE, &expr->node, arg1, 0); diff --git a/tests/asuint.shader_test b/tests/asuint.shader_test index 77385515..a08beaf3 100644 --- a/tests/asuint.shader_test +++ b/tests/asuint.shader_test @@ -16,7 +16,7 @@ float4 main(uniform float f, uniform int i, uniform uint u, uniform half h) : sv
[test] uniform 0 uint4 123 0xc0000000 456 0x7fd69345 -todo draw quad +draw quad probe (320,240) rgba (123.0, 3221225472.0, 456.0, 2144768896.0)
@@ -31,7 +31,7 @@ float4 main(uniform float2x2 m, uniform float4 v) : sv_target uniform 0 uint4 11 12 0 0 uniform 4 uint4 13 14 0 0 uniform 8 uint4 20 21 22 23 -todo draw quad +draw quad probe (320,240) rgba (13.0, 21.0, 0.0, 0.0)
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 40 +++++++++++++++++++++++++++------------- libs/vkd3d-shader/hlsl.h | 13 +++---------- libs/vkd3d-shader/hlsl.y | 12 ++++-------- 3 files changed, 34 insertions(+), 31 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8eac4fe4..f0426620 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -835,6 +835,16 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va deref->var = var; }
+static void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, + struct hlsl_type *data_type, struct vkd3d_shader_location loc) +{ + memset(node, 0, sizeof(*node)); + node->type = type; + node->data_type = data_type; + node->loc = loc; + list_init(&node->uses); +} + struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) { struct hlsl_deref lhs_deref; @@ -962,33 +972,37 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i return c; }
-struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) +struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) { struct hlsl_ir_expr *expr; + unsigned int i;
if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg->data_type, loc); + init_node(&expr->node, HLSL_IR_EXPR, data_type, *loc); expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg); + for (i = 0; i < HLSL_MAX_OPERANDS; ++i) + hlsl_src_from_node(&expr->operands[i], operands[i]); return &expr->node; }
+struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg, struct vkd3d_shader_location loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg}; + + return hlsl_new_expr(ctx, op, operands, arg->data_type, &loc); +} + struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) { - struct hlsl_ir_expr *expr; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2};
assert(hlsl_types_are_equal(arg1->data_type, arg2->data_type)); - - if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) - return NULL; - init_node(&expr->node, HLSL_IR_EXPR, arg1->data_type, arg1->loc); - expr->op = op; - hlsl_src_from_node(&expr->operands[0], arg1); - hlsl_src_from_node(&expr->operands[1], arg2); - return &expr->node; + return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); }
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 9039e9bc..e8f01f2b 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -589,16 +589,6 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); }
-static inline void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, - struct hlsl_type *data_type, struct vkd3d_shader_location loc) -{ - memset(node, 0, sizeof(*node)); - node->type = type; - node->data_type = data_type; - node->loc = loc; - list_init(&node->uses); -} - static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node) { src->node = node; @@ -760,6 +750,9 @@ struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *no struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, const struct vkd3d_shader_location *loc); struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); +struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); struct hlsl_ir_constant *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, const struct vkd3d_shader_location *loc); struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bbcc28b0..26bde674 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1217,7 +1217,7 @@ 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_expr *expr; + struct hlsl_ir_node *expr; unsigned int i;
if (type->type == HLSL_CLASS_MATRIX) @@ -1271,15 +1271,11 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, return &load->node; }
- if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) + if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) return NULL; - init_node(&expr->node, HLSL_IR_EXPR, type, *loc); - expr->op = op; - for (i = 0; i < HLSL_MAX_OPERANDS; ++i) - hlsl_src_from_node(&expr->operands[i], operands[i]); - list_add_tail(instrs, &expr->node.entry); + list_add_tail(instrs, &expr->entry);
- return &expr->node; + return expr; }
static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr)
From: Zebediah Figura zfigura@codeweavers.com
Instead of a flat location structure. --- libs/vkd3d-shader/hlsl.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index f0426620..3edbb978 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -836,12 +836,12 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va }
static void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type type, - struct hlsl_type *data_type, struct vkd3d_shader_location loc) + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) { memset(node, 0, sizeof(*node)); node->type = type; node->data_type = data_type; - node->loc = loc; + node->loc = *loc; list_init(&node->uses); }
@@ -864,7 +864,7 @@ struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hl
if (!(store = hlsl_alloc(ctx, sizeof(*store)))) return NULL; - init_node(&store->node, HLSL_IR_STORE, NULL, *loc); + init_node(&store->node, HLSL_IR_STORE, NULL, loc);
if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx)) return NULL; @@ -892,7 +892,7 @@ struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl
if (!(store = hlsl_alloc(ctx, sizeof(*store)))) return NULL; - init_node(&store->node, HLSL_IR_STORE, NULL, rhs->loc); + init_node(&store->node, HLSL_IR_STORE, NULL, &rhs->loc);
if (!init_deref_from_component_index(ctx, &comp_path_block, &store->lhs, lhs, comp, &rhs->loc)) { @@ -920,7 +920,7 @@ struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_typ if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL;
- init_node(&c->node, HLSL_IR_CONSTANT, type, *loc); + init_node(&c->node, HLSL_IR_CONSTANT, type, loc);
return c; } @@ -981,7 +981,7 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op
if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) return NULL; - init_node(&expr->node, HLSL_IR_EXPR, data_type, *loc); + init_node(&expr->node, HLSL_IR_EXPR, data_type, loc); expr->op = op; for (i = 0; i < HLSL_MAX_OPERANDS; ++i) hlsl_src_from_node(&expr->operands[i], operands[i]); @@ -1011,7 +1011,7 @@ struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condit
if (!(iff = hlsl_alloc(ctx, sizeof(*iff)))) return NULL; - init_node(&iff->node, HLSL_IR_IF, NULL, loc); + init_node(&iff->node, HLSL_IR_IF, NULL, &loc); hlsl_src_from_node(&iff->condition, condition); list_init(&iff->then_instrs.instrs); list_init(&iff->else_instrs.instrs); @@ -1033,7 +1033,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl
if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; - init_node(&load->node, HLSL_IR_LOAD, type, *loc); + init_node(&load->node, HLSL_IR_LOAD, type, loc);
if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx)) { @@ -1071,7 +1071,7 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b
type = get_type_from_deref(ctx, deref); comp_type = hlsl_type_get_component_type(ctx, type, comp); - init_node(&load->node, HLSL_IR_LOAD, comp_type, *loc); + init_node(&load->node, HLSL_IR_LOAD, comp_type, loc);
if (!init_deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc)) { @@ -1092,7 +1092,7 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx,
if (!(load = hlsl_alloc(ctx, sizeof(*load)))) return NULL; - init_node(&load->node, HLSL_IR_RESOURCE_LOAD, params->format, *loc); + init_node(&load->node, HLSL_IR_RESOURCE_LOAD, params->format, loc); load->load_type = params->type; if (!hlsl_copy_deref(ctx, &load->resource, ¶ms->resource)) { @@ -1119,7 +1119,7 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) return NULL; init_node(&swizzle->node, HLSL_IR_SWIZZLE, - hlsl_get_vector_type(ctx, val->data_type->base_type, components), *loc); + hlsl_get_vector_type(ctx, val->data_type->base_type, components), loc); hlsl_src_from_node(&swizzle->val, val); swizzle->swizzle = s; return swizzle; @@ -1131,7 +1131,7 @@ struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type
if (!(jump = hlsl_alloc(ctx, sizeof(*jump)))) return NULL; - init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); + init_node(&jump->node, HLSL_IR_JUMP, NULL, &loc); jump->type = type; return jump; } @@ -1142,7 +1142,7 @@ struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_loc
if (!(loop = hlsl_alloc(ctx, sizeof(*loop)))) return NULL; - init_node(&loop->node, HLSL_IR_LOOP, NULL, loc); + init_node(&loop->node, HLSL_IR_LOOP, NULL, &loc); list_init(&loop->body.instrs); return loop; }
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Henri Verbeet.