From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 180 +++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 + tests/hlsl/all.shader_test | 14 +- tests/hlsl/any.shader_test | 36 ++--- tests/hlsl/bool-cast.shader_test | 4 +- tests/hlsl/cast-to-float.shader_test | 2 +- tests/hlsl/cast-to-half.shader_test | 2 +- tests/hlsl/cast-to-int.shader_test | 2 +- tests/hlsl/cast-to-uint.shader_test | 2 +- tests/hlsl/sign.shader_test | 20 +-- 10 files changed, 223 insertions(+), 41 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 17521d3ef..00a05f050 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -306,6 +306,36 @@ enum dxil_cast_code CAST_ADDRSPACECAST = 12, };
+enum dxil_predicate +{ + FCMP_FALSE = 0, + FCMP_OEQ = 1, + FCMP_OGT = 2, + FCMP_OGE = 3, + FCMP_OLT = 4, + FCMP_OLE = 5, + FCMP_ONE = 6, + FCMP_ORD = 7, + FCMP_UNO = 8, + FCMP_UEQ = 9, + FCMP_UGT = 10, + FCMP_UGE = 11, + FCMP_ULT = 12, + FCMP_ULE = 13, + FCMP_UNE = 14, + FCMP_TRUE = 15, + ICMP_EQ = 32, + ICMP_NE = 33, + ICMP_UGT = 34, + ICMP_UGE = 35, + ICMP_ULT = 36, + ICMP_ULE = 37, + ICMP_SGT = 38, + ICMP_SGE = 39, + ICMP_SLT = 40, + ICMP_SLE = 41, +}; + struct sm6_pointer_info { const struct sm6_type *type; @@ -514,6 +544,7 @@ struct sm6_parser
struct sm6_type *types; size_t type_count; + struct sm6_type *bool_type; struct sm6_type *metadata_type; struct sm6_type *handle_type;
@@ -1388,6 +1419,8 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) switch ((width = record->operands[0])) { case 1: + sm6->bool_type = type; + break; case 8: case 16: case 32: @@ -3418,6 +3451,150 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor src_param->reg.data_type = dst->u.reg.data_type; }
+struct sm6_cmp_info +{ + enum vkd3d_shader_opcode handler_idx; + bool src_swap; + unsigned int flags; +}; + +static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) +{ + static const struct sm6_cmp_info cmp_op_table[] = + { + [FCMP_FALSE] = {VKD3DSIH_INVALID}, + [FCMP_OEQ] = {VKD3DSIH_EQ}, + [FCMP_OGT] = {VKD3DSIH_LT, true}, + [FCMP_OGE] = {VKD3DSIH_GE}, + [FCMP_OLT] = {VKD3DSIH_LT}, + [FCMP_OLE] = {VKD3DSIH_GE, true}, + [FCMP_ONE] = {VKD3DSIH_NE, false, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_ORD] = {VKD3DSIH_INVALID}, + [FCMP_UNO] = {VKD3DSIH_INVALID}, + [FCMP_UEQ] = {VKD3DSIH_EQ, false, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_UGT] = {VKD3DSIH_LT, true, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_UGE] = {VKD3DSIH_GE, false, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_ULT] = {VKD3DSIH_LT, false, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_ULE] = {VKD3DSIH_GE, true, VKD3DSI_FCMP_INVERT_ORDEREDNESS}, + [FCMP_UNE] = {VKD3DSIH_NE}, + [FCMP_TRUE] = {VKD3DSIH_INVALID}, + + [ICMP_EQ] = {VKD3DSIH_IEQ}, + [ICMP_NE] = {VKD3DSIH_INE}, + [ICMP_UGT] = {VKD3DSIH_ULT, true}, + [ICMP_UGE] = {VKD3DSIH_UGE}, + [ICMP_ULT] = {VKD3DSIH_ULT}, + [ICMP_ULE] = {VKD3DSIH_UGE, true}, + [ICMP_SGT] = {VKD3DSIH_ILT, true}, + [ICMP_SGE] = {VKD3DSIH_IGE}, + [ICMP_SLT] = {VKD3DSIH_ILT}, + [ICMP_SLE] = {VKD3DSIH_IGE, true}, + }; + + return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; +} + +static void sm6_parser_emit_cmp2(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_type *type_a, *type_b; + const struct sm6_cmp_info *cmp; + const struct sm6_value *a, *b; + unsigned int i = 0; + bool is_int, is_fp; + uint64_t code; + + if (!(dst->type = sm6->bool_type)) + { + WARN("Bool type not found.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, + "Module does not define a boolean type for comparison results."); + return; + } + + a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i); + b = sm6_parser_get_value_by_ref(sm6, record, a->type, &i); + if (!a || !b) + return; + + if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6)) + return; + + type_a = a->type; + type_b = b->type; + is_int = sm6_type_is_bool_i16_i32_i64(type_a); + is_fp = sm6_type_is_floating_point(type_a); + + code = record->operands[i++]; + + if ((!is_int && !is_fp) || is_int != (code >= ICMP_EQ)) + { + FIXME("Invalid operation %"PRIu64" on type class %u.\n", code, type_a->class); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Comparison operation %"PRIu64" on type class %u is invalid.", code, type_a->class); + return; + } + + if (type_a != type_b) + { + WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type_a->class, + type_a->u.width, type_b->class, type_b->u.width); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "Type mismatch in comparison operation arguments."); + } + + if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID) + { + FIXME("Unhandled operation %"PRIu64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Comparison operation %"PRIu64" is unhandled.", code); + return; + } + + vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx); + ins->flags = cmp->flags; + + if (record->operand_count > i) + { + uint64_t flags = record->operands[i]; + bool silence_warning = false; + + if (is_fp) + { + if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) + ins->flags |= VKD3DSI_PRECISE_X; + flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; + /* SPIR-V FPFastMathMode is only available in the Kernel executon model. */ + silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); + } + if (flags && silence_warning) + { + TRACE("Ignoring fast FP modifier %#"PRIx64".\n", flags); + } + else if (flags) + { + WARN("Ignoring flags %#"PRIx64".\n", flags); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring flags %#"PRIx64" for a comparison operation.", flags); + } + } + + src_params = instruction_src_params_alloc(ins, 2, sm6); + if (cmp->src_swap) + { + src_param_init_from_value(&src_params[0], b); + src_param_init_from_value(&src_params[1], a); + } + else + { + src_param_init_from_value(&src_params[0], a); + src_param_init_from_value(&src_params[1], b); + } + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { @@ -3637,6 +3814,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const case FUNC_CODE_INST_CAST: sm6_parser_emit_cast(sm6, record, ins, dst); break; + case FUNC_CODE_INST_CMP2: + sm6_parser_emit_cmp2(sm6, record, ins, dst); + break; case FUNC_CODE_INST_EXTRACTVAL: sm6_parser_emit_extractval(sm6, record, ins, dst); break; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 18cfb2fcd..b54b4f19e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1419,6 +1419,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty return VKD3D_SHADER_COMPONENT_INT; case VKD3D_DATA_DOUBLE: return VKD3D_SHADER_COMPONENT_DOUBLE; + case VKD3D_DATA_BOOL: + return VKD3D_SHADER_COMPONENT_BOOL; default: FIXME("Unhandled data type %#x.\n", data_type); /* fall-through */ diff --git a/tests/hlsl/all.shader_test b/tests/hlsl/all.shader_test index 564cc5b00..7bdb0dc82 100644 --- a/tests/hlsl/all.shader_test +++ b/tests/hlsl/all.shader_test @@ -11,17 +11,17 @@ float4 main() : sv_target
[test] uniform 0 float4 -1.1 1.6 1.3 0.5 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[test] uniform 0 float4 0.0 1.6 1.3 0.5 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[test] uniform 0 float4 1.0 0.0 1.3 0.5 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] @@ -34,12 +34,12 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[test] uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] @@ -53,11 +53,11 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 0.0 0.0 uniform 4 float4 3.0 4.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[test] uniform 0 float4 1.0 2.0 0.0 0.0 uniform 4 float4 0.0 4.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0) diff --git a/tests/hlsl/any.shader_test b/tests/hlsl/any.shader_test index 9b8b922c9..f2298d3a3 100644 --- a/tests/hlsl/any.shader_test +++ b/tests/hlsl/any.shader_test @@ -8,25 +8,25 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 1.0 1.0 1.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 0.0 1.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 0.0 0.0 1.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 0.0 0.0 0.0 1.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0) uniform 0 float4 -1.0 -1.0 -1.0 -1.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[pixel shader] @@ -39,13 +39,13 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0) uniform 0 float4 -1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[require] @@ -61,22 +61,22 @@ float4 main() : sv_target
[test] uniform 0 uint4 1 1 1 1 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 0 1 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 0 0 1 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 0 0 0 1 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 0 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] @@ -89,8 +89,8 @@ float4 main() : sv_target
[test] uniform 0 uint4 1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 uint4 0 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0) diff --git a/tests/hlsl/bool-cast.shader_test b/tests/hlsl/bool-cast.shader_test index dc75ea376..09ca12e2b 100644 --- a/tests/hlsl/bool-cast.shader_test +++ b/tests/hlsl/bool-cast.shader_test @@ -30,7 +30,7 @@ float4 main() : SV_TARGET [test] uniform 0 float4 0.0 0.0 2.0 4.0 uniform 4 int4 0 1 0 10 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 10.0, 1.0, 11.0)
@@ -44,5 +44,5 @@ float4 main() : sv_target
[test] uniform 0 uint4 0x00000001 0x00000002 0x80000000 0x00000000 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, 2.0, 2.0, 0.0) diff --git a/tests/hlsl/cast-to-float.shader_test b/tests/hlsl/cast-to-float.shader_test index 7c32acfa3..caaf98c02 100644 --- a/tests/hlsl/cast-to-float.shader_test +++ b/tests/hlsl/cast-to-float.shader_test @@ -17,7 +17,7 @@ uniform 0 int -1 uniform 1 uint 3 uniform 2 int -2 uniform 3 float 0.5 -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/cast-to-half.shader_test b/tests/hlsl/cast-to-half.shader_test index 1579c63f3..b8feb6760 100644 --- a/tests/hlsl/cast-to-half.shader_test +++ b/tests/hlsl/cast-to-half.shader_test @@ -17,7 +17,7 @@ uniform 0 int -1 uniform 1 uint 3 uniform 2 int -2 uniform 3 float 0.5 -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/cast-to-int.shader_test b/tests/hlsl/cast-to-int.shader_test index ae566a039..3e850fb5b 100644 --- a/tests/hlsl/cast-to-int.shader_test +++ b/tests/hlsl/cast-to-int.shader_test @@ -23,7 +23,7 @@ uniform 0 float 2.6 uniform 1 int -2 uniform 2 int -2 uniform 3 float -3.6 -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/cast-to-uint.shader_test b/tests/hlsl/cast-to-uint.shader_test index dece99b75..07479984a 100644 --- a/tests/hlsl/cast-to-uint.shader_test +++ b/tests/hlsl/cast-to-uint.shader_test @@ -23,7 +23,7 @@ uniform 0 float 2.6 uniform 1 int 2 uniform 2 int -2 uniform 3 float -3.6 -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/sign.shader_test b/tests/hlsl/sign.shader_test index 54b953681..5d8b43168 100644 --- a/tests/hlsl/sign.shader_test +++ b/tests/hlsl/sign.shader_test @@ -8,13 +8,13 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0) uniform 0 float4 -1.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (-1.0, -1.0, -1.0, -1.0) uniform 0 float4 0.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.0, 0.0, 0.0, 0.0)
[pixel shader] @@ -27,7 +27,7 @@ float4 main() : sv_target
[test] uniform 0 float4 1.0 2.0 3.0 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[pixel shader] @@ -41,7 +41,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 0.0 0.0 uniform 4 float4 3.0 4.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (1.0, 1.0, 1.0, 1.0)
[require] @@ -58,13 +58,13 @@ float4 main() : sv_target
[test] uniform 0 int4 1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1, 1, 1, 1) uniform 0 int4 -1 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (-1, -1, -1, -1) uniform 0 int4 0 0 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (0, 0, 0, 0)
[pixel shader] @@ -77,7 +77,7 @@ float4 main() : sv_target
[test] uniform 0 int4 1 2 3 4 -todo(sm>=6) draw quad +draw quad probe all rgba (1, 1, 1, 1)
[pixel shader] @@ -91,5 +91,5 @@ float4 main() : sv_target [test] uniform 0 int4 1 2 0 0 uniform 4 int4 3 4 0 0 -todo(sm>=6) draw quad +draw quad probe all rgba (1, 1, 1, 1)