diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b2f42f69..2db9a0dd 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -298,6 +298,35 @@ bool hlsl_type_is_patch_array(const struct hlsl_type *type) || type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT); } +bool hlsl_type_is_integer(const struct hlsl_type *type) +{ + if (!hlsl_is_numeric_type(type)) + return false; + + switch (type->e.numeric.type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + return true; + + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return false; + } + + vkd3d_unreachable(); +} + +bool hlsl_type_is_floating_point(const struct hlsl_type *type) +{ + if (!hlsl_is_numeric_type(type)) + return false; + + return !hlsl_type_is_integer(type); +} + /* Only intended to be used for derefs (after copies have been lowered to components or vectors) or * resources, since for both their data types span across a single regset. */ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 1a21fd1f..9d4cdc23 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1695,6 +1695,8 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl unsigned int index); unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index, enum hlsl_regset *regset); +bool hlsl_type_is_integer(const struct hlsl_type *type); +bool hlsl_type_is_floating_point(const struct hlsl_type *type); bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 2ffbd3cc..abcead82 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -4187,15 +4187,7 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst switch (expr->op) { - case HLSL_OP1_ABS: - case HLSL_OP1_NEG: - case HLSL_OP2_ADD: case HLSL_OP2_DIV: - case HLSL_OP2_LOGIC_AND: - case HLSL_OP2_LOGIC_OR: - case HLSL_OP2_MAX: - case HLSL_OP2_MIN: - case HLSL_OP2_MUL: { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; struct hlsl_ir_node *arg, *float_expr; @@ -7711,13 +7703,8 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - if (ctx->double_as_float_alias) - { - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); - return true; - } - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "The 'double' type is not supported for the %s profile.", ctx->profile->name); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + return true; break; default: @@ -7740,12 +7727,15 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr struct hlsl_ir_expr *expr) { struct hlsl_ir_node *instr = &expr->node; + struct hlsl_type *type = instr->data_type; - if (expr->op != HLSL_OP1_REINTERPRET && expr->op != HLSL_OP1_CAST - && instr->data_type->e.numeric.type != HLSL_TYPE_FLOAT) + if (!hlsl_is_numeric_type(type)) + goto err; + + if (type->e.numeric.type == HLSL_TYPE_DOUBLE && !ctx->double_as_float_alias) { - /* These need to be lowered. */ - hlsl_fixme(ctx, &instr->loc, "SM1 non-float expression."); + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The 'double' type is not supported for the %s profile.", ctx->profile->name); return false; } @@ -7760,30 +7750,44 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP1_COS_REDUCED: VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_0); + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_sincos(ctx, program, expr); break; case HLSL_OP1_DSX: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); break; case HLSL_OP1_DSY: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); break; case HLSL_OP1_EXP2: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP); break; case HLSL_OP1_LOG2: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG); break; case HLSL_OP1_NEG: + if (type->e.numeric.type == HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); break; case HLSL_OP1_RCP: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP); break; @@ -7792,23 +7796,33 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP1_RSQ: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ); break; case HLSL_OP1_SAT: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); break; case HLSL_OP1_SIN_REDUCED: VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_1); + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_sincos(ctx, program, expr); break; case HLSL_OP2_ADD: + if (type->e.numeric.type == HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); break; case HLSL_OP2_DOT: + if (!hlsl_type_is_floating_point(type)) + goto err; switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 3: @@ -7842,35 +7856,49 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP2_LOGIC_AND: + if (type->e.numeric.type != HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); break; case HLSL_OP2_LOGIC_OR: + if (type->e.numeric.type != HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); break; case HLSL_OP2_SLT: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true); break; case HLSL_OP3_CMP: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true); break; case HLSL_OP3_DP2ADD: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false); break; case HLSL_OP3_MAD: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); break; default: - hlsl_fixme(ctx, &instr->loc, "SM1 \"%s\" expression.", debug_hlsl_expr_op(expr->op)); - return false; + goto err; } - return true; + +err: + hlsl_fixme(ctx, &instr->loc, "SM1 %s expression of type %s.", debug_hlsl_expr_op(expr->op), instr->data_type->name); + return false; } static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, diff --git a/tests/hlsl/cast-to-int.shader_test b/tests/hlsl/cast-to-int.shader_test index 9f4f7f7a..077f967d 100644 --- a/tests/hlsl/cast-to-int.shader_test +++ b/tests/hlsl/cast-to-int.shader_test @@ -35,7 +35,7 @@ draw quad probe (0, 0) rgba(0, 0, -12, 14) -[pixel shader todo(sm<4)] +[pixel shader] uniform float f; uniform uint u; uniform bool b; @@ -61,7 +61,7 @@ if(sm>=4) uniform 0 float 2.6 if(sm>=4) uniform 1 int -2 if(sm>=4) uniform 2 int -2 if(sm>=4) uniform 3 float -3.6 -todo(sm<4) draw quad +draw quad probe (0, 0) rgba (0.5, 0.5, 0.5, 0.5) diff --git a/tests/hlsl/saturate.shader_test b/tests/hlsl/saturate.shader_test index e82c92fe..7c5ff0ef 100644 --- a/tests/hlsl/saturate.shader_test +++ b/tests/hlsl/saturate.shader_test @@ -25,7 +25,7 @@ uniform 0 float4 -2 0 2 -1 draw quad probe (0, 0) rgba (0.0, 0.0, 1.0, 0.0) -[pixel shader todo(sm<4)] +[pixel shader] uniform float4 u; float4 main() : sv_target @@ -36,5 +36,5 @@ float4 main() : sv_target [test] uniform 0 float4 -2.0 1.2 0.2 4.0 -todo(sm<4) draw quad +draw quad probe (0, 0) rgba (0.0, 1.0, 0.2, 1.0)