diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index e8283379..0ef64b66 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -7791,15 +7791,359 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, add_last_vsir_instr_to_block(ctx, program, block); } -static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, - struct vsir_program *program, struct hlsl_ir_expr *expr) +static bool type_is_float(const struct hlsl_type *type) { + return type->e.numeric.type == HLSL_TYPE_FLOAT || type->e.numeric.type == HLSL_TYPE_HALF; +} + +static bool type_is_integer(const struct hlsl_type *type) +{ + return type->e.numeric.type == HLSL_TYPE_BOOL + || type->e.numeric.type == HLSL_TYPE_INT + || type->e.numeric.type == HLSL_TYPE_UINT; +} + +static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, + struct vsir_program *program, struct hlsl_ir_expr *expr, const char *dst_type_name) +{ + const struct hlsl_type *dst_type = expr->node.data_type; + const struct hlsl_type *src_type = NULL; + + VKD3D_ASSERT(expr->node.reg.allocated); + if (expr->operands[0].node) + src_type = expr->operands[0].node->data_type; + switch (expr->op) { case HLSL_OP1_ABS: + VKD3D_ASSERT(type_is_float(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_ABS, 0, true); return true; + case HLSL_OP1_BIT_NOT: + VKD3D_ASSERT(type_is_integer(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); + return true; + + case HLSL_OP1_CEIL: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_PI, 0, 0, true); + return true; + + case HLSL_OP1_DSX: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); + return true; + + case HLSL_OP1_DSX_COARSE: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_COARSE, 0, 0, true); + return true; + + case HLSL_OP1_DSX_FINE: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_FINE, 0, 0, true); + return true; + + case HLSL_OP1_DSY: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); + return true; + + case HLSL_OP1_DSY_COARSE: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_COARSE, 0, 0, true); + return true; + + case HLSL_OP1_DSY_FINE: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_FINE, 0, 0, true); + return true; + + case HLSL_OP1_EXP2: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EXP, 0, 0, true); + return true; + + case HLSL_OP1_F16TOF32: + VKD3D_ASSERT(type_is_float(dst_type)); + VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F16TOF32, 0, 0, true); + return true; + + case HLSL_OP1_F32TOF16: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F32TOF16, 0, 0, true); + return true; + + case HLSL_OP1_FLOOR: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NI, 0, 0, true); + return true; + + case HLSL_OP1_FRACT: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true); + return true; + + case HLSL_OP1_LOG2: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LOG, 0, 0, true); + return true; + + case HLSL_OP1_LOGIC_NOT: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); + return true; + + case HLSL_OP1_NEG: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); + return true; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s negation expression.", dst_type_name); + return false; + } + + case HLSL_OP1_REINTERPRET: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + return true; + + case HLSL_OP1_ROUND: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NE, 0, 0, true); + return true; + + case HLSL_OP1_RSQ: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RSQ, 0, 0, true); + return true; + + case HLSL_OP1_SQRT: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SQRT, 0, 0, true); + return true; + + case HLSL_OP1_TRUNC: + VKD3D_ASSERT(type_is_float(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_Z, 0, 0, true); + return true; + + case HLSL_OP2_ADD: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s addition expression.", dst_type_name); + return false; + } + + case HLSL_OP2_BIT_AND: + VKD3D_ASSERT(type_is_integer(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); + return true; + + case HLSL_OP2_BIT_OR: + VKD3D_ASSERT(type_is_integer(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); + return true; + + case HLSL_OP2_BIT_XOR: + VKD3D_ASSERT(type_is_integer(dst_type)); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true); + return true; + + case HLSL_OP2_EQUAL: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + + switch (src_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EQO, 0, 0, true); + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 equality between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); + return false; + } + + case HLSL_OP2_GEQUAL: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + + switch (src_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_GEO, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IGE, 0, 0, true); + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 greater-than-or-equal between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); + return false; + } + + case HLSL_OP2_LESS: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + + switch (src_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LTO, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ILT, 0, 0, true); + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 less-than between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); + return false; + } + + case HLSL_OP2_LOGIC_AND: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); + return true; + + case HLSL_OP2_LOGIC_OR: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); + return true; + + case HLSL_OP2_LSHIFT: + VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ISHL, 0, 0, true); + return true; + + case HLSL_OP3_MAD: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s MAD expression.", dst_type_name); + return false; + } + + case HLSL_OP2_MAX: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true); + return true; + + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s maximum expression.", dst_type_name); + return false; + } + + case HLSL_OP2_MIN: + switch (dst_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); + return true; + + case HLSL_TYPE_INT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true); + return true; + + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 %s minimum expression.", dst_type_name); + return false; + } + + case HLSL_OP2_NEQUAL: + VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + + switch (src_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NEU, 0, 0, true); + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true); + return true; + + default: + hlsl_fixme(ctx, &expr->node.loc, "SM4 inequality between \"%s\" operands.", + debug_hlsl_type(ctx, src_type)); + return false; + } + + case HLSL_OP2_RSHIFT: + VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, + dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true); + return true; + + case HLSL_OP3_TERNARY: + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOVC, 0, 0, true); + return true; + default: return false; } @@ -7807,6 +8151,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program) { + struct vkd3d_string_buffer *dst_type_string; struct hlsl_ir_node *instr, *next; struct hlsl_ir_switch_case *c; @@ -7831,8 +8176,13 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo break; case HLSL_IR_EXPR: - if (sm4_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr))) + if (!(dst_type_string = hlsl_type_to_string(ctx, instr->data_type))) + break; + + if (sm4_generate_vsir_instr_expr(ctx, program, hlsl_ir_expr(instr), dst_type_string->buffer)) replace_instr_with_last_vsir_instr(ctx, program, instr); + + hlsl_release_string_buffer(ctx, dst_type_string); break; case HLSL_IR_IF: diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index c8fb8e3d..f8d164f5 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2995,20 +2995,6 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con static void write_sm4_block(struct tpf_compiler *tpf, const struct hlsl_block *block); -static bool type_is_integer(const struct hlsl_type *type) -{ - switch (type->e.numeric.type) - { - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - return true; - - default: - return false; - } -} - bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, bool output, enum vkd3d_shader_register_type *type, bool *has_idx) { @@ -5137,26 +5123,6 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_compiler write_sm4_instruction(tpf, &instr); } -static void write_sm4_ternary_op(const struct tpf_compiler *tpf, enum vkd3d_sm4_opcode opcode, - const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2, - const struct hlsl_ir_node *src3) -{ - struct sm4_instruction instr; - - memset(&instr, 0, sizeof(instr)); - instr.opcode = opcode; - - sm4_dst_from_node(&instr.dsts[0], dst); - instr.dst_count = 1; - - sm4_src_from_node(tpf, &instr.srcs[0], src1, instr.dsts[0].write_mask); - sm4_src_from_node(tpf, &instr.srcs[1], src2, instr.dsts[0].write_mask); - sm4_src_from_node(tpf, &instr.srcs[2], src3, instr.dsts[0].write_mask); - instr.src_count = 3; - - write_sm4_instruction(tpf, &instr); -} - static void write_sm4_ld(const struct tpf_compiler *tpf, const struct hlsl_ir_node *dst, const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, const struct hlsl_ir_node *sample_index, const struct hlsl_ir_node *texel_offset, @@ -5526,7 +5492,6 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ const struct vkd3d_shader_version *version = &tpf->program->shader_version; const struct hlsl_ir_node *arg1 = expr->operands[0].node; const struct hlsl_ir_node *arg2 = expr->operands[1].node; - const struct hlsl_ir_node *arg3 = expr->operands[2].node; const struct hlsl_type *dst_type = expr->node.data_type; struct vkd3d_string_buffer *dst_type_string; @@ -5545,109 +5510,15 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ "GetRenderTargetSampleCount() can only be used from a pixel shader using version 4.1 or higher."); break; - case HLSL_OP1_BIT_NOT: - VKD3D_ASSERT(type_is_integer(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); - break; - case HLSL_OP1_CAST: write_sm4_cast(tpf, expr); break; - case HLSL_OP1_CEIL: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_PI, &expr->node, arg1, 0); - break; - case HLSL_OP1_COS: VKD3D_ASSERT(type_is_float(dst_type)); write_sm4_unary_op_with_two_destinations(tpf, VKD3D_SM4_OP_SINCOS, &expr->node, 1, arg1); break; - case HLSL_OP1_DSX: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_DERIV_RTX, &expr->node, arg1, 0); - break; - - case HLSL_OP1_DSX_COARSE: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_DERIV_RTX_COARSE, &expr->node, arg1, 0); - break; - - case HLSL_OP1_DSX_FINE: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_DERIV_RTX_FINE, &expr->node, arg1, 0); - break; - - case HLSL_OP1_DSY: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_DERIV_RTY, &expr->node, arg1, 0); - break; - - case HLSL_OP1_DSY_COARSE: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_DERIV_RTY_COARSE, &expr->node, arg1, 0); - break; - - case HLSL_OP1_DSY_FINE: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_DERIV_RTY_FINE, &expr->node, arg1, 0); - break; - - case HLSL_OP1_EXP2: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_EXP, &expr->node, arg1, 0); - break; - - case HLSL_OP1_F16TOF32: - VKD3D_ASSERT(type_is_float(dst_type)); - VKD3D_ASSERT(hlsl_version_ge(tpf->ctx, 5, 0)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_F16TOF32, &expr->node, arg1, 0); - break; - - case HLSL_OP1_F32TOF16: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_UINT); - VKD3D_ASSERT(hlsl_version_ge(tpf->ctx, 5, 0)); - write_sm4_unary_op(tpf, VKD3D_SM5_OP_F32TOF16, &expr->node, arg1, 0); - break; - - case HLSL_OP1_FLOOR: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_NI, &expr->node, arg1, 0); - break; - - case HLSL_OP1_FRACT: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_FRC, &expr->node, arg1, 0); - break; - - case HLSL_OP1_LOG2: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_LOG, &expr->node, arg1, 0); - break; - - case HLSL_OP1_LOGIC_NOT: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); - break; - - case HLSL_OP1_NEG: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_NEG); - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_unary_op(tpf, VKD3D_SM4_OP_INEG, &expr->node, arg1, 0); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s negation expression.", dst_type_string->buffer); - } - break; - case HLSL_OP1_RCP: switch (dst_type->e.numeric.type) { @@ -5686,20 +5557,6 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ } break; - case HLSL_OP1_REINTERPRET: - write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0); - break; - - case HLSL_OP1_ROUND: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_NE, &expr->node, arg1, 0); - break; - - case HLSL_OP1_RSQ: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_RSQ, &expr->node, arg1, 0); - break; - case HLSL_OP1_SAT: VKD3D_ASSERT(type_is_float(dst_type)); write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV @@ -5712,48 +5569,6 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ write_sm4_unary_op_with_two_destinations(tpf, VKD3D_SM4_OP_SINCOS, &expr->node, 0, arg1); break; - case HLSL_OP1_SQRT: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_SQRT, &expr->node, arg1, 0); - break; - - case HLSL_OP1_TRUNC: - VKD3D_ASSERT(type_is_float(dst_type)); - write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_Z, &expr->node, arg1, 0); - break; - - case HLSL_OP2_ADD: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_ADD, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_IADD, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s addition expression.", dst_type_string->buffer); - } - break; - - case HLSL_OP2_BIT_AND: - VKD3D_ASSERT(type_is_integer(dst_type)); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_AND, &expr->node, arg1, arg2); - break; - - case HLSL_OP2_BIT_OR: - VKD3D_ASSERT(type_is_integer(dst_type)); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_OR, &expr->node, arg1, arg2); - break; - - case HLSL_OP2_BIT_XOR: - VKD3D_ASSERT(type_is_integer(dst_type)); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_XOR, &expr->node, arg1, arg2); - break; - case HLSL_OP2_DIV: switch (dst_type->e.numeric.type) { @@ -5799,146 +5614,6 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ } break; - case HLSL_OP2_EQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; - - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - - switch (src_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_EQ, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_IEQ, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 equality between \"%s\" operands.", - debug_hlsl_type(tpf->ctx, src_type)); - break; - } - break; - } - - case HLSL_OP2_GEQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; - - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - - switch (src_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_GE, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_INT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_IGE, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_UGE, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 greater-than-or-equal between \"%s\" operands.", - debug_hlsl_type(tpf->ctx, src_type)); - break; - } - break; - } - - case HLSL_OP2_LESS: - { - const struct hlsl_type *src_type = arg1->data_type; - - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - - switch (src_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_LT, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_INT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_ILT, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_ULT, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 less-than between \"%s\" operands.", - debug_hlsl_type(tpf->ctx, src_type)); - break; - } - break; - } - - case HLSL_OP2_LOGIC_AND: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_AND, &expr->node, arg1, arg2); - break; - - case HLSL_OP2_LOGIC_OR: - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_OR, &expr->node, arg1, arg2); - break; - - case HLSL_OP2_LSHIFT: - VKD3D_ASSERT(type_is_integer(dst_type)); - VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); - write_sm4_binary_op(tpf, VKD3D_SM4_OP_ISHL, &expr->node, arg1, arg2); - break; - - case HLSL_OP2_MAX: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_MAX, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_INT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_IMAX, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_UMAX, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s maximum expression.", dst_type_string->buffer); - } - break; - - case HLSL_OP2_MIN: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_MIN, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_INT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_IMIN, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_UMIN, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s minimum expression.", dst_type_string->buffer); - } - break; - case HLSL_OP2_MOD: switch (dst_type->e.numeric.type) { @@ -5970,60 +5645,6 @@ static void write_sm4_expr(const struct tpf_compiler *tpf, const struct hlsl_ir_ } break; - case HLSL_OP2_NEQUAL: - { - const struct hlsl_type *src_type = arg1->data_type; - - VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - - switch (src_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_NE, &expr->node, arg1, arg2); - break; - - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_binary_op(tpf, VKD3D_SM4_OP_INE, &expr->node, arg1, arg2); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 inequality between \"%s\" operands.", - debug_hlsl_type(tpf->ctx, src_type)); - break; - } - break; - } - - case HLSL_OP2_RSHIFT: - VKD3D_ASSERT(type_is_integer(dst_type)); - VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); - write_sm4_binary_op(tpf, dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, - &expr->node, arg1, arg2); - break; - - case HLSL_OP3_TERNARY: - write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3); - break; - - case HLSL_OP3_MAD: - switch (dst_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MAD, &expr->node, arg1, arg2, arg3); - break; - - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - write_sm4_ternary_op(tpf, VKD3D_SM4_OP_IMAD, &expr->node, arg1, arg2, arg3); - break; - - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s negation expression.", dst_type_string->buffer); - } - break; - default: hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); } @@ -6476,7 +6097,53 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); break; + case VKD3DSIH_ADD: + case VKD3DSIH_AND: + case VKD3DSIH_DSX: + case VKD3DSIH_DSX_COARSE: + case VKD3DSIH_DSX_FINE: + case VKD3DSIH_DSY: + case VKD3DSIH_DSY_COARSE: + case VKD3DSIH_DSY_FINE: + case VKD3DSIH_EQO: + case VKD3DSIH_EXP: + case VKD3DSIH_F16TOF32: + case VKD3DSIH_F32TOF16: + case VKD3DSIH_FRC: + case VKD3DSIH_GEO: + case VKD3DSIH_IADD: + case VKD3DSIH_IEQ: + case VKD3DSIH_IGE: + case VKD3DSIH_ILT: + case VKD3DSIH_INE: + case VKD3DSIH_IMAD: + case VKD3DSIH_IMAX: + case VKD3DSIH_IMIN: + case VKD3DSIH_INEG: + case VKD3DSIH_ISHL: + case VKD3DSIH_ISHR: + case VKD3DSIH_LOG: + case VKD3DSIH_LTO: + case VKD3DSIH_MAD: + case VKD3DSIH_MAX: + case VKD3DSIH_MIN: case VKD3DSIH_MOV: + case VKD3DSIH_MOVC: + case VKD3DSIH_NEU: + case VKD3DSIH_NOT: + case VKD3DSIH_OR: + case VKD3DSIH_ROUND_NE: + case VKD3DSIH_ROUND_NI: + case VKD3DSIH_ROUND_PI: + case VKD3DSIH_ROUND_Z: + case VKD3DSIH_RSQ: + case VKD3DSIH_SQRT: + case VKD3DSIH_UGE: + case VKD3DSIH_ULT: + case VKD3DSIH_UMAX: + case VKD3DSIH_UMIN: + case VKD3DSIH_USHR: + case VKD3DSIH_XOR: tpf_simple_instruction(tpf, ins); break;