vkd3d-shader/dxil: Implement the DXIL CMP2 instruction.

This commit is contained in:
Conor McCarthy 2023-11-07 14:01:39 +10:00 committed by Alexandre Julliard
parent 1dd141535c
commit d3b90cc877
Notes: Alexandre Julliard 2023-11-10 21:38:32 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/441
10 changed files with 213 additions and 41 deletions

View File

@ -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:
@ -3416,6 +3449,140 @@ 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;
};
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},
[FCMP_ORD] = {VKD3DSIH_INVALID},
[FCMP_UNO] = {VKD3DSIH_INVALID},
[FCMP_UEQ] = {VKD3DSIH_EQ},
[FCMP_UGT] = {VKD3DSIH_LT, true},
[FCMP_UGE] = {VKD3DSIH_GE},
[FCMP_ULT] = {VKD3DSIH_LT},
[FCMP_ULE] = {VKD3DSIH_GE, true},
[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);
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);
src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a);
src_param_init_from_value(&src_params[1 ^ cmp->src_swap], 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)
{
@ -3635,6 +3802,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;

View File

@ -1411,6 +1411,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 */

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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)