From: Zebediah Figura zfigura@codeweavers.com
--- tests/asuint.shader_test | 40 ++++++++++++++++++++++++++++++++++++++++ tests/shader_runner.c | 12 ++++++++---- 2 files changed, 48 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..eda96f58 --- /dev/null +++ b/tests/asuint.shader_test @@ -0,0 +1,40 @@ +[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 fail todo] + +float4 main() : sv_target +{ + bool b = true; + + return asuint(b); +} + + +[pixel shader fail todo] + +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 | 30 +++++++++++++----------- libs/vkd3d-shader/hlsl.h | 3 +++ libs/vkd3d-shader/hlsl.y | 49 ++++++++++++++++++++++++++++++++++++++++ tests/asuint.shader_test | 4 ++-- 4 files changed, 71 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index c1cd065a..1a92af3f 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -962,33 +962,36 @@ 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_type *data_type, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], 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, arg->data_type, operands, &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, arg1->data_type, operands, &arg1->loc); }
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) @@ -1642,6 +1645,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..4002ca51 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, @@ -759,6 +760,8 @@ 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_type *data_type, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], 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 fc3b31a4..0c427005 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2053,6 +2053,54 @@ 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; + struct hlsl_ir_node *expr; + + 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]; + if (!(expr = hlsl_new_expr(ctx, HLSL_OP1_REINTERPRET, data_type, operands, loc))) + return false; + list_add_tail(params->instrs, &expr->entry); + return true; +} + static bool intrinsic_clamp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2333,6 +2381,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}, diff --git a/tests/asuint.shader_test b/tests/asuint.shader_test index eda96f58..3511d044 100644 --- a/tests/asuint.shader_test +++ b/tests/asuint.shader_test @@ -20,7 +20,7 @@ todo draw quad probe (320,240) rgba (123.0, 3221225472.0, 456.0, 2144768896.0)
-[pixel shader fail todo] +[pixel shader fail]
float4 main() : sv_target { @@ -30,7 +30,7 @@ float4 main() : sv_target }
-[pixel shader fail todo] +[pixel shader fail]
float4 main() : sv_target {
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl_sm4.c | 4 ++++ tests/asuint.shader_test | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-)
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 3511d044..192dddd4 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)
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 10 ++++++++++ libs/vkd3d-shader/hlsl.h | 10 ---------- libs/vkd3d-shader/hlsl.y | 12 ++++-------- 3 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 1a92af3f..6925c2cc 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; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 4002ca51..787500e1 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; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 0c427005..25698fff 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, type, operands, 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 6925c2cc..20698d80 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; } @@ -980,7 +980,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]); @@ -1010,7 +1010,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); @@ -1032,7 +1032,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)) { @@ -1070,7 +1070,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)) { @@ -1091,7 +1091,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)) { @@ -1118,7 +1118,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; @@ -1130,7 +1130,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; } @@ -1141,7 +1141,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; }
Not a big deal, but maybe it would make sense to test a matrix and a vector too.
On 9/29/22 08:26, Giovanni Mascellani (@giomasce) wrote:
Not a big deal, but maybe it would make sense to test a matrix and a vector too.
Thanks, I've added those tests as well.