From: Zebediah Figura zfigura@codeweavers.com
--- tests/hlsl-bool-cast.shader_test | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/tests/hlsl-bool-cast.shader_test b/tests/hlsl-bool-cast.shader_test index 397cbcc0..b0913bb8 100644 --- a/tests/hlsl-bool-cast.shader_test +++ b/tests/hlsl-bool-cast.shader_test @@ -13,9 +13,11 @@ float4 main() : SV_TARGET draw quad probe all rgba (0.0, 0.0, 1.0, 1.0)
+ [require] shader model >= 4.0
+ [pixel shader] uniform float4 x; uniform int4 y; @@ -30,3 +32,17 @@ uniform 0 float4 0.0 0.0 2.0 4.0 uniform 4 int4 0 1 0 10 draw quad probe all rgba (0.0, 10.0, 1.0, 11.0) + + +[pixel shader] +uniform bool4 b; + +float4 main() : sv_target +{ + return (float4)b + (float4)(int4)b; +} + +[test] +uniform 0 uint4 0x00000001 0x00000002 0x80000000 0x00000000 +draw quad +todo probe all rgba (2.0, 2.0, 2.0, 0.0)
From: Zebediah Figura zfigura@codeweavers.com
--- Makefile.am | 1 + tests/bool-semantics.shader_test | 53 ++++++++++++++++++++++++++++++++ tests/shader_runner.c | 6 ++-- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 tests/bool-semantics.shader_test
diff --git a/Makefile.am b/Makefile.am index 549354b4..e5bec8fd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,6 +53,7 @@ vkd3d_shader_tests = \ tests/array-parameters.shader_test \ tests/asuint.shader_test \ tests/bitwise.shader_test \ + tests/bool-semantics.shader_test \ tests/cast-broadcast.shader_test \ tests/cast-componentwise-compatible.shader_test \ tests/cast-componentwise-equal.shader_test \ diff --git a/tests/bool-semantics.shader_test b/tests/bool-semantics.shader_test new file mode 100644 index 00000000..0e42fdf9 --- /dev/null +++ b/tests/bool-semantics.shader_test @@ -0,0 +1,53 @@ +[require] +shader model >= 4.0 + +[input layout] +0 r32g32b32a32 uint apple +0 r32g32 int sv_position + +[vertex buffer 0] +format r32 uint +0 1 0x80000000 0xffffffff -2 -2 +0 1 0x80000000 0xffffffff -2 2 +0 1 0x80000000 0xffffffff 2 -2 +0 1 0x80000000 0xffffffff 2 2 + +[vertex shader] + +struct input +{ + bool4 apple : apple; + int4 pos : sv_position; +}; + +struct output +{ + bool4 apple : apple; + int4 fapple : apple1; + float4 pos : sv_position; +}; + +void main(in struct input i, out struct output o, uint id : SV_VertexID) +{ + o.apple = i.apple; + o.fapple = i.apple; + o.pos = i.pos; +} + +[pixel shader] + +struct input +{ + bool4 apple : apple; + int4 fapple : apple1; + float4 pos : sv_position; +}; + +float4 main(struct input i) : sv_target +{ + return i.apple + i.fapple; +} + +[test] +draw triangle strip 4 +todo probe all rgba (0.0, 2.0, 2.0, 2.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 8e66948e..cf1c1266 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -151,7 +151,9 @@ static DXGI_FORMAT parse_format(const char *line, enum texture_data_type *data_t formats[] = { {"r32g32b32a32 float", TEXTURE_DATA_FLOAT, 16, DXGI_FORMAT_R32G32B32A32_FLOAT}, + {"r32g32b32a32 uint", TEXTURE_DATA_UINT, 16, DXGI_FORMAT_R32G32B32A32_UINT}, {"r32g32 float", TEXTURE_DATA_FLOAT, 8, DXGI_FORMAT_R32G32_FLOAT}, + {"r32g32 int", TEXTURE_DATA_SINT, 8, DXGI_FORMAT_R32G32_SINT}, {"r32g32 uint", TEXTURE_DATA_UINT, 8, DXGI_FORMAT_R32G32_UINT}, {"r32 float", TEXTURE_DATA_FLOAT, 4, DXGI_FORMAT_R32_FLOAT}, {"r32 sint", TEXTURE_DATA_SINT, 4, DXGI_FORMAT_R32_SINT}, @@ -269,11 +271,11 @@ static void parse_resource_directive(struct resource_params *resource, const cha break;
case TEXTURE_DATA_SINT: - u.i = strtol(line, &rest, 10); + u.i = strtol(line, &rest, 0); break;
case TEXTURE_DATA_UINT: - u.u = strtoul(line, &rest, 10); + u.u = strtoul(line, &rest, 0); break; }
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 16 ++-- libs/vkd3d-shader/hlsl.h | 15 ++-- libs/vkd3d-shader/hlsl.y | 10 +-- libs/vkd3d-shader/hlsl_codegen.c | 37 ++++---- libs/vkd3d-shader/hlsl_constant_ops.c | 124 +++++++++++++------------- libs/vkd3d-shader/tpf.c | 10 +-- 6 files changed, 106 insertions(+), 106 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 32511590..6cf22f3c 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -589,8 +589,8 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co { struct hlsl_ir_constant *c = hlsl_ir_constant(idx);
- assert(c->value[0].u < type->e.record.field_count); - return type->e.record.fields[c->value[0].u].type; + assert(c->value.u[0].u < type->e.record.field_count); + return type->e.record.fields[c->value.u[0].u].type; }
default: @@ -1133,7 +1133,7 @@ struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const struct hlsl_ir_constant *c;
if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), loc))) - c->value[0].u = b ? ~0u : 0; + c->value.u[0].u = b ? ~0u : 0;
return &c->node; } @@ -1144,7 +1144,7 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, struct hlsl_ir_constant *c;
if ((c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - c->value[0].f = f; + c->value.u[0].f = f;
return &c->node; } @@ -1156,7 +1156,7 @@ struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, cons c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc);
if (c) - c->value[0].i = n; + c->value.u[0].i = n;
return &c->node; } @@ -1169,7 +1169,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i c = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
if (c) - c->value[0].u = n; + c->value.u[0].u = n;
return c; } @@ -1503,7 +1503,7 @@ static struct hlsl_ir_node *clone_constant(struct hlsl_ctx *ctx, struct hlsl_ir_
if (!(dst = hlsl_new_constant(ctx, src->node.data_type, &src->node.loc))) return NULL; - memcpy(dst->value, src->value, sizeof(src->value)); + dst->value = src->value; return &dst->node; }
@@ -2234,7 +2234,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "{"); for (x = 0; x < type->dimx; ++x) { - const union hlsl_constant_value *value = &constant->value[x]; + const union hlsl_constant_value_component *value = &constant->value.u[x];
switch (type->base_type) { diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 86f35df2..40b6683e 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -620,13 +620,16 @@ struct hlsl_ir_store struct hlsl_ir_constant { struct hlsl_ir_node node; - union hlsl_constant_value + struct hlsl_constant_value { - uint32_t u; - int32_t i; - float f; - double d; - } value[4]; + union hlsl_constant_value_component + { + uint32_t u; + int32_t i; + float f; + double d; + } u[4]; + } value; /* Constant register of type 'c' where the constant value is stored for SM1. */ struct hlsl_reg reg; }; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index b9e03325..c700c04a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1104,7 +1104,7 @@ static unsigned int evaluate_static_expression(struct hlsl_ir_node *node) case HLSL_IR_CONSTANT: { struct hlsl_ir_constant *constant = hlsl_ir_constant(node); - const union hlsl_constant_value *value = &constant->value[0]; + const union hlsl_constant_value_component *value = &constant->value.u[0];
switch (constant->node.data_type->base_type) { @@ -2794,10 +2794,10 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx,
if (!(init = hlsl_new_constant(ctx, ret_type, loc))) return false; - init->value[0].f = 1.0f; - init->value[1].f = 0.0f; - init->value[2].f = 0.0f; - init->value[3].f = 1.0f; + init->value.u[0].f = 1.0f; + init->value.u[1].f = 0.0f; + init->value.u[2].f = 0.0f; + init->value.u[3].f = 1.0f; list_add_tail(params->instrs, &init->node.entry);
if (!(store = hlsl_new_simple_store(ctx, var, &init->node))) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 42f8ab3b..e5fd03e5 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -67,7 +67,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
case HLSL_CLASS_STRUCT: { - unsigned int field_idx = hlsl_ir_constant(idx)->value[0].u; + unsigned int field_idx = hlsl_ir_constant(idx)->value.u[0].u; struct hlsl_struct_field *field = &type->e.record.fields[field_idx];
if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset[regset], loc))) @@ -1026,7 +1026,7 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_
if (type->class == HLSL_CLASS_STRUCT) { - unsigned int idx = hlsl_ir_constant(path_node)->value[0].u; + unsigned int idx = hlsl_ir_constant(path_node)->value.u[0].u;
for (i = 0; i < idx; ++i) comp_start += hlsl_type_component_count(type->e.record.fields[i].type); @@ -1041,7 +1041,7 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ if (path_node->type == HLSL_IR_CONSTANT) { copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, - depth + 1, hlsl_ir_constant(path_node)->value[0].u * subtype_comp_count, writemask); + depth + 1, hlsl_ir_constant(path_node)->value.u[0].u * subtype_comp_count, writemask); } else { @@ -1136,7 +1136,7 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, { const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type); const struct hlsl_ir_var *var = deref->var; - union hlsl_constant_value values[4] = {0}; + struct hlsl_constant_value values = {0}; struct hlsl_ir_constant *cons; unsigned int start, count, i;
@@ -1151,15 +1151,12 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, || value->node->type != HLSL_IR_CONSTANT) return false;
- values[i] = hlsl_ir_constant(value->node)->value[value->component]; + values.u[i] = hlsl_ir_constant(value->node)->value.u[value->component]; }
if (!(cons = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) return false; - cons->value[0] = values[0]; - cons->value[1] = values[1]; - cons->value[2] = values[2]; - cons->value[3] = values[3]; + cons->value = values; list_add_before(&instr->entry, &cons->node.entry);
TRACE("Load from %s[%u-%u]%s turned into a constant %p.\n", @@ -1944,7 +1941,7 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *
component_count = hlsl_type_component_count(type); for (i = 0; i < component_count; ++i) - half->value[i].f = 0.5f; + half->value.u[i].f = 0.5f; list_add_before(&instr->entry, &half->node.entry);
if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, &half->node))) @@ -2063,7 +2060,7 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) return false; for (i = 0; i < type->dimx; ++i) - high_bit->value[i].u = 0x80000000; + high_bit->value.u[i].u = 0x80000000; list_add_before(&instr->entry, &high_bit->node.entry);
if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, &high_bit->node))) @@ -2130,7 +2127,7 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) return false; for (i = 0; i < type->dimx; ++i) - high_bit->value[i].u = 0x80000000; + high_bit->value.u[i].u = 0x80000000; list_add_before(&instr->entry, &high_bit->node.entry);
if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, &high_bit->node))) @@ -2246,7 +2243,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (!(one = hlsl_new_constant(ctx, type, &instr->loc))) return false; for (i = 0; i < type->dimx; ++i) - one->value[i].f = 1.0f; + one->value.u[i].f = 1.0f; list_add_before(&instr->entry, &one->node.entry);
if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &one->node, &cond->node))) @@ -2802,12 +2799,12 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b { for (x = 0, i = 0; x < 4; ++x) { - const union hlsl_constant_value *value; + const union hlsl_constant_value_component *value; float f;
if (!(writemask & (1u << x))) continue; - value = &constant->value[i++]; + value = &constant->value.u[i++];
switch (type->base_type) { @@ -3263,7 +3260,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl assert(path_node->data_type->class == HLSL_CLASS_SCALAR && path_node->data_type->base_type == HLSL_TYPE_UINT);
- idx = hlsl_ir_constant(path_node)->value[0].u; + idx = hlsl_ir_constant(path_node)->value.u[0].u;
switch (type->class) { @@ -3334,7 +3331,7 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref if (offset_node->type != HLSL_IR_CONSTANT) return false;
- *offset = hlsl_ir_constant(offset_node)->value[0].u; + *offset = hlsl_ir_constant(offset_node)->value.u[0].u;
size = deref->var->data_type->reg_size[deref->offset_regset]; if (*offset >= size) @@ -3416,12 +3413,12 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a } constant = hlsl_ir_constant(instr);
- if ((type->base_type == HLSL_TYPE_INT && constant->value[0].i <= 0) - || (type->base_type == HLSL_TYPE_UINT && !constant->value[0].u)) + if ((type->base_type == HLSL_TYPE_INT && constant->value.u[0].i <= 0) + || (type->base_type == HLSL_TYPE_UINT && !constant->value.u[0].u)) hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, "Thread count must be a positive integer.");
- ctx->thread_count[i] = constant->value[0].u; + ctx->thread_count[i] = constant->value.u[0].u; } }
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 212b37e5..f5bd1bc1 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -44,38 +44,38 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - u = src->value[k].f; - i = src->value[k].f; - f = src->value[k].f; - d = src->value[k].f; + u = src->value.u[k].f; + i = src->value.u[k].f; + f = src->value.u[k].f; + d = src->value.u[k].f; break;
case HLSL_TYPE_DOUBLE: - u = src->value[k].d; - i = src->value[k].d; - f = src->value[k].d; - d = src->value[k].d; + u = src->value.u[k].d; + i = src->value.u[k].d; + f = src->value.u[k].d; + d = src->value.u[k].d; break;
case HLSL_TYPE_INT: - u = src->value[k].i; - i = src->value[k].i; - f = src->value[k].i; - d = src->value[k].i; + u = src->value.u[k].i; + i = src->value.u[k].i; + f = src->value.u[k].i; + d = src->value.u[k].i; break;
case HLSL_TYPE_UINT: - u = src->value[k].u; - i = src->value[k].u; - f = src->value[k].u; - d = src->value[k].u; + u = src->value.u[k].u; + i = src->value.u[k].u; + f = src->value.u[k].u; + d = src->value.u[k].u; break;
case HLSL_TYPE_BOOL: - u = !!src->value[k].u; - i = !!src->value[k].u; - f = !!src->value[k].u; - d = !!src->value[k].u; + u = !!src->value.u[k].u; + i = !!src->value.u[k].u; + f = !!src->value.u[k].u; + d = !!src->value.u[k].u; break;
default: @@ -86,19 +86,19 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - dst->value[k].f = f; + dst->value.u[k].f = f; break;
case HLSL_TYPE_DOUBLE: - dst->value[k].d = d; + dst->value.u[k].d = d; break;
case HLSL_TYPE_INT: - dst->value[k].i = i; + dst->value.u[k].i = i; break;
case HLSL_TYPE_UINT: - dst->value[k].u = u; + dst->value.u[k].u = u; break;
case HLSL_TYPE_BOOL: @@ -123,16 +123,16 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - dst->value[k].f = -src->value[k].f; + dst->value.u[k].f = -src->value.u[k].f; break;
case HLSL_TYPE_DOUBLE: - dst->value[k].d = -src->value[k].d; + dst->value.u[k].d = -src->value.u[k].d; break;
case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = -src->value[k].u; + dst->value.u[k].u = -src->value.u[k].u; break;
default: @@ -158,18 +158,18 @@ static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, struct { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - dst->value[k].f = src1->value[k].f + src2->value[k].f; + dst->value.u[k].f = src1->value.u[k].f + src2->value.u[k].f; break;
case HLSL_TYPE_DOUBLE: - dst->value[k].d = src1->value[k].d + src2->value[k].d; + dst->value.u[k].d = src1->value.u[k].d + src2->value.u[k].d; break;
/* Handling HLSL_TYPE_INT through the unsigned field to avoid * undefined behavior with signed integers in C. */ case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u + src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u + src2->value.u[k].u; break;
default: @@ -195,16 +195,16 @@ static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - dst->value[k].f = src1->value[k].f * src2->value[k].f; + dst->value.u[k].f = src1->value.u[k].f * src2->value.u[k].f; break;
case HLSL_TYPE_DOUBLE: - dst->value[k].d = src1->value[k].d * src2->value[k].d; + dst->value.u[k].d = src1->value.u[k].d * src2->value.u[k].d; break;
case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u * src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u * src2->value.u[k].u; break;
default: @@ -229,24 +229,24 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - dst->value[k].u = src1->value[k].f != src2->value[k].f; + dst->value.u[k].u = src1->value.u[k].f != src2->value.u[k].f; break;
case HLSL_TYPE_DOUBLE: - dst->value[k].u = src1->value[k].d != src2->value[k].d; + dst->value.u[k].u = src1->value.u[k].d != src2->value.u[k].d; break;
case HLSL_TYPE_INT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: - dst->value[k].u = src1->value[k].u != src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u != src2->value.u[k].u; break;
default: vkd3d_unreachable(); }
- dst->value[k].u *= ~0u; + dst->value.u[k].u *= ~0u; } return true; } @@ -266,13 +266,13 @@ static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - if (ctx->profile->major_version >= 4 && src2->value[k].f == 0) + if (ctx->profile->major_version >= 4 && src2->value.u[k].f == 0) { hlsl_warning(ctx, &dst->node.loc, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO, "Floating point division by zero."); } - dst->value[k].f = src1->value[k].f / src2->value[k].f; - if (ctx->profile->major_version < 4 && !isfinite(dst->value[k].f)) + dst->value.u[k].f = src1->value.u[k].f / src2->value.u[k].f; + if (ctx->profile->major_version < 4 && !isfinite(dst->value.u[k].f)) { hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Infinities and NaNs are not allowed by the shader model."); @@ -280,35 +280,35 @@ static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, break;
case HLSL_TYPE_DOUBLE: - if (src2->value[k].d == 0) + if (src2->value.u[k].d == 0) { hlsl_warning(ctx, &dst->node.loc, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO, "Floating point division by zero."); } - dst->value[k].d = src1->value[k].d / src2->value[k].d; + dst->value.u[k].d = src1->value.u[k].d / src2->value.u[k].d; break;
case HLSL_TYPE_INT: - if (src2->value[k].i == 0) + if (src2->value.u[k].i == 0) { hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero."); return false; } - if (src1->value[k].i == INT_MIN && src2->value[k].i == -1) - dst->value[k].i = INT_MIN; + if (src1->value.u[k].i == INT_MIN && src2->value.u[k].i == -1) + dst->value.u[k].i = INT_MIN; else - dst->value[k].i = src1->value[k].i / src2->value[k].i; + dst->value.u[k].i = src1->value.u[k].i / src2->value.u[k].i; break;
case HLSL_TYPE_UINT: - if (src2->value[k].u == 0) + if (src2->value.u[k].u == 0) { hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero."); return false; } - dst->value[k].u = src1->value[k].u / src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u / src2->value.u[k].u; break;
default: @@ -333,26 +333,26 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, switch (type) { case HLSL_TYPE_INT: - if (src2->value[k].i == 0) + if (src2->value.u[k].i == 0) { hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero."); return false; } - if (src1->value[k].i == INT_MIN && src2->value[k].i == -1) - dst->value[k].i = 0; + if (src1->value.u[k].i == INT_MIN && src2->value.u[k].i == -1) + dst->value.u[k].i = 0; else - dst->value[k].i = src1->value[k].i % src2->value[k].i; + dst->value.u[k].i = src1->value.u[k].i % src2->value.u[k].i; break;
case HLSL_TYPE_UINT: - if (src2->value[k].u == 0) + if (src2->value.u[k].u == 0) { hlsl_error(ctx, &dst->node.loc, VKD3D_SHADER_ERROR_HLSL_DIVISION_BY_ZERO, "Division by zero."); return false; } - dst->value[k].u = src1->value[k].u % src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u % src2->value.u[k].u; break;
default: @@ -377,11 +377,11 @@ static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, switch (type) { case HLSL_TYPE_INT: - dst->value[k].i = max(src1->value[k].i, src2->value[k].i); + dst->value.u[k].i = max(src1->value.u[k].i, src2->value.u[k].i); break;
case HLSL_TYPE_UINT: - dst->value[k].u = max(src1->value[k].u, src2->value[k].u); + dst->value.u[k].u = max(src1->value.u[k].u, src2->value.u[k].u); break;
default: @@ -406,11 +406,11 @@ static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, switch (type) { case HLSL_TYPE_INT: - dst->value[k].i = min(src1->value[k].i, src2->value[k].i); + dst->value.u[k].i = min(src1->value.u[k].i, src2->value.u[k].i); break;
case HLSL_TYPE_UINT: - dst->value[k].u = min(src1->value[k].u, src2->value[k].u); + dst->value.u[k].u = min(src1->value.u[k].u, src2->value.u[k].u); break;
default: @@ -436,7 +436,7 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u ^ src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u ^ src2->value.u[k].u; break;
default: @@ -462,7 +462,7 @@ static bool fold_bit_and(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u & src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u & src2->value.u[k].u; break;
default: @@ -488,7 +488,7 @@ static bool fold_bit_or(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - dst->value[k].u = src1->value[k].u | src2->value[k].u; + dst->value.u[k].u = src1->value.u[k].u | src2->value.u[k].u; break;
default: @@ -616,7 +616,7 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst return false;
for (i = 0; i < swizzle->node.data_type->dimx; ++i) - res->value[i] = value->value[hlsl_swizzle_get_component(swizzle->swizzle, i)]; + res->value.u[i] = value->value.u[hlsl_swizzle_get_component(swizzle->swizzle, i)];
list_add_before(&swizzle->node.entry, &res->node.entry); hlsl_replace_node(&swizzle->node, &res->node); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 80487060..31545736 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3311,9 +3311,9 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, offset = hlsl_ir_constant(texel_offset);
modif.type = VKD3D_SM4_MODIFIER_AOFFIMMI; - modif.u.aoffimmi.u = offset->value[0].i; - modif.u.aoffimmi.v = offset->value[1].i; - modif.u.aoffimmi.w = offset->value[2].i; + modif.u.aoffimmi.u = offset->value.u[0].i; + modif.u.aoffimmi.v = offset->value.u[1].i; + modif.u.aoffimmi.w = offset->value.u[2].i; if (modif.u.aoffimmi.u < -8 || modif.u.aoffimmi.u > 7 || modif.u.aoffimmi.v < -8 || modif.u.aoffimmi.v > 7 || modif.u.aoffimmi.w < -8 || modif.u.aoffimmi.w > 7) @@ -3636,7 +3636,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, if (dimx == 1) { reg->dim = VKD3D_SM4_DIMENSION_SCALAR; - reg->immconst_uint[0] = constant->value[0].u; + reg->immconst_uint[0] = constant->value.u[0].u; } else { @@ -3646,7 +3646,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, for (i = 0; i < 4; ++i) { if (instr.dsts[0].writemask & (1u << i)) - reg->immconst_uint[i] = constant->value[j++].u; + reg->immconst_uint[i] = constant->value.u[j++].u; } } instr.src_count = 1,
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/tpf.c | 43 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 31545736..ae4b4aff 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3213,6 +3213,29 @@ static void sm4_src_from_node(struct sm4_src_register *src, src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); }
+static void sm4_src_from_constant_value(struct sm4_src_register *src, + const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) +{ + src->swizzle_type = VKD3D_SM4_SWIZZLE_NONE; + src->reg.type = VKD3D_SM4_RT_IMMCONST; + if (width == 1) + { + src->reg.dim = VKD3D_SM4_DIMENSION_SCALAR; + src->reg.immconst_uint[0] = value->u[0].u; + } + else + { + unsigned int i, j = 0; + + src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; + for (i = 0; i < 4; ++i) + { + if (map_writemask & (1u << i)) + src->reg.immconst_uint[i] = value->u[j++].u; + } + } +} + static uint32_t sm4_encode_register(const struct sm4_register *reg) { return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT) @@ -3623,7 +3646,6 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, { const unsigned int dimx = constant->node.data_type->dimx; struct sm4_instruction instr; - struct sm4_register *reg = &instr.srcs[0].reg;
memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; @@ -3631,24 +3653,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, sm4_dst_from_node(&instr.dsts[0], &constant->node); instr.dst_count = 1;
- instr.srcs[0].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; - reg->type = VKD3D_SM4_RT_IMMCONST; - if (dimx == 1) - { - reg->dim = VKD3D_SM4_DIMENSION_SCALAR; - reg->immconst_uint[0] = constant->value.u[0].u; - } - else - { - unsigned int i, j = 0; - - reg->dim = VKD3D_SM4_DIMENSION_VEC4; - for (i = 0; i < 4; ++i) - { - if (instr.dsts[0].writemask & (1u << i)) - reg->immconst_uint[i] = constant->value.u[j++].u; - } - } + sm4_src_from_constant_value(&instr.srcs[0], &constant->value, dimx, instr.dsts[0].writemask); instr.src_count = 1,
write_sm4_instruction(buffer, &instr);
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/tpf.c | 40 +++++++++++++++++++++++++++++--- tests/bool-semantics.shader_test | 2 +- tests/cast-to-int.shader_test | 2 +- tests/cast-to-uint.shader_test | 2 +- tests/hlsl-bool-cast.shader_test | 2 +- 5 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index ae4b4aff..a669dbfb 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4343,19 +4343,53 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, write_sm4_instruction(buffer, &instr); }
+/* Does this variable's data come directly from the API user, rather than being + * temporary or from a previous shader stage? + * I.e. is it a uniform or VS input? */ +static bool var_is_user_input(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) +{ + if (var->is_uniform) + return true; + + return var->is_input_semantic && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; +} + static void write_sm4_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_load *load) { + const struct hlsl_type *type = load->node.data_type; struct sm4_instruction instr;
memset(&instr, 0, sizeof(instr)); - instr.opcode = VKD3D_SM4_OP_MOV;
sm4_dst_from_node(&instr.dsts[0], &load->node); instr.dst_count = 1;
- sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, load->node.data_type, instr.dsts[0].writemask); - instr.src_count = 1; + assert(type->class <= HLSL_CLASS_LAST_NUMERIC); + if (type->base_type == HLSL_TYPE_BOOL && var_is_user_input(ctx, load->src.var)) + { + struct hlsl_constant_value value; + + /* Uniform bools can be specified as anything, but internal bools always + * have 0 for false and ~0 for true. Normalize that here. */ + + instr.opcode = VKD3D_SM4_OP_MOVC; + + sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, type, instr.dsts[0].writemask); + + memset(&value, 0xff, sizeof(value)); + sm4_src_from_constant_value(&instr.srcs[1], &value, type->dimx, instr.dsts[0].writemask); + memset(&value, 0, sizeof(value)); + sm4_src_from_constant_value(&instr.srcs[2], &value, type->dimx, instr.dsts[0].writemask); + instr.src_count = 3; + } + else + { + instr.opcode = VKD3D_SM4_OP_MOV; + + sm4_src_from_deref(ctx, &instr.srcs[0], &load->src, type, instr.dsts[0].writemask); + instr.src_count = 1; + }
write_sm4_instruction(buffer, &instr); } diff --git a/tests/bool-semantics.shader_test b/tests/bool-semantics.shader_test index 0e42fdf9..bcbd9f9b 100644 --- a/tests/bool-semantics.shader_test +++ b/tests/bool-semantics.shader_test @@ -50,4 +50,4 @@ float4 main(struct input i) : sv_target
[test] draw triangle strip 4 -todo probe all rgba (0.0, 2.0, 2.0, 2.0) +probe all rgba (0.0, 2.0, 2.0, 2.0) diff --git a/tests/cast-to-int.shader_test b/tests/cast-to-int.shader_test index 4c5d0e2f..fe8c79a3 100644 --- a/tests/cast-to-int.shader_test +++ b/tests/cast-to-int.shader_test @@ -20,7 +20,7 @@ uniform 1 int -2 uniform 2 int -2 uniform 3 float -3.6 draw quad -todo probe all rgba (0.5, 0.5, 0.5, 0.5) +probe all rgba (0.5, 0.5, 0.5, 0.5)
[pixel shader]
diff --git a/tests/cast-to-uint.shader_test b/tests/cast-to-uint.shader_test index 66f7267e..4ffc041a 100644 --- a/tests/cast-to-uint.shader_test +++ b/tests/cast-to-uint.shader_test @@ -20,7 +20,7 @@ uniform 1 int 2 uniform 2 int -2 uniform 3 float -3.6 draw quad -todo probe all rgba (0.5, 0.5, 0.5, 0.5) +probe all rgba (0.5, 0.5, 0.5, 0.5)
[pixel shader]
diff --git a/tests/hlsl-bool-cast.shader_test b/tests/hlsl-bool-cast.shader_test index b0913bb8..09ca12e2 100644 --- a/tests/hlsl-bool-cast.shader_test +++ b/tests/hlsl-bool-cast.shader_test @@ -45,4 +45,4 @@ float4 main() : sv_target [test] uniform 0 uint4 0x00000001 0x00000002 0x80000000 0x00000000 draw quad -todo probe all rgba (2.0, 2.0, 2.0, 0.0) +probe all rgba (2.0, 2.0, 2.0, 0.0)
Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/hlsl.h:
- union hlsl_constant_value
- struct hlsl_constant_value {
uint32_t u;
int32_t i;
float f;
double d;
- } value[4];
union hlsl_constant_value_component
{
uint32_t u;
int32_t i;
float f;
double d;
} u[4];
- } value;
What's the advantage of that? I can't say I really like all the `.u` that you have to sprinkle throughout the code.
On Fri Apr 21 09:07:42 2023 +0000, Giovanni Mascellani wrote:
What's the advantage of that? I can't say I really like all the `.u` that you have to sprinkle throughout the code.
Being able to pass around hlsl_constant_value directly, mainly, without having to implicitly worry about array size mismatches. There are two places that I want to do this: firstly (what this patch was originally written for) I'd like to pass it to hlsl_new_constant(), to make the function able to return hlsl_ir_node and generally more consistent with other functions; secondly, the sm4_src_from_constant_value() helper introduced in patch 4/5.
On Fri Apr 21 17:49:24 2023 +0000, Zebediah Figura wrote:
Being able to pass around hlsl_constant_value directly, mainly, without having to implicitly worry about array size mismatches. There are two places that I want to do this: firstly (what this patch was originally written for) I'd like to pass it to hlsl_new_constant(), to make the function able to return hlsl_ir_node and generally more consistent with other functions; secondly, the sm4_src_from_constant_value() helper introduced in patch 4/5.
Ah, right, you cannot copy around arrays easily in C. Unfortunate, but ok.
This merge request was approved by Giovanni Mascellani.
This merge request was approved by Francisco Casas.
I see that the native compiler does ``` ine ·, ·, l(0, 0, 0, 0) ``` movc also works, but is there a particular reason to choose movc over ine ?
movc also works, but is there a particular reason to choose movc over ine ?
It was the first thing I thought of :-)
This merge request was approved by Henri Verbeet.