vkd3d-shader/hlsl: Lower casts to int for SM1.

This commit is contained in:
Francisco Casas
2023-10-20 23:23:46 -03:00
committed by Alexandre Julliard
parent e62bd1927e
commit e3ed5ac77e
Notes: Alexandre Julliard 2024-02-15 23:59:05 +01:00
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Matteo Bruni (@Mystral)
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/608
7 changed files with 59 additions and 25 deletions

View File

@@ -2000,16 +2000,14 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
case HLSL_TYPE_UINT:
switch(src_type->base_type)
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
/* A compilation pass applies a FLOOR operation to casts to int, so no change is necessary. */
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
write_sm1_unary_op(ctx, buffer, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0);
break;
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from float to integer.");
break;
case HLSL_TYPE_BOOL:
hlsl_fixme(ctx, &instr->loc, "SM1 cast from bool to integer.");
break;
@@ -2244,6 +2242,12 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
assert(instr->reg.allocated);
if (expr->op == HLSL_OP1_CAST)
{
write_sm1_cast(ctx, buffer, instr);
return;
}
if (instr->data_type->base_type != HLSL_TYPE_FLOAT)
{
/* These need to be lowered. */
@@ -2257,10 +2261,6 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
write_sm1_unary_op(ctx, buffer, D3DSIO_ABS, &instr->reg, &arg1->reg, 0, 0);
break;
case HLSL_OP1_CAST:
write_sm1_cast(ctx, buffer, instr);
break;
case HLSL_OP1_DSX:
write_sm1_unary_op(ctx, buffer, D3DSIO_DSX, &instr->reg, &arg1->reg, 0, 0);
break;

View File

@@ -2647,6 +2647,39 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx)
return false;
}
/* Append a FLOOR before a CAST to int or uint (which is written as a mere MOV). */
static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
struct hlsl_ir_node *arg, *floor, *cast2;
struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR)
return false;
expr = hlsl_ir_expr(instr);
if (expr->op != HLSL_OP1_CAST)
return false;
arg = expr->operands[0].node;
if (instr->data_type->base_type != HLSL_TYPE_INT && instr->data_type->base_type != HLSL_TYPE_UINT)
return false;
if (arg->data_type->base_type != HLSL_TYPE_FLOAT && arg->data_type->base_type != HLSL_TYPE_HALF)
return false;
/* Check that the argument is not already a FLOOR */
if (arg->type == HLSL_IR_EXPR && hlsl_ir_expr(arg)->op == HLSL_OP1_FLOOR)
return false;
if (!(floor = hlsl_new_unary_expr(ctx, HLSL_OP1_FLOOR, arg, &instr->loc)))
return false;
hlsl_block_add_instr(block, floor);
if (!(cast2 = hlsl_new_cast(ctx, floor, instr->data_type, &instr->loc)))
return false;
hlsl_block_add_instr(block, cast2);
return true;
}
/* Lower DIV to RCP + MUL. */
static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
{
@@ -5060,6 +5093,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
lower_ir(ctx, lower_ternary, body);
if (profile->major_version < 4)
{
lower_ir(ctx, lower_casts_to_int, body);
lower_ir(ctx, lower_division, body);
lower_ir(ctx, lower_sqrt, body);
lower_ir(ctx, lower_dot, body);