-- v7: vkd3d-shader/spirv: Avoid invalid bool-to-bool conversion in spirv_compiler_emit_movc(). vkd3d-shader/dxil: Implement the DXIL VSELECT instruction. tests/shader-runner: Add tests for 64-bit casts. vkd3d-shader/spirv: Return an error if an invalid handler is encountered. tests/shader-runner: Add a test for float comparisons.
From: Conor McCarthy cmccarthy@codeweavers.com
Where SM >= 6.0 returns different results than earlier models it is convenient to use conditional 'probe' lines containing different expected values. --- tests/hlsl/arithmetic-int.shader_test | 9 +++------ tests/hlsl/duplicate-modifiers.shader_test | 7 ++----- tests/hlsl/entry-point-semantics.shader_test | 17 ++++++----------- tests/hlsl/side-effects.shader_test | 9 +++------ tests/shader_runner.c | 5 +++++ 5 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/tests/hlsl/arithmetic-int.shader_test b/tests/hlsl/arithmetic-int.shader_test index f2044c42c..1128a004f 100644 --- a/tests/hlsl/arithmetic-int.shader_test +++ b/tests/hlsl/arithmetic-int.shader_test @@ -104,8 +104,6 @@ probe all rgba (0.0, 0.0, 0.0, 0.0)
[require] shader model >= 4.0 -% dxcompiler performs this calculation on unsigned values and emits zero. -shader model < 6.0
[pixel shader] float4 main() : SV_TARGET @@ -118,10 +116,9 @@ float4 main() : SV_TARGET
[test] draw quad -probe all rgba (-2147483648.0, -2147483648.0, -2147483648.0, -2147483648.0) - -[require] -shader model >= 4.0 +if(sm<6) probe all rgba (-2147483648.0, -2147483648.0, -2147483648.0, -2147483648.0) +% dxcompiler performs this calculation on unsigned values and emits zero. +if(sm>=6) probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] float4 main() : sv_target diff --git a/tests/hlsl/duplicate-modifiers.shader_test b/tests/hlsl/duplicate-modifiers.shader_test index bf1d9c1b8..8a3838ffe 100644 --- a/tests/hlsl/duplicate-modifiers.shader_test +++ b/tests/hlsl/duplicate-modifiers.shader_test @@ -1,7 +1,3 @@ -% Returns (0.1, 0.3, 0.2, 0.4) with dxcompiler -[require] -shader model < 6.0 - [pixel shader] typedef const precise row_major float2x2 mat_t; float4 main() : sv_target @@ -12,4 +8,5 @@ float4 main() : sv_target
[test] draw quad -probe all rgba (0.1, 0.2, 0.3, 0.4) +if(sm<6) probe all rgba (0.1, 0.2, 0.3, 0.4) +if(sm>=6) probe all rgba (0.1, 0.3, 0.2, 0.4) diff --git a/tests/hlsl/entry-point-semantics.shader_test b/tests/hlsl/entry-point-semantics.shader_test index d177b0376..e4854a294 100644 --- a/tests/hlsl/entry-point-semantics.shader_test +++ b/tests/hlsl/entry-point-semantics.shader_test @@ -104,11 +104,6 @@ draw quad probe (0, 0) rgba (10.0, 11.0, 30.0, 31.0)
-% dxcompiler emits correct array addressing. -[require] -shader model < 6.0 - - % Arrays (even multi-dimensional) of struct elements are allowed. The fields in the different struct % elements get the same indexes. [pixel shader] @@ -125,7 +120,9 @@ float4 main(in apple aps[2][2]) : sv_target
[test] draw quad -todo(sm>=6) probe (0, 0) rgba (10.0, 10.0, 20.0, 20.0) +if(sm<6) probe (0, 0) rgba (10.0, 10.0, 20.0, 20.0) +% dxcompiler emits correct array addressing. +if(sm>=6) probe (0, 0) rgba (10.0, 40.0, 10.0, 10.0)
[pixel shader] @@ -147,11 +144,9 @@ float4 main(in banana bans[2]) : sv_target
[test] draw quad -todo(sm>=6) probe (0, 0) rgba (10.0, 11.0, 20.0, 21.0) - - -[require] -% reset requirements +if(sm<6) probe (0, 0) rgba (10.0, 11.0, 20.0, 21.0) +% dxcompiler emits correct array addressing. +if(sm>=6) probe (0, 0) rgba (10.0, 11.0, 40.0, 41.0)
[pixel shader fail] diff --git a/tests/hlsl/side-effects.shader_test b/tests/hlsl/side-effects.shader_test index f41e98510..c49a907ba 100644 --- a/tests/hlsl/side-effects.shader_test +++ b/tests/hlsl/side-effects.shader_test @@ -27,11 +27,6 @@ draw quad probe all rgba (11.0, 11.0, 11.0, 11.0)
-% dxcompiler performs the first call to func() before the array index call. -[require] -shader model < 6.0 - - [pixel shader] float4 func(void) { @@ -49,4 +44,6 @@ float4 main() : sv_target
[test] draw quad -probe all rgba (2.2, 2.2, 2.2, 2.2) +if(sm<6) probe all rgba (2.2, 2.2, 2.2, 2.2) +% dxcompiler performs the first call to func() before the array index call. +if(sm>=6) probe all rgba (1.3, 1.3, 1.3, 1.3) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index dadfe3338..def7ec877 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -496,6 +496,11 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) char *rest; int ret;
+ if (match_string(line, "if(sm<6)", &line) && runner->maximum_shader_model >= SHADER_MODEL_6_0) + return; + else if (match_string(line, "if(sm>=6)", &line) && runner->maximum_shader_model < SHADER_MODEL_6_0) + return; + runner->is_todo = false;
if (match_string(line, "todo", &line))
From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/hlsl/float-comparison.shader_test | 49 +++++++++++++++++++++++++ tests/shader_runner.c | 7 +++- 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/hlsl/float-comparison.shader_test
diff --git a/Makefile.am b/Makefile.am index 002746829..a5c5fe62f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -87,6 +87,7 @@ vkd3d_shader_tests = \ tests/hlsl/entry-point-semantics.shader_test \ tests/hlsl/exp.shader_test \ tests/hlsl/expr-indexing.shader_test \ + tests/hlsl/float-comparison.shader_test \ tests/hlsl/floor.shader_test \ tests/hlsl/fmod.shader_test \ tests/hlsl/for.shader_test \ diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test new file mode 100644 index 000000000..8fa7e3d03 --- /dev/null +++ b/tests/hlsl/float-comparison.shader_test @@ -0,0 +1,49 @@ +[pixel shader] +uniform float4 f; + +float4 main() : sv_target +{ + float4 result; + float n = f.x/f.w; + + /* '!(condition)' in SM6 forces use of the unordered instruction variant. */ + + result.x = (f.y > f.x) ? 1.0 : 0.0; + result.x += (f.y < f.x) ? 10.0 : 0.0; + result.x += (f.y >= f.x) ? 100.0 : 0.0; + result.x += (f.y <= f.x) ? 1000.0 : 0.0; + result.x += !(f.y <= f.x) ? 10000.0 : 0.0; + result.x += !(f.y >= f.x) ? 100000.0 : 0.0; + result.x += !(f.y < f.x) ? 1000000.0 : 0.0; + result.x += !(f.y > f.x) ? 10000000.0 : 0.0; + result.y = (n > f.x) ? 1.0 : 0.0; + result.y += (n < f.x) ? 10.0 : 0.0; + result.y += (n >= f.x) ? 100.0 : 0.0; + result.y += (n <= f.x) ? 1000.0 : 0.0; + result.y += !(n <= f.x) ? 10000.0 : 0.0; + result.y += !(n >= f.x) ? 100000.0 : 0.0; + result.y += !(n < f.x) ? 1000000.0 : 0.0; + result.y += !(n > f.x) ? 10000000.0 : 0.0; + result.z = (f.z == f.y) ? 1.0 : 0.0; + result.z += (f.z != f.y) ? 10.0 : 0.0; + result.z += !(f.z == f.y) ? 100.0 : 0.0; + result.z += !(f.z != f.y) ? 1000.0 : 0.0; + result.z += (n == f.y) ? 10000.0 : 0.0; + result.z += (n != f.y) ? 100000.0 : 0.0; + result.z += !(n == f.y) ? 1000000.0 : 0.0; + result.z += !(n != f.y) ? 10000000.0 : 0.0; + /* It doesn't seem possible to generate DXIL instructions for 'is ordered' or 'is unordered'. + * Expressions 'isnan(n)' and '(isnan(n) || isnan(f.x))' compile into intrinsics. */ + result.w = 0; + return result; +} + +[test] +uniform 0 float4 0.0 1.5 1.5 0.0 +todo(sm>=6) draw quad +% SM1-3 apparently treats '0/0' as zero. +if(sm<4) todo probe all rgba (1010101.0, 11001100.0, 1101001.0, 0.0) +% SM4-5 optimises away the 'not' by inverting the condition, even though this is invalid for NaN. +if(sm<6) todo probe all rgba (1010101.0, 0.0, 1101001.0, 0.0) +% SM6 emits the correct ordered/unordered instructions, so comparisons are false for NaN, and are made true with 'not'. +if(sm>=6) probe all rgba (1010101.0, 11110000.0, 1101001.0, 0.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index def7ec877..6beb4a418 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -496,7 +496,12 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) char *rest; int ret;
- if (match_string(line, "if(sm<6)", &line) && runner->maximum_shader_model >= SHADER_MODEL_6_0) + if (match_string(line, "if(sm<4)", &line) && runner->maximum_shader_model >= SHADER_MODEL_4_0) + return; + else if (match_string(line, "if(4<=sm<6)", &line) + && (runner->maximum_shader_model < SHADER_MODEL_4_0 || runner->maximum_shader_model >= SHADER_MODEL_6_0)) + return; + else if (match_string(line, "if(sm<6)", &line) && runner->maximum_shader_model >= SHADER_MODEL_6_0) return; else if (match_string(line, "if(sm>=6)", &line) && runner->maximum_shader_model < SHADER_MODEL_6_0) return;
From: Conor McCarthy cmccarthy@codeweavers.com
Prevents assertions while handling later instructions, and prevents return of an invalid SPIR-V module. --- libs/vkd3d-shader/spirv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d2621ffa1..2f88ecb31 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6657,7 +6657,7 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); }
-static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, +static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -6681,7 +6681,7 @@ static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, /* VSIR supports cast from bool to signed/unsigned integer types and floating point types, * where bool is treated as a 1-bit integer and a signed 'true' value converts to -1. */ spirv_compiler_emit_bool_cast(compiler, instruction); - return; + return VKD3D_OK; } } else @@ -6694,7 +6694,7 @@ static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, ERR("Unexpected instruction %#x.\n", instruction->handler_idx); spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, "Encountered invalid/unhandled instruction handler %#x.", instruction->handler_idx); - return; + return VKD3D_ERROR_INVALID_SHADER; }
assert(instruction->dst_count == 1); @@ -6726,6 +6726,7 @@ static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
spirv_compiler_emit_store_dst(compiler, dst, val_id); + return VKD3D_OK; }
static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( @@ -9506,7 +9507,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_UTOF: case VKD3DSIH_UTOU: case VKD3DSIH_XOR: - spirv_compiler_emit_alu_instruction(compiler, instruction); + ret = spirv_compiler_emit_alu_instruction(compiler, instruction); break; case VKD3DSIH_DFMA: case VKD3DSIH_DMAX: @@ -9727,6 +9728,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, break; default: FIXME("Unhandled instruction %#x.\n", instruction->handler_idx); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, + "Encountered invalid/unhandled instruction handler %#x.", instruction->handler_idx); + return VKD3D_ERROR_INVALID_SHADER; }
return ret;
From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/d3d12.c | 5 --- tests/hlsl/cast-64-bit.shader_test | 57 ++++++++++++++++++++++++++ tests/shader_runner.c | 64 ++++++++++++++++++++++++++++++ tests/utils.h | 15 +++++++ 5 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 tests/hlsl/cast-64-bit.shader_test
diff --git a/Makefile.am b/Makefile.am index a5c5fe62f..2666194a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -61,6 +61,7 @@ vkd3d_shader_tests = \ tests/hlsl/bitwise.shader_test \ tests/hlsl/bool-cast.shader_test \ tests/hlsl/bool-semantics.shader_test \ + tests/hlsl/cast-64-bit.shader_test \ tests/hlsl/cast-broadcast.shader_test \ tests/hlsl/cast-componentwise-compatible.shader_test \ tests/hlsl/cast-componentwise-equal.shader_test \ diff --git a/tests/d3d12.c b/tests/d3d12.c index 8f100a5e7..f9b5c5e98 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -42,11 +42,6 @@ static ID3D10Blob *compile_shader(const char *source, size_t len, const char *pr return bytecode; }
-struct dvec2 -{ - double x, y; -}; - static bool compare_uint8(uint8_t a, uint8_t b, unsigned int max_diff) { return abs(a - b) <= max_diff; diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test new file mode 100644 index 000000000..813cce108 --- /dev/null +++ b/tests/hlsl/cast-64-bit.shader_test @@ -0,0 +1,57 @@ +[require] +shader model >= 5.0 + +[pixel shader todo] +uniform double2 d; +uniform float2 f; + +float4 main() : sv_target +{ + double2 n = d / f; + return float4(d.x, d.y, n.x, n.y); +} + +[test] +uniform 0 double2 -4.5 8.5 +uniform 4 float4 -2.25 4.25 0.0 0.0 +todo(sm<6) draw quad +probe all rgba (-4.5, 8.5, 2.0, 2.0) + + +[require] +shader model >= 6.0 + +[pixel shader] +uniform uint64_t2 l; +uniform uint2 u; + +float4 main() : sv_target +{ + uint64_t2 n = l / u; + uint4 result = uint4(l.x, l.y, n.x, n.y); + return result; +} + +[test] +uniform 0 uint64_t2 0x500000001 0x100000002 +uniform 4 uint4 10 4 0 0 +todo draw quad +todo probe all rgba (1.0, 2.0, 2147483648.0, 1073741824.0) + + +[pixel shader] +uniform int64_t2 l; +uniform int2 i; + +float4 main() : sv_target +{ + int64_t2 n = l / i; + int4 result = int4(l.x, l.y, n.x, n.y); + return result; +} + +[test] +uniform 0 int64_t2 -21474836481 0x100000002 +uniform 4 int4 -20 8 0 0 +todo draw quad +todo probe all rgba (-1.0, 2.0, 1073741824.0, 536870912.0) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 6beb4a418..c7ca2df99 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -491,6 +491,48 @@ static void read_uint4(const char **line, struct uvec4 *v) read_uint(line, &v->w); }
+static void read_int64(const char **line, int64_t *i) +{ + char *rest; + int64_t val; + + errno = 0; + val = strtoll(*line, &rest, 0); + + if (errno != 0 || (*rest != '\0' && !isspace((unsigned char)*rest))) + fatal_error("Malformed int64 constant '%s'.\n", *line); + + *i = val; + *line = rest; +} + +static void read_uint64(const char **line, uint64_t *u) +{ + char *rest; + uint64_t val; + + errno = 0; + val = strtoull(*line, &rest, 0); + + if (errno != 0 || (*rest != '\0' && !isspace((unsigned char)*rest))) + fatal_error("Malformed uint64 constant '%s'.\n", *line); + + *u = val; + *line = rest; +} + +static void read_int64_t4(const char **line, struct i64vec2 *v) +{ + read_int64(line, &v->x); + read_int64(line, &v->y); +} + +static void read_uint64_t4(const char **line, struct u64vec2 *v) +{ + read_uint64(line, &v->x); + read_uint64(line, &v->y); +} + static void parse_test_directive(struct shader_runner *runner, const char *line) { char *rest; @@ -736,6 +778,14 @@ 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, "double2", &line)) + { + struct dvec2 v; + + if (sscanf(line, "%lf %lf", &v.x, &v.y) < 2) + fatal_error("Malformed double2 constant '%s'.\n", line); + set_uniforms(runner, offset, 4, &v); + } else if (match_string(line, "int4", &line)) { struct ivec4 v; @@ -764,6 +814,20 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) read_uint(&line, &u); set_uniforms(runner, offset, 1, &u); } + else if (match_string(line, "int64_t2", &line)) + { + struct i64vec2 v; + + read_int64_t4(&line, &v); + set_uniforms(runner, offset, 4, &v); + } + else if (match_string(line, "uint64_t2", &line)) + { + struct u64vec2 v; + + read_uint64_t4(&line, &v); + set_uniforms(runner, offset, 4, &v); + } else { fatal_error("Unknown uniform type '%s'.\n", line); diff --git a/tests/utils.h b/tests/utils.h index 670941905..e8bbacc37 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -35,6 +35,11 @@ struct vec4 float x, y, z, w; };
+struct dvec2 +{ + double x, y; +}; + struct ivec4 { int x, y, z, w; @@ -45,6 +50,16 @@ struct uvec4 unsigned int x, y, z, w; };
+struct i64vec2 +{ + int64_t x, y; +}; + +struct u64vec2 +{ + uint64_t x, y; +}; + struct resource_readback { uint64_t width;
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 63 +++++++++++++++++++++++++ tests/hlsl/conditional.shader_test | 6 +-- tests/hlsl/float-comparison.shader_test | 2 +- tests/hlsl/for.shader_test | 2 +- tests/hlsl/return.shader_test | 12 ++--- tests/hlsl/step.shader_test | 2 +- tests/hlsl/switch.shader_test | 12 ++--- tests/hlsl/ternary.shader_test | 7 +-- 8 files changed, 85 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2174ba52c..4d289ab85 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -2156,6 +2156,18 @@ static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx) return i; }
+static bool sm6_value_validate_is_register(const struct sm6_value *value, struct sm6_parser *sm6) +{ + if (!sm6_value_is_register(value)) + { + WARN("Operand of type %u is not a register.\n", value->value_type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "A register operand passed to a DXIL instruction is not a register."); + return false; + } + return true; +} + static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_value_is_handle(value)) @@ -2168,6 +2180,19 @@ static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct s return true; }
+static bool sm6_value_validate_is_bool(const struct sm6_value *value, struct sm6_parser *sm6) +{ + const struct sm6_type *type = value->type; + if (!sm6_type_is_bool(type)) + { + WARN("Operand of type class %u is not bool.\n", type->class); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "A bool operand of type class %u passed to a DXIL instruction is not a bool.", type->class); + return false; + } + return true; +} + static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx) { if (idx < sm6->value_count) @@ -3653,6 +3678,41 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record ins->handler_idx = VKD3DSIH_NOP; }
+static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +{ + struct vkd3d_shader_src_param *src_params; + const struct sm6_value *src[3]; + unsigned int i = 0; + + if (!(src[1] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)) + || !(src[2] = sm6_parser_get_value_by_ref(sm6, record, src[1]->type, &i)) + || !(src[0] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) + { + return; + } + dxil_record_validate_operand_max_count(record, i, sm6); + + for (i = 0; i < 3; ++i) + { + if (!sm6_value_validate_is_register(src[i], sm6)) + return; + } + + dst->type = src[1]->type; + + if (!sm6_value_validate_is_bool(src[0], sm6)) + return; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC); + + src_params = instruction_src_params_alloc(ins, 3, sm6); + for (i = 0; i < 3; ++i) + src_param_init_from_value(&src_params[i], src[i]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static bool sm6_metadata_value_is_node(const struct sm6_metadata_value *m) { return m && m->type == VKD3D_METADATA_NODE; @@ -3813,6 +3873,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const is_terminator = true; ret_found = true; break; + case FUNC_CODE_INST_VSELECT: + sm6_parser_emit_vselect(sm6, record, ins, dst); + break; default: FIXME("Unhandled dxil instruction %u.\n", record->code); return VKD3D_ERROR_INVALID_SHADER; diff --git a/tests/hlsl/conditional.shader_test b/tests/hlsl/conditional.shader_test index 4175813bd..0a927a8fa 100644 --- a/tests/hlsl/conditional.shader_test +++ b/tests/hlsl/conditional.shader_test @@ -11,10 +11,10 @@ float4 main() : sv_target
[test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.9, 0.8, 0.7, 0.6) uniform 0 float4 0.1 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4)
[pixel shader] @@ -43,7 +43,7 @@ float4 main() : sv_target
[test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.9, 0.8, 0.7, 0.6)
[pixel shader fail(sm<6)] diff --git a/tests/hlsl/float-comparison.shader_test b/tests/hlsl/float-comparison.shader_test index 8fa7e3d03..5bbe9c06b 100644 --- a/tests/hlsl/float-comparison.shader_test +++ b/tests/hlsl/float-comparison.shader_test @@ -40,7 +40,7 @@ float4 main() : sv_target
[test] uniform 0 float4 0.0 1.5 1.5 0.0 -todo(sm>=6) draw quad +draw quad % SM1-3 apparently treats '0/0' as zero. if(sm<4) todo probe all rgba (1010101.0, 11001100.0, 1101001.0, 0.0) % SM4-5 optimises away the 'not' by inverting the condition, even though this is invalid for NaN. diff --git a/tests/hlsl/for.shader_test b/tests/hlsl/for.shader_test index e5faa28fd..1392118b3 100644 --- a/tests/hlsl/for.shader_test +++ b/tests/hlsl/for.shader_test @@ -22,7 +22,7 @@ float4 main(float tex : texcoord) : sv_target }
[test] -todo(sm>=6) draw quad +draw quad probe ( 0, 0, 159, 480) rgba (10.0, 35.0, 0.0, 0.0) probe (161, 0, 479, 480) rgba (10.0, 38.0, 0.0, 0.0) probe (481, 0, 640, 480) rgba ( 5.0, 10.0, 0.0, 0.0) diff --git a/tests/hlsl/return.shader_test b/tests/hlsl/return.shader_test index 29621b006..fbea07926 100644 --- a/tests/hlsl/return.shader_test +++ b/tests/hlsl/return.shader_test @@ -38,10 +38,10 @@ float4 main() : sv_target
[test] uniform 0 float 0.2 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4) uniform 0 float 0.8 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5, 0.6, 0.7, 0.8)
[pixel shader] @@ -65,10 +65,10 @@ void main(out float4 ret : sv_target)
[test] uniform 0 float 0.2 -todo(sm>=6) draw quad +draw quad probe all rgba (0.3, 0.4, 0.5, 0.6) uniform 0 float 0.8 -todo(sm>=6) draw quad +draw quad probe all rgba (0.1, 0.2, 0.3, 0.4)
[pixel shader] @@ -211,10 +211,10 @@ void main(out float4 ret : sv_target)
[test] uniform 0 float 0.2 -todo(sm>=6) draw quad +draw quad probe all rgba (0.2, 0.2, 0.2, 0.2) uniform 0 float 0.8 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5, 0.5, 0.5, 0.5)
[pixel shader] diff --git a/tests/hlsl/step.shader_test b/tests/hlsl/step.shader_test index b857f00b2..e201e15f9 100644 --- a/tests/hlsl/step.shader_test +++ b/tests/hlsl/step.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target [test] uniform 0 float4 5.0 -2.6 3.0 2.0 uniform 4 float4 1.0 -4.3 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 1.0, 1.0)
diff --git a/tests/hlsl/switch.shader_test b/tests/hlsl/switch.shader_test index 243b0b117..b7edadccf 100644 --- a/tests/hlsl/switch.shader_test +++ b/tests/hlsl/switch.shader_test @@ -19,13 +19,13 @@ float4 main() : sv_target
[test] uniform 0 uint4 3 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (5.0, 5.0, 5.0, 5.0) uniform 0 uint4 1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (4.0, 4.0, 4.0, 4.0) uniform 0 uint4 0 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (3.0, 3.0, 3.0, 3.0)
% falling through is only supported for empty case statements @@ -49,13 +49,13 @@ float4 main() : sv_target
[test] uniform 0 uint4 2 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 2.0, 3.0, 4.0) uniform 0 uint4 1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.1, 2.0, 3.0, 4.0) uniform 0 uint4 0 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.1, 2.0, 3.0, 4.0)
% case value evaluation diff --git a/tests/hlsl/ternary.shader_test b/tests/hlsl/ternary.shader_test index 587b3d556..757c3b653 100644 --- a/tests/hlsl/ternary.shader_test +++ b/tests/hlsl/ternary.shader_test @@ -29,7 +29,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.1 3.0 4.0 5.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.1, 2.0, 0.0, 0.0)
[pixel shader] @@ -44,8 +44,9 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad -probe all rgba (0.5, 0.6, 0.7, 0.0) +draw quad +if(sm<6) probe all rgba (0.5, 0.6, 0.7, 0.0) +if(sm>=6) probe all rgba (0.5, 0.2, 0.7, 0.0)
[pixel shader fail(sm>=6)] float4 x, y, z;
From: Conor McCarthy cmccarthy@codeweavers.com
Shaders parsed from DXIL contain a bool condition register, so calling spirv_compiler_emit_int_to_bool() results in an invalid bool/uint comparison. --- libs/vkd3d-shader/spirv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2f88ecb31..a19b2bf37 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6893,8 +6893,9 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, component_count = vkd3d_write_mask_component_count(dst->write_mask); type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
- condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); + if (src[0].reg.data_type != VKD3D_DATA_BOOL) + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, component_count, condition_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id);
spirv_compiler_emit_store_dst(compiler, dst, val_id);