Module: vkd3d Branch: master Commit: 3c4631a4d4dd4e1a94200caf66b4bad20f83177e URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/3c4631a4d4dd4e1a94200caf66b4ba...
Author: Conor McCarthy cmccarthy@codeweavers.com Date: Thu Nov 9 13:43:34 2023 +1000
vkd3d-shader/dxil: Implement the DXIL VSELECT instruction.
---
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 | 19 ++++++++-- 8 files changed, 98 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 04dfdf57..ca7e0e72 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) @@ -3648,6 +3673,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; @@ -3808,6 +3868,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 4175813b..0a927a8f 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 6f3ec376..ee4b5eb7 100644 --- a/tests/hlsl/float-comparison.shader_test +++ b/tests/hlsl/float-comparison.shader_test @@ -63,5 +63,5 @@ shader model >= 6.0
[test] uniform 0 float4 0.0 1.5 1.5 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1010101.0, 11110000.0, 1101001.0, 0.0) diff --git a/tests/hlsl/for.shader_test b/tests/hlsl/for.shader_test index e5faa28f..1392118b 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 29621b00..fbea0792 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 b857f00b..e201e15f 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 243b0b11..b7edadcc 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 587b3d55..7b4c71f7 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] @@ -42,11 +42,26 @@ float4 main() : sv_target return float4(f1, f2, f3, 0.0); }
+[require] +shader model < 6.0 + [test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5, 0.6, 0.7, 0.0)
+[require] +shader model >= 6.0 + +[test] +uniform 0 float4 1.0 0.0 0.0 0.0 +draw quad +probe all rgba (0.5, 0.2, 0.7, 0.0) + +[require] +% reset requirements + + [pixel shader fail(sm>=6)] float4 x, y, z;