Goes atop MR 409. The last six commits belong to this MR.
-- v6: vkd3d-shader/dxil: Implement the DXIL CAST instruction. vkd3d-shader/spirv: Handle unsigned result in spirv_compiler_emit_ftoi(). vkd3d-shader/spirv: Introduce integer width cast instructions. vkd3d-shader/spirv: Support bool cast in spirv_compiler_emit_alu_instruction(). vkd3d-shader/spirv: Support bool logic ops in spirv_compiler_emit_alu_instruction(). vkd3d-shader/spirv: Support bitcast in spirv_compiler_emit_load_ssa_reg(). vkd3d-shader/dxil: Implement the DXIL BINOP instruction. vkd3d-shader/spirv: Support VKD3D_DATA_UINT in spirv_compiler_emit_neg(). vkd3d-shader/spirv: Handle the UMUL instruction. vkd3d-shader/spirv: Introduce an IDIV instruction. vkd3d-shader/spirv: Introduce an FREM instruction.
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 1 + libs/vkd3d-shader/spirv.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 4 insertions(+)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index eae7e6b70..7a810819c 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -152,6 +152,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", [VKD3DSIH_FRC ] = "frc", + [VKD3DSIH_FREM ] = "frem", [VKD3DSIH_FTOD ] = "ftod", [VKD3DSIH_FTOI ] = "ftoi", [VKD3DSIH_FTOU ] = "ftou", diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 6faac0ccd..4fc2348bc 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6602,6 +6602,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_DTOF, SpvOpFConvert}, {VKD3DSIH_DTOI, SpvOpConvertFToS}, {VKD3DSIH_DTOU, SpvOpConvertFToU}, + {VKD3DSIH_FREM, SpvOpFRem}, {VKD3DSIH_FTOD, SpvOpFConvert}, {VKD3DSIH_IADD, SpvOpIAdd}, {VKD3DSIH_INEG, SpvOpSNegate}, @@ -9413,6 +9414,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DTOF: case VKD3DSIH_DTOI: case VKD3DSIH_DTOU: + case VKD3DSIH_FREM: case VKD3DSIH_FTOD: case VKD3DSIH_IADD: case VKD3DSIH_INEG: diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 912267e0e..39107ddbb 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -336,6 +336,7 @@ enum vkd3d_shader_opcode VKD3DSIH_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_SHI, VKD3DSIH_FRC, + VKD3DSIH_FREM, VKD3DSIH_FTOD, VKD3DSIH_FTOI, VKD3DSIH_FTOU,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/d3d_asm.c | 1 + libs/vkd3d-shader/spirv.c | 20 +++++++++----------- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 7a810819c..c9e75c90a 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -171,6 +171,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", [VKD3DSIH_IADD ] = "iadd", [VKD3DSIH_IBFE ] = "ibfe", + [VKD3DSIH_IDIV ] = "idiv", [VKD3DSIH_IEQ ] = "ieq", [VKD3DSIH_IF ] = "if", [VKD3DSIH_IFC ] = "ifc", diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 4fc2348bc..d9e11c82d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1431,13 +1431,6 @@ static uint32_t vkd3d_spirv_build_op_udiv(struct vkd3d_spirv_builder *builder, SpvOpUDiv, result_type, operand0, operand1); }
-static uint32_t vkd3d_spirv_build_op_umod(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand0, uint32_t operand1) -{ - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpUMod, result_type, operand0, operand1); -} - static uint32_t vkd3d_spirv_build_op_isub(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t operand0, uint32_t operand1) { @@ -7017,7 +7010,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); }
-static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, +static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id; @@ -7025,6 +7018,10 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; unsigned int component_count = 0; + SpvOp div_op, mod_op; + + div_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv; + mod_op = instruction->handler_idx == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod;
if (dst[0].reg.type != VKD3DSPR_NULL) { @@ -7039,7 +7036,7 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
- val_id = vkd3d_spirv_build_op_udiv(builder, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
@@ -7062,7 +7059,7 @@ static void spirv_compiler_emit_udiv(struct spirv_compiler *compiler, 0xffffffff, component_count); }
- val_id = vkd3d_spirv_build_op_umod(builder, type_id, src0_id, src1_id); + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
@@ -9473,8 +9470,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_IMAD: spirv_compiler_emit_imad(compiler, instruction); break; + case VKD3DSIH_IDIV: case VKD3DSIH_UDIV: - spirv_compiler_emit_udiv(compiler, instruction); + spirv_compiler_emit_int_div(compiler, instruction); break; case VKD3DSIH_FTOI: spirv_compiler_emit_ftoi(compiler, instruction); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 39107ddbb..1afcf98c5 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -355,6 +355,7 @@ enum vkd3d_shader_opcode VKD3DSIH_HS_JOIN_PHASE, VKD3DSIH_IADD, VKD3DSIH_IBFE, + VKD3DSIH_IDIV, VKD3DSIH_IEQ, VKD3DSIH_IF, VKD3DSIH_IFC,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index d9e11c82d..e24431d32 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6974,7 +6974,7 @@ static void spirv_compiler_emit_imul(struct spirv_compiler *compiler, uint32_t type_id, val_id, src0_id, src1_id;
if (dst[0].reg.type != VKD3DSPR_NULL) - FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended */ + FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended/SpvOpUMulExtended */
if (dst[1].reg.type == VKD3DSPR_NULL) return; @@ -9465,6 +9465,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, spirv_compiler_emit_sincos(compiler, instruction); break; case VKD3DSIH_IMUL: + case VKD3DSIH_UMUL: spirv_compiler_emit_imul(compiler, instruction); break; case VKD3DSIH_IMAD:
From: Conor McCarthy cmccarthy@codeweavers.com
The DXIL parser uses unsigned types even if the source code uses signed, so unsigned values may be negated. --- libs/vkd3d-shader/spirv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index e24431d32..099da0058 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3865,7 +3865,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); - else if (reg->data_type == VKD3D_DATA_INT) + else if (reg->data_type == VKD3D_DATA_INT || reg->data_type == VKD3D_DATA_UINT) return vkd3d_spirv_build_op_snegate(builder, type_id, val_id);
FIXME("Unhandled data type %#x.\n", reg->data_type);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 228 ++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + .../hlsl/arithmetic-float-uniform.shader_test | 14 +- tests/hlsl/cbuffer.shader_test | 6 +- tests/hlsl/const.shader_test | 2 +- tests/hlsl/cross.shader_test | 4 +- tests/hlsl/dot.shader_test | 2 +- tests/hlsl/expr-indexing.shader_test | 2 +- tests/hlsl/lerp.shader_test | 2 +- tests/hlsl/loop.shader_test | 10 +- tests/hlsl/math.shader_test | 2 +- tests/hlsl/object-references.shader_test | 2 +- tests/hlsl/reflect.shader_test | 2 +- tests/hlsl/writemask-assignop-0.shader_test | 2 +- tests/hlsl/writemask-assignop-1.shader_test | 2 +- 15 files changed, 256 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 94f5b8622..24b320459 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -242,6 +242,45 @@ enum dxil_shader_properties_tag SHADER_PROPERTIES_ENTRY_ROOT_SIG = 12, };
+enum dxil_binop_code +{ + BINOP_ADD = 0, + BINOP_SUB = 1, + BINOP_MUL = 2, + BINOP_UDIV = 3, + BINOP_SDIV = 4, + BINOP_UREM = 5, + BINOP_SREM = 6, + BINOP_SHL = 7, + BINOP_LSHR = 8, + BINOP_ASHR = 9, + BINOP_AND = 10, + BINOP_OR = 11, + BINOP_XOR = 12 +}; + +enum dxil_fast_fp_flags +{ + FP_ALLOW_UNSAFE_ALGEBRA = 0x1, + FP_NO_NAN = 0x2, + FP_NO_INF = 0x4, + FP_NO_SIGNED_ZEROS = 0x8, + FP_ALLOW_RECIPROCAL = 0x10, +}; + +enum dxil_overflowing_binop_flags +{ + /* Operation is known to never overflow. */ + OB_NO_UNSIGNED_WRAP = 0x1, + OB_NO_SIGNED_WRAP = 0x2, +}; + +enum dxil_possibly_exact_binop_flags +{ + /* "A udiv or sdiv instruction, which can be marked as "exact", indicating that no bits are destroyed." */ + PEB_EXACT = 0x1, +}; + enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, @@ -1463,6 +1502,11 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER; }
+static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16); +} + static bool sm6_type_is_bool(const struct sm6_type *type) { return type->class == TYPE_CLASS_INTEGER && type->u.width == 1; @@ -2634,6 +2678,187 @@ static struct sm6_block *sm6_block_create() return block; }
+static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, + const struct sm6_type *type_b, struct sm6_parser *sm6) +{ + bool is_int = sm6_type_is_bool_i16_i32_i64(type_a); + bool is_bool = sm6_type_is_bool(type_a); + enum vkd3d_shader_opcode op; + bool is_valid; + + if (!is_int && !sm6_type_is_floating_point(type_a)) + { + WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "An argument to a binary operation is not bool, int16/32/64 or floating point."); + return VKD3DSIH_INVALID; + } + 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 binary operation arguments."); + } + + switch (code) + { + case BINOP_ADD: + case BINOP_SUB: + /* NEG is applied later for subtraction. */ + op = is_int ? VKD3DSIH_IADD : VKD3DSIH_ADD; + is_valid = !is_bool; + break; + case BINOP_AND: + op = VKD3DSIH_AND; + is_valid = is_int; + break; + case BINOP_ASHR: + op = VKD3DSIH_ISHR; + is_valid = is_int && !is_bool; + break; + case BINOP_LSHR: + op = VKD3DSIH_USHR; + is_valid = is_int && !is_bool; + break; + case BINOP_MUL: + op = is_int ? VKD3DSIH_UMUL : VKD3DSIH_MUL; + is_valid = !is_bool; + break; + case BINOP_OR: + op = VKD3DSIH_OR; + is_valid = is_int; + break; + case BINOP_SDIV: + op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_DIV; + is_valid = !is_bool; + break; + case BINOP_SREM: + op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_FREM; + is_valid = !is_bool; + break; + case BINOP_SHL: + op = VKD3DSIH_ISHL; + is_valid = is_int && !is_bool; + break; + case BINOP_UDIV: + case BINOP_UREM: + op = VKD3DSIH_UDIV; + is_valid = is_int && !is_bool; + break; + case BINOP_XOR: + op = VKD3DSIH_XOR; + is_valid = is_int; + break; + default: + FIXME("Unhandled binary op %#"PRIx64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Binary operation %#"PRIx64" is unhandled.", code); + return VKD3DSIH_INVALID; + } + + if (!is_valid) + { + WARN("Invalid operation %u for type %u, width %u.\n", op, type_a->class, type_a->u.width); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION, + "Binary operation %u is invalid on type class %u, width %u.", op, type_a->class, type_a->u.width); + } + + return op; +} + +static void sm6_parser_emit_binop(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; + enum vkd3d_shader_opcode handler_idx; + const struct sm6_value *a, *b; + unsigned int i = 0; + uint64_t code; + + 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; + + code = record->operands[i++]; + if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VKD3DSIH_INVALID) + return; + + vsir_instruction_init(ins, &sm6->p.location, handler_idx); + + if (record->operand_count > i && record->operands[i]) + { + uint64_t flags = record->operands[i]; + bool silence_warning = false; + + switch (handler_idx) + { + case VKD3DSIH_ADD: + case VKD3DSIH_MUL: + case VKD3DSIH_DIV: + case VKD3DSIH_FREM: + 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)); + break; + case VKD3DSIH_IADD: + case VKD3DSIH_UMUL: + case VKD3DSIH_ISHL: + silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); + break; + case VKD3DSIH_ISHR: + case VKD3DSIH_USHR: + case VKD3DSIH_IDIV: + case VKD3DSIH_UDIV: + silence_warning = !(flags & ~PEB_EXACT); + break; + default: + break; + } + /* The above flags are very common and cause warning spam. */ + if (flags && silence_warning) + { + TRACE("Ignoring flags %#"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 binary operation.", flags); + } + } + + src_params = instruction_src_params_alloc(ins, 2, sm6); + src_param_init_from_value(&src_params[0], a); + src_param_init_from_value(&src_params[1], b); + if (code == BINOP_SUB) + src_params[1].modifiers = VKD3DSPSM_NEG; + + dst->type = a->type; + + if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV) + { + struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6); + unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV; + + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); + register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6); + vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->u.reg = dst_params[index].reg; + } + else + { + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +} + static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) { @@ -3233,6 +3458,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const record = block->records[i]; switch (record->code) { + case FUNC_CODE_INST_BINOP: + sm6_parser_emit_binop(sm6, record, ins, dst); + break; case FUNC_CODE_INST_CALL: sm6_parser_emit_call(sm6, record, code_block, ins, dst); break; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1afcf98c5..7f350d7ac 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -192,6 +192,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH = 8305, VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306, VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307, + VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, diff --git a/tests/hlsl/arithmetic-float-uniform.shader_test b/tests/hlsl/arithmetic-float-uniform.shader_test index 8aaca621a..4812d053a 100644 --- a/tests/hlsl/arithmetic-float-uniform.shader_test +++ b/tests/hlsl/arithmetic-float-uniform.shader_test @@ -10,7 +10,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 15.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (20.0, -10.0, 75.0, 0.33333333) 1
[pixel shader] @@ -25,7 +25,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 15.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (5.0, 5.0, -5.0, 3.0) 1
[pixel shader] @@ -40,7 +40,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 42.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -2.0, 2.0, -2.0) 16
[pixel shader] @@ -55,7 +55,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 45.0 5.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] @@ -69,8 +69,8 @@ float4 main() : sv_target [test] uniform 0 float4 5.0 -42.1 4.0 45.0 uniform 4 float4 15.0 -5.0 4.1 5.0 -todo(sm>=6) draw quad -probe all rgba (5.0, -2.1, 4.0, 0.0) 4 +draw quad +probe all rgba (5.0, -2.1, 4.0, 0.0) 6
[require] % Infinities are not allowed in SM1 @@ -88,5 +88,5 @@ 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 (1e99, 1e99, 1e99, 1e99) diff --git a/tests/hlsl/cbuffer.shader_test b/tests/hlsl/cbuffer.shader_test index dbb49ea7e..b4dc01edd 100644 --- a/tests/hlsl/cbuffer.shader_test +++ b/tests/hlsl/cbuffer.shader_test @@ -176,7 +176,7 @@ float4 main() : sv_target uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 -todo(sm>=6) draw quad +draw quad probe all rgba (509, 610, 711, 812)
@@ -204,7 +204,7 @@ uniform 0 float4 0.0 1.0 2.0 3.0 uniform 4 float4 4.0 5.0 6.0 7.0 uniform 8 float4 8.0 9.0 10.0 11.0 uniform 12 float4 12.0 13.0 14.0 15.0 -todo(sm>=6) draw quad +draw quad probe all rgba (12468.0, 13509.0, 14010.0, 15011.0)
@@ -326,7 +326,7 @@ float4 main() : sv_target uniform 0 float 1.0 uniform 1 float 2.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (512.0, 612.0, 712.0, 812.0)
diff --git a/tests/hlsl/const.shader_test b/tests/hlsl/const.shader_test index 17427c385..9541203dc 100644 --- a/tests/hlsl/const.shader_test +++ b/tests/hlsl/const.shader_test @@ -10,7 +10,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 0.1 0.2 0.3 0.4 -todo(sm>=6) draw quad +draw quad probe all rgba (1.1, 2.2, 3.3, 4.4)
[pixel shader fail(sm<6)] diff --git a/tests/hlsl/cross.shader_test b/tests/hlsl/cross.shader_test index b84e2eaca..22f373a6d 100644 --- a/tests/hlsl/cross.shader_test +++ b/tests/hlsl/cross.shader_test @@ -12,7 +12,7 @@ float4 main() : sv_target [test] uniform 0 float4 1 -2 3 4 uniform 4 float4 10 100 1000 10000 -todo(sm>=6) draw quad +draw quad probe all rgba (-2300, -970, 120, 0)
@@ -29,5 +29,5 @@ float4 main() : sv_target
[test] uniform 0 float4 1 -2 3 4 -todo(sm>=6) draw quad +draw quad probe all rgba (-20, 8, 12, 3.5) diff --git a/tests/hlsl/dot.shader_test b/tests/hlsl/dot.shader_test index bb71919ce..c620e5fac 100644 --- a/tests/hlsl/dot.shader_test +++ b/tests/hlsl/dot.shader_test @@ -71,7 +71,7 @@ float4 main() : SV_TARGET % Account for both the SM1 and SM4 uniform layout uniform 0 float4 2.0 3.0 0.0 0.0 uniform 4 float4 3.0 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (6.0, 6.0, 6.0, 6.0)
[pixel shader] diff --git a/tests/hlsl/expr-indexing.shader_test b/tests/hlsl/expr-indexing.shader_test index 1c598816e..c11fa6540 100644 --- a/tests/hlsl/expr-indexing.shader_test +++ b/tests/hlsl/expr-indexing.shader_test @@ -9,7 +9,7 @@ float4 main() : sv_target [test] uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 -todo(sm>=6) draw quad +draw quad probe all rgba (8.0, 8.0, 8.0, 8.0)
diff --git a/tests/hlsl/lerp.shader_test b/tests/hlsl/lerp.shader_test index 27c45fe7d..413bfe833 100644 --- a/tests/hlsl/lerp.shader_test +++ b/tests/hlsl/lerp.shader_test @@ -12,7 +12,7 @@ float4 main() : SV_TARGET uniform 0 float4 2.0 3.0 4.0 5.0 uniform 4 float4 0.0 -10.0 10.0 100.0 uniform 8 float4 0.0 1.0 -1.0 0.75 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -10.0, -2.0, 76.25)
[require] diff --git a/tests/hlsl/loop.shader_test b/tests/hlsl/loop.shader_test index c15e48798..35a303595 100644 --- a/tests/hlsl/loop.shader_test +++ b/tests/hlsl/loop.shader_test @@ -1,3 +1,5 @@ +% TODO: dxcompiler emits no loops for any of these test shaders. + [pixel shader] float a;
@@ -16,7 +18,7 @@ float4 main() : sv_target
[test] uniform 0 float 5.0 -todo(sm>=6) draw quad +draw quad probe all rgba (50.0, 50.0, 50.0, 50.0)
@@ -39,7 +41,7 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (20.0, 20.0, 20.0, 20.0)
[pixel shader] @@ -68,7 +70,7 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (409.1, 409.1, 409.1, 409.1)
[pixel shader] @@ -98,7 +100,7 @@ float4 main() : sv_target
[test] uniform 0 float 4.0 -todo(sm>=6) draw quad +draw quad probe all rgba (410.1, 410.1, 410.1, 410.1)
% loop attribute by itself diff --git a/tests/hlsl/math.shader_test b/tests/hlsl/math.shader_test index 8f0592275..15f579331 100644 --- a/tests/hlsl/math.shader_test +++ b/tests/hlsl/math.shader_test @@ -14,5 +14,5 @@ float4 main() : SV_TARGET [test] uniform 0 float4 2.5 0.3 0.2 0.7 uniform 4 float4 0.1 1.5 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (-12.43, 9.833333, 1.6, 35.0) 1 diff --git a/tests/hlsl/object-references.shader_test b/tests/hlsl/object-references.shader_test index ff405559c..c857f3885 100644 --- a/tests/hlsl/object-references.shader_test +++ b/tests/hlsl/object-references.shader_test @@ -202,7 +202,7 @@ float4 main() : sv_target
[test] uniform 0 float 10.0 -todo(sm>=6) draw quad +draw quad probe (0, 0) rgba (11.0, 12.0, 13.0, 11.0)
diff --git a/tests/hlsl/reflect.shader_test b/tests/hlsl/reflect.shader_test index 808b4b772..25890086b 100644 --- a/tests/hlsl/reflect.shader_test +++ b/tests/hlsl/reflect.shader_test @@ -62,7 +62,7 @@ float4 main() : sv_target [test] uniform 0 float4 0.5 0.0 0.0 0.0 uniform 4 float4 0.6 0.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (0.14, 0.14, 0.14, 0.14) 4
[pixel shader] diff --git a/tests/hlsl/writemask-assignop-0.shader_test b/tests/hlsl/writemask-assignop-0.shader_test index fa8ecc2e4..374a38bb4 100644 --- a/tests/hlsl/writemask-assignop-0.shader_test +++ b/tests/hlsl/writemask-assignop-0.shader_test @@ -11,5 +11,5 @@ float4 main() : SV_target
[test] uniform 0 float4 0.0303 0.08 0.07 0.0202 -todo(sm>=6) draw quad +draw quad probe all rgba (-0.4697, -0.02, 0.57, 0.3202) 2 diff --git a/tests/hlsl/writemask-assignop-1.shader_test b/tests/hlsl/writemask-assignop-1.shader_test index 3bebcce61..61993257c 100644 --- a/tests/hlsl/writemask-assignop-1.shader_test +++ b/tests/hlsl/writemask-assignop-1.shader_test @@ -12,5 +12,5 @@ float4 main() : SV_target
[test] uniform 0 float4 0.0303 0.08 0.07 0.0202 -todo(sm>=6) draw quad +draw quad probe all rgba (0.5697, -0.08, -0.27, -0.4202)
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 1 + libs/vkd3d-shader/spirv.c | 10 ++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 3 files changed, 12 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 24b320459..95bd6cc69 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -1937,6 +1937,7 @@ static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const st id = sm6_parser_alloc_ssa_id(sm6); data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); + reg->u.ssa_data_type = data_type; reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; }
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 099da0058..69169368d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3751,6 +3751,7 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler unsigned int swizzle) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + enum vkd3d_shader_component_type reg_component_type; unsigned int component_idx; uint32_t type_id, val_id;
@@ -3759,7 +3760,16 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler assert(vkd3d_swizzle_is_scalar(swizzle));
if (reg->dimension == VSIR_DIMENSION_SCALAR) + { + reg_component_type = vkd3d_component_type_from_data_type(reg->u.ssa_data_type); + if (component_type != reg_component_type) + { + type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + return val_id; + }
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); component_idx = vkd3d_swizzle_get_component(swizzle, 0); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 7f350d7ac..d3ee57052 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -818,6 +818,7 @@ struct vkd3d_shader_register uint64_t immconst_uint64[VKD3D_DVEC2_SIZE]; double immconst_double[VKD3D_DVEC2_SIZE]; unsigned fp_body_idx; + enum vkd3d_data_type ssa_data_type; } u; };
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 48 +++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 69169368d..be8dc5ede 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1150,6 +1150,20 @@ static uint32_t vkd3d_spirv_get_op_type_pointer(struct vkd3d_spirv_builder *buil vkd3d_spirv_build_op_type_pointer); }
+static uint32_t vkd3d_spirv_build_op_constant_bool(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t value) +{ + return vkd3d_spirv_build_op_tr(builder, &builder->global_stream, + value ? SpvOpConstantTrue : SpvOpConstantFalse, result_type); +} + +static uint32_t vkd3d_spirv_get_op_constant_bool(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t value) +{ + return vkd3d_spirv_build_once2(builder, value ? SpvOpConstantTrue : SpvOpConstantFalse, result_type, value, + vkd3d_spirv_build_op_constant_bool); +} + /* Types larger than 32-bits are not supported. */ static uint32_t vkd3d_spirv_build_op_constant(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t value) @@ -1802,6 +1816,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder break; case VKD3D_DATA_DOUBLE: return vkd3d_spirv_get_op_type_float(builder, 64); + case VKD3D_DATA_BOOL: + return vkd3d_spirv_get_op_type_bool(builder); default: FIXME("Unhandled data type %#x.\n", data_type); return 0; @@ -2880,6 +2896,13 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_FLOAT: break; + case VKD3D_SHADER_COMPONENT_BOOL: + if (component_count == 1) + return vkd3d_spirv_get_op_constant_bool(builder, type_id, *values); + FIXME("Unsupported vector of bool.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE, + "Vectors of bool type are not supported."); + return vkd3d_spirv_get_op_undef(builder, type_id); default: FIXME("Unhandled component_type %#x.\n", component_type); return vkd3d_spirv_get_op_undef(builder, type_id); @@ -6632,6 +6655,21 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru return SpvOpMax; }
+static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_instruction *instruction) +{ + switch (instruction->handler_idx) + { + case VKD3DSIH_AND: + return SpvOpLogicalAnd; + case VKD3DSIH_OR: + return SpvOpLogicalOr; + case VKD3DSIH_XOR: + return SpvOpLogicalNotEqual; + default: + return SpvOpMax; + } +} + static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -6643,7 +6681,15 @@ static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, unsigned int i; SpvOp op;
- op = spirv_compiler_map_alu_instruction(instruction); + if (src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type == VKD3D_DATA_BOOL) + { + op = spirv_compiler_map_logical_instruction(instruction); + } + else + { + op = spirv_compiler_map_alu_instruction(instruction); + } + if (op == SpvOpMax) { ERR("Unexpected instruction %#x.\n", instruction->handler_idx); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index d3ee57052..6bc7dd0c7 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -93,6 +93,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003, VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004, VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005, + VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 59 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index be8dc5ede..55c5c8502 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4246,6 +4246,30 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); }
+static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, + unsigned int component_count, uint32_t val_id, bool signedness) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, true_id, false_id; + + true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); + false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +} + +static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, + unsigned int component_count, uint32_t val_id, bool signedness) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, true_id, false_id; + + true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); + false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +} + typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, uint32_t val_id);
@@ -6670,6 +6694,34 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in } }
+static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t val_id; + + assert(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL); + + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + if (dst->reg.data_type == VKD3D_DATA_FLOAT) + { + val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOF); + } + else if (dst->reg.data_type == VKD3D_DATA_DOUBLE) + { + val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOD); + } + else + { + WARN("Unhandled data type %u.\n", dst->reg.data_type); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE, + "Register data type %u is unhandled.", dst->reg.data_type); + } + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -6681,9 +6733,12 @@ static void spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, unsigned int i; SpvOp op;
- if (src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type == VKD3D_DATA_BOOL) + if (src->reg.data_type == VKD3D_DATA_BOOL) { - op = spirv_compiler_map_logical_instruction(instruction); + if (dst->reg.data_type == VKD3D_DATA_BOOL) + op = spirv_compiler_map_logical_instruction(instruction); + else + return spirv_compiler_emit_bool_cast(compiler, instruction); } else {
From: Conor McCarthy cmccarthy@codeweavers.com
ITOI and UTOU may cast from a bool to a 32-bit integer. Cast to a 64-bit integer from a smaller type will be added later. --- libs/vkd3d-shader/d3d_asm.c | 2 ++ libs/vkd3d-shader/spirv.c | 14 ++++++++++---- libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index c9e75c90a..c0779d718 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -199,6 +199,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_ISHR ] = "ishr", [VKD3DSIH_ITOD ] = "itod", [VKD3DSIH_ITOF ] = "itof", + [VKD3DSIH_ITOI ] = "itoi", [VKD3DSIH_LABEL ] = "label", [VKD3DSIH_LD ] = "ld", [VKD3DSIH_LD2DMS ] = "ld2dms", @@ -306,6 +307,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_USHR ] = "ushr", [VKD3DSIH_UTOD ] = "utod", [VKD3DSIH_UTOF ] = "utof", + [VKD3DSIH_UTOU ] = "utou", [VKD3DSIH_XOR ] = "xor", };
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 55c5c8502..35a341787 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4235,12 +4235,12 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, }
static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, - unsigned int component_count, uint32_t val_id) + unsigned int component_count, uint32_t val_id, bool signedness) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, true_id, false_id;
- true_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count); + true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); @@ -4312,7 +4312,7 @@ static uint32_t sv_instance_id_fixup(struct spirv_compiler *compiler, static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, uint32_t front_facing_id) { - return spirv_compiler_emit_bool_to_int(compiler, 1, front_facing_id); + return spirv_compiler_emit_bool_to_int(compiler, 1, front_facing_id, true); }
/* frag_coord.w = 1.0f / frag_coord.w */ @@ -6712,6 +6712,10 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, { val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOD); } + else if (dst->reg.data_type == VKD3D_DATA_UINT) + { + val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI); + } else { WARN("Unhandled data type %u.\n", dst->reg.data_type); @@ -7419,7 +7423,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id);
- result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id); + result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id, true); spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); }
@@ -9530,12 +9534,14 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_ISHR: case VKD3DSIH_ITOD: case VKD3DSIH_ITOF: + case VKD3DSIH_ITOI: case VKD3DSIH_MUL: case VKD3DSIH_NOT: case VKD3DSIH_OR: case VKD3DSIH_USHR: case VKD3DSIH_UTOD: case VKD3DSIH_UTOF: + case VKD3DSIH_UTOU: case VKD3DSIH_XOR: spirv_compiler_emit_alu_instruction(compiler, instruction); break; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 6bc7dd0c7..c10e77f53 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -385,6 +385,7 @@ enum vkd3d_shader_opcode VKD3DSIH_ISHR, VKD3DSIH_ITOD, VKD3DSIH_ITOF, + VKD3DSIH_ITOI, VKD3DSIH_LABEL, VKD3DSIH_LD, VKD3DSIH_LD2DMS, @@ -492,6 +493,7 @@ enum vkd3d_shader_opcode VKD3DSIH_USHR, VKD3DSIH_UTOD, VKD3DSIH_UTOF, + VKD3DSIH_UTOU, VKD3DSIH_XOR,
VKD3DSIH_INVALID,
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 35a341787..ee9cca1bc 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2969,12 +2969,6 @@ static uint32_t spirv_compiler_get_constant_vector(struct spirv_compiler *compil return spirv_compiler_get_constant(compiler, component_type, component_count, values); }
-static uint32_t spirv_compiler_get_constant_int_vector(struct spirv_compiler *compiler, - uint32_t value, unsigned int component_count) -{ - return spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_INT, component_count, value); -} - static uint32_t spirv_compiler_get_constant_uint_vector(struct spirv_compiler *compiler, uint32_t value, unsigned int component_count) { @@ -7190,6 +7184,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t src_type_id, dst_type_id, condition_type_id; + enum vkd3d_shader_component_type component_type; unsigned int component_count;
assert(instruction->dst_count == 1); @@ -7207,8 +7202,11 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, int_min_id = spirv_compiler_get_constant_float_vector(compiler, -2147483648.0f, component_count); val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, int_min_id);
+ /* DXIL uses unsigned int but requires a signed conversion. */ + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); + float_max_id = spirv_compiler_get_constant_float_vector(compiler, 2147483648.0f, component_count); - int_max_id = spirv_compiler_get_constant_int_vector(compiler, INT_MAX, component_count); + int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); @@ -7216,7 +7214,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpConvertFToS, dst_type_id, val_id); val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, int_max_id, val_id);
- zero_id = spirv_compiler_get_constant_int_vector(compiler, 0, component_count); + zero_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, 0); condition_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpIsNan, condition_type_id, src_id); val_id = vkd3d_spirv_build_op_select(builder, dst_type_id, condition_id, zero_id, val_id);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 172 ++++++++++++++++++ tests/hlsl/arithmetic-int-uniform.shader_test | 14 +- tests/hlsl/array-index-expr.shader_test | 16 +- tests/hlsl/asfloat.shader_test | 2 +- tests/hlsl/asuint.shader_test | 4 +- tests/hlsl/d3dcolor-to-ubyte4.shader_test | 4 +- tests/hlsl/function-cast.shader_test | 4 +- tests/hlsl/lerp.shader_test | 2 +- .../shader-interstage-interface.shader_test | 2 +- 9 files changed, 196 insertions(+), 24 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 95bd6cc69..f8d2c95a6 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -289,6 +289,23 @@ enum dx_intrinsic_opcode DX_CBUFFER_LOAD_LEGACY = 59, };
+enum dxil_cast_code +{ + CAST_TRUNC = 0, + CAST_ZEXT = 1, + CAST_SEXT = 2, + CAST_FPTOUI = 3, + CAST_FPTOSI = 4, + CAST_UITOFP = 5, + CAST_SITOFP = 6, + CAST_FPTRUNC = 7, + CAST_FPEXT = 8, + CAST_PTRTOINT = 9, + CAST_INTTOPTR = 10, + CAST_BITCAST = 11, + CAST_ADDRSPACECAST = 12, +}; + struct sm6_pointer_info { const struct sm6_type *type; @@ -3249,6 +3266,158 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst); }
+static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, + const struct sm6_type *to, struct sm6_parser *sm6) +{ + enum vkd3d_shader_opcode op = VKD3DSIH_INVALID; + bool from_int, to_int; + bool is_valid = false; + + /* NOTE: DXIL currently doesn't use vectors here. */ + if (!sm6_type_is_scalar(from) || !sm6_type_is_scalar(to)) + { + FIXME("Unhandled non-scalar type class %u and/or %u.\n", from->class, to->class); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Cast of non-scalar types is not implemented."); + /* width is not available for non-scalar types so we can't attempt to compile it. */ + return VKD3DSIH_INVALID; + } + if (to->u.width == 8 || from->u.width == 8) + { + FIXME("Unhandled 8-bit value.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Cast to/from an 8-bit type is not implemented."); + return VKD3DSIH_INVALID; + } + + from_int = sm6_type_is_integer(from); + to_int = sm6_type_is_integer(to); + + /* DXC emits minimum precision types as 16-bit. These must be emitted + * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */ + switch (code) + { + case CAST_TRUNC: + /* nop or min precision. TODO: native 16-bit */ + if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32)) + op = VKD3DSIH_NOP; + else + op = VKD3DSIH_UTOU; + is_valid = from_int && to_int && to->u.width <= from->u.width; + break; + case CAST_ZEXT: + case CAST_SEXT: + /* nop or min precision. TODO: native 16-bit */ + if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16)) + { + op = VKD3DSIH_NOP; + is_valid = from_int && to_int; + } + else if (to->u.width > from->u.width) + { + op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI; + assert(from->u.width == 1 || to->u.width == 64); + is_valid = from_int && to_int; + } + break; + case CAST_FPTOUI: + op = (from->u.width == 64) ? VKD3DSIH_DTOU : VKD3DSIH_FTOU; + is_valid = !from_int && to_int && to->u.width > 1; + break; + case CAST_FPTOSI: + op = (from->u.width == 64) ? VKD3DSIH_DTOI : VKD3DSIH_FTOI; + is_valid = !from_int && to_int && to->u.width > 1; + break; + case CAST_UITOFP: + op = (to->u.width == 64) ? VKD3DSIH_UTOD : VKD3DSIH_UTOF; + is_valid = from_int && !to_int; + break; + case CAST_SITOFP: + op = (to->u.width == 64) ? VKD3DSIH_ITOD : VKD3DSIH_ITOF; + is_valid = from_int && !to_int; + break; + case CAST_FPTRUNC: + /* TODO: native 16-bit */ + op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP; + is_valid = !from_int && !to_int; + break; + case CAST_FPEXT: + /* TODO: native 16-bit */ + op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP; + is_valid = !from_int && !to_int; + break; + case CAST_BITCAST: + op = VKD3DSIH_MOV; + is_valid = to->u.width == from->u.width; + break; + default: + FIXME("Unhandled cast op %"PRIu64".\n", code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Cast operation %"PRIu64" is unhandled.\n", code); + return VKD3DSIH_INVALID; + } + + if (!is_valid) + { + FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n", + code, from->class, from->u.width, to->class, to->u.width); + return VKD3DSIH_INVALID; + } + + return op; +} + +static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_record *record, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +{ + struct vkd3d_shader_src_param *src_param; + enum vkd3d_shader_opcode handler_idx; + const struct sm6_value *value; + const struct sm6_type *type; + unsigned int i = 0; + + if (!(value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) + return; + + if (!dxil_record_validate_operand_count(record, i + 2, i + 2, sm6)) + return; + + if (!(type = sm6_parser_get_type(sm6, record->operands[i++]))) + return; + + dst->type = type; + + if (sm6_type_is_pointer(type)) + { + *dst = *value; + dst->type = type; + ins->handler_idx = VKD3DSIH_NOP; + return; + } + + if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VKD3DSIH_INVALID) + return; + + vsir_instruction_init(ins, &sm6->p.location, handler_idx); + + if (handler_idx == VKD3DSIH_NOP) + { + dst->u.reg = value->u.reg; + return; + } + + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param_init_from_value(src_param, value); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + + /* bitcast */ + if (handler_idx == VKD3DSIH_MOV) + src_param->reg.data_type = dst->u.reg.data_type; +} + static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { @@ -3465,6 +3634,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const case FUNC_CODE_INST_CALL: sm6_parser_emit_call(sm6, record, code_block, ins, dst); break; + case FUNC_CODE_INST_CAST: + sm6_parser_emit_cast(sm6, record, ins, dst); + break; case FUNC_CODE_INST_EXTRACTVAL: sm6_parser_emit_extractval(sm6, record, ins, dst); break; diff --git a/tests/hlsl/arithmetic-int-uniform.shader_test b/tests/hlsl/arithmetic-int-uniform.shader_test index 726a191a7..7f5cdaaa6 100644 --- a/tests/hlsl/arithmetic-int-uniform.shader_test +++ b/tests/hlsl/arithmetic-int-uniform.shader_test @@ -10,7 +10,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 16.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (21.0, -11.0, 80.0, 0.0)
[pixel shader] @@ -25,7 +25,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 16.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (5.0, 5.0, -5.0, 3.0)
[pixel shader] @@ -40,7 +40,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 42.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (8.0, -8.0, -8.0, 8.0)
[pixel shader] @@ -55,7 +55,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 42.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -2.0, 2.0, -2.0)
[pixel shader] @@ -70,7 +70,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 45.0 5.0 0.0 0.0 -todo(sm>=6) draw quad +draw quad probe all rgba (9.0, -9.0, -9.0, 9.0)
[pixel shader] @@ -85,7 +85,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 45.0 5.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] @@ -117,5 +117,5 @@ float4 main() : sv_target [test] uniform 0 float4 45.0 5.0 50.0 10.0 uniform 4 float4 3.0 8.0 2.0 5.0 -todo(sm>=6) draw quad +draw quad probe all rgba (9.0, 5.0, 1.0, 3.0) diff --git a/tests/hlsl/array-index-expr.shader_test b/tests/hlsl/array-index-expr.shader_test index b7d91ea09..0b45df927 100644 --- a/tests/hlsl/array-index-expr.shader_test +++ b/tests/hlsl/array-index-expr.shader_test @@ -12,17 +12,17 @@ uniform 0 float4 1.0 2.0 3.0 4.0 uniform 4 float4 5.0 6.0 7.0 8.0 uniform 8 float4 9.0 10.0 11.0 12.0 uniform 12 float4 0 0 0 0 -todo draw quad -todo probe all rgba (1.0, 2.0, 3.0, 4.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (1.0, 2.0, 3.0, 4.0) uniform 12 float4 1 0 0 0 -todo draw quad -todo probe all rgba (5.0, 6.0, 7.0, 8.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (5.0, 6.0, 7.0, 8.0) uniform 12 float4 0 1 0 0 -todo draw quad -todo probe all rgba (5.0, 6.0, 7.0, 8.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (5.0, 6.0, 7.0, 8.0) uniform 12 float4 1 1 0 0 -todo draw quad -todo probe all rgba (9.0, 10.0, 11.0, 12.0) +todo(sm<6) draw quad +todo(sm<6) probe all rgba (9.0, 10.0, 11.0, 12.0)
[pixel shader] diff --git a/tests/hlsl/asfloat.shader_test b/tests/hlsl/asfloat.shader_test index f43f2fdff..2184c1869 100644 --- a/tests/hlsl/asfloat.shader_test +++ b/tests/hlsl/asfloat.shader_test @@ -20,7 +20,7 @@ float4 main() : sv_target
[test] uniform 0 float4 123.0 -2.0 456 0.01 -todo(sm>=6) draw quad +draw quad probe (320,240) rgba (123.0, -2.0, 456.0, 0.01)
[pixel shader] diff --git a/tests/hlsl/asuint.shader_test b/tests/hlsl/asuint.shader_test index 0a2e39e53..50b0895e9 100644 --- a/tests/hlsl/asuint.shader_test +++ b/tests/hlsl/asuint.shader_test @@ -20,7 +20,7 @@ float4 main() : sv_target
[test] uniform 0 uint4 123 0xc0000000 456 0x7fd69345 -todo(sm>=6) draw quad +draw quad probe (320,240) rgba (123.0, 3221225472.0, 456.0, 2144768896.0)
@@ -37,7 +37,7 @@ float4 main() : sv_target uniform 0 uint4 11 12 0 0 uniform 4 uint4 13 14 0 0 uniform 8 uint4 20 21 22 23 -todo(sm>=6) draw quad +draw quad probe (320,240) rgba (13.0, 21.0, 0.0, 0.0)
diff --git a/tests/hlsl/d3dcolor-to-ubyte4.shader_test b/tests/hlsl/d3dcolor-to-ubyte4.shader_test index 01b7f2f64..dca307cdb 100644 --- a/tests/hlsl/d3dcolor-to-ubyte4.shader_test +++ b/tests/hlsl/d3dcolor-to-ubyte4.shader_test @@ -11,7 +11,7 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo(sm>=6) draw quad +draw quad probe all rgba (1912.0, 1657.0, -127.0, 867.0) 1
[pixel shader] @@ -24,5 +24,5 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo(sm>=6) draw quad +draw quad probe all rgba (-127.0, -127.0, -127.0, -127.0) 1 diff --git a/tests/hlsl/function-cast.shader_test b/tests/hlsl/function-cast.shader_test index a2b9cf4f4..c92289863 100644 --- a/tests/hlsl/function-cast.shader_test +++ b/tests/hlsl/function-cast.shader_test @@ -18,7 +18,7 @@ float4 main() : sv_target
[test] uniform 0 float4 -1.9 -1.0 2.9 4.0 -todo draw quad +todo(sm<6) draw quad probe all rgba (-1.0, -1.0, 2.0, 4.0)
% As above, but cast "x" to float4 first. @@ -89,5 +89,5 @@ float4 main() : sv_target
[test] uniform 0 int4 -2 0 1 -3000000 -todo draw quad +todo(sm<6) draw quad probe all rgba (-1.0, 0.0, 1.0, -3000000.0) diff --git a/tests/hlsl/lerp.shader_test b/tests/hlsl/lerp.shader_test index 413bfe833..15e90cef9 100644 --- a/tests/hlsl/lerp.shader_test +++ b/tests/hlsl/lerp.shader_test @@ -32,7 +32,7 @@ float4 main() : SV_TARGET uniform 0 int4 2 3 4 0 uniform 4 int4 0 -10 10 1000000 uniform 8 int4 0 1 -1 1000000 -todo(sm>=6) draw quad +draw quad probe all rgba (2.0, -10.0, -2.0, 1e12)
diff --git a/tests/hlsl/shader-interstage-interface.shader_test b/tests/hlsl/shader-interstage-interface.shader_test index 271eb3bbe..584b88cf9 100644 --- a/tests/hlsl/shader-interstage-interface.shader_test +++ b/tests/hlsl/shader-interstage-interface.shader_test @@ -52,5 +52,5 @@ void main(float4 position : SV_Position, float2 t0 : TEXCOORD0, }
[test] -todo(sm>=6) draw triangle strip 4 +draw triangle strip 4 probe all rgba (10.0, 8.0, 7.0, 3.0)
On Mon Nov 6 10:54:11 2023 +0000, Giovanni Mascellani wrote:
You can download the job artifacts from the panel on the right when looking at the job (i.e., https://gitlab.winehq.org/cmccarthy/vkd3d/-/jobs/35840). That's a ZIP archive where you can find the .log files sorted by commit. In this specific case, the problem is flagged by the VSIR validator. You're probably not seeing it on your computer because it has to be explicitly enabled with `VKD3D_CONFIG=force_validation` (which is on in the CI). Even then, the failure is unfortunately not completely evident, because the shader compiler used by vkd3d to compile to SPIR-V has logging disabled. This patch should probably applied to the validator, I'll submit it with the next MR:
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 8cf92656b..f6ba888d3 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1489,6 +1489,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c va_end(args); vkd3d_shader_parser_error(ctx->parser, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); + FIXME("Validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); vkd3d_string_buffer_cleanup(&buf); }
With this patch in place the problem becomes apparent:
vkd3d:3777003:fixme:validator_error Validation error: instruction 11: Invalid register precision 0x559d. vkd3d:3777003:fixme:validator_error Validation error: instruction 14: Invalid register precision 0x7ffe. vkd3d:3777003:fixme:validator_error Validation error: instruction 16: Invalid register precision 0x559d. vkd3d:3777003:fixme:validator_error Validation error: instruction 16: Invalid register data type 0x559d. [...]
So it seems that some registers are not fully initialized in your code. Ideally you should always go through `vsir_register_init()`, maybe there is some place where this doesn't happen?
Turns out it's in the `BINOP` MR. Validation doesn't fail there because the shaders fail to compile.
On Mon Nov 6 11:43:12 2023 +0000, Giovanni Mascellani wrote:
It makes an odd kind of sense. LLVM treats bool as a 1-bit int, so a
signed bool has only a sign bit, and `true` is `-1`. I could add a new instruction, but `spirv_compiler_emit_alu_instruction()` must handle bool anyway, so I see no issue in treating bool as a 1-bit int and passing it to numeric handlers. Oh, right, it makes sense at the DXIL level. But please add a comment in the code, I don't think it's evident. Also, you should probably check that if the instruction is not `itof` then it is `utof`, because at that point in control flow you only have checked that source and destination types. And similarly for the `double` branch.
`CAST_SITOFP` supports bool and maps to `ITOF`.
Yes, but this happens in a later commit, even if it's the same MR. I don't insist to change it for this MR, but in general please try to order commits, even inside a single MR, in such a way that there is no dead code. This usually means implementing the frontend changes first and then backend changes.
Thus far I've always changed the SPIR-V backend before the DXIL frontend, but it can certainly be done the other way around: add the instruction and allow compilation to fail in the backend until patched.
On Mon Nov 6 11:43:13 2023 +0000, Giovanni Mascellani wrote:
I'd rather introduce some kind of `bitcast` VSIR operator, rather than introducing an ad-hoc solution that only works for SSA registers and add some complexity to `vkd3d_shader_register` (not a lot of complexity, yes, but that structure is used all over the place).
With a `bitcast` instruction we may be able to do without the implicit bitcast available for other register types, but I need to check.
On Mon Nov 6 14:49:19 2023 +0000, Conor McCarthy wrote:
With a `bitcast` instruction we may be able to do without the implicit bitcast available for other register types, but I need to check.
In the current `sm6_rebase` branch we can cover all cases with a `bitcast` instruction, but I think that's the wrong approach for a couple of reasons.
TPF and therefore VSIR have no `bitcast` instruction because the register mechanism enables bitcasting to be done without one. Introducing a `bitcast` instruction would add complexity to the IR and create two pathways to the same result.
While we currently don't need bitcast support for SSA registers, there's no guarantee a need for it won't arise in the future. Then the change made in this patch would become necessary anyway.