vkd3d-shader/hlsl: Introduce hlsl_block_add_swizzle().

This commit is contained in:
Elizabeth Figura
2024-12-09 17:11:55 -06:00
committed by Henri Verbeet
parent f8c53fae37
commit 0642531c2a
Notes: Henri Verbeet 2025-03-12 22:21:12 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Francisco Casas (@fcasas)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1413
4 changed files with 35 additions and 87 deletions

View File

@@ -2060,6 +2060,12 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
return &swizzle->node; return &swizzle->node;
} }
struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s,
unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
{
return append_new_instr(ctx, block, hlsl_new_swizzle(ctx, s, width, val, loc));
}
struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s, struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s,
unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
{ {

View File

@@ -1564,6 +1564,8 @@ void hlsl_block_add_store_component(struct hlsl_ctx *ctx, struct hlsl_block *blo
void hlsl_block_add_store_index(struct hlsl_ctx *ctx, struct hlsl_block *block, void hlsl_block_add_store_index(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs,
unsigned int writemask, const struct vkd3d_shader_location *loc); unsigned int writemask, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s,
unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block,
unsigned int n, const struct vkd3d_shader_location *loc); unsigned int n, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,

View File

@@ -2064,7 +2064,6 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
else if (lhs->type == HLSL_IR_SWIZZLE) else if (lhs->type == HLSL_IR_SWIZZLE)
{ {
struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs); struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs);
struct hlsl_ir_node *new_swizzle;
uint32_t s; uint32_t s;
VKD3D_ASSERT(!matrix_writemask); VKD3D_ASSERT(!matrix_writemask);
@@ -2095,13 +2094,9 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
} }
} }
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) rhs = hlsl_block_add_swizzle(ctx, block, s, width, rhs, &swizzle->node.loc);
return false;
hlsl_block_add_instr(block, new_swizzle);
lhs = swizzle->val.node; lhs = swizzle->val.node;
lhs_type = hlsl_get_vector_type(ctx, lhs_type->e.numeric.type, width); lhs_type = hlsl_get_vector_type(ctx, lhs_type->e.numeric.type, width);
rhs = new_swizzle;
} }
else else
{ {
@@ -3661,26 +3656,16 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx,
if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc)))
return false; return false;
if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) arg1_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc);
return false; arg2_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc);
hlsl_block_add_instr(params->instrs, arg1_swzl1);
if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc)))
return false;
hlsl_block_add_instr(params->instrs, arg2_swzl1);
if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl1, arg2_swzl1, loc))) if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl1, arg2_swzl1, loc)))
return false; return false;
mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc); mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc);
if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) arg1_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc);
return false; arg2_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc);
hlsl_block_add_instr(params->instrs, arg1_swzl2);
if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc)))
return false;
hlsl_block_add_instr(params->instrs, arg2_swzl2);
if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc))) if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc)))
return false; return false;
@@ -4800,9 +4785,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
else else
load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS; load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS;
if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc))) c = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc);
return false;
hlsl_block_add_instr(params->instrs, c);
if (!(coords = add_implicit_conversion(ctx, params->instrs, c, if (!(coords = add_implicit_conversion(ctx, params->instrs, c,
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
@@ -4810,9 +4793,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
return false; return false;
} }
if (!(lod = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc))) lod = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc);
return false;
hlsl_block_add_instr(params->instrs, lod);
if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod, if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod,
hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
@@ -4834,13 +4815,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
{ {
struct hlsl_ir_node *divisor; struct hlsl_ir_node *divisor;
if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc))) divisor = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc);
return false; coords = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc);
hlsl_block_add_instr(params->instrs, divisor);
if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc)))
return false;
hlsl_block_add_instr(params->instrs, coords);
if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc))) if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc)))
return false; return false;
@@ -5055,7 +5031,7 @@ static bool intrinsic_trunc(struct hlsl_ctx *ctx,
static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc) const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{ {
struct hlsl_ir_node *arg = params->args[0], *ret, *c, *swizzle; struct hlsl_ir_node *arg = params->args[0], *ret, *c;
struct hlsl_type *arg_type = arg->data_type; struct hlsl_type *arg_type = arg->data_type;
if (arg_type->class != HLSL_CLASS_SCALAR && !(arg_type->class == HLSL_CLASS_VECTOR if (arg_type->class != HLSL_CLASS_SCALAR && !(arg_type->class == HLSL_CLASS_VECTOR
@@ -5078,13 +5054,7 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx,
c = hlsl_block_add_float_constant(ctx, params->instrs, 255.0f + (0.5f / 256.0f), loc); c = hlsl_block_add_float_constant(ctx, params->instrs, 255.0f + (0.5f / 256.0f), loc);
if (arg_type->class == HLSL_CLASS_VECTOR) if (arg_type->class == HLSL_CLASS_VECTOR)
{ arg = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc);
if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc)))
return false;
hlsl_block_add_instr(params->instrs, swizzle);
arg = swizzle;
}
if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc))) if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc)))
return false; return false;

View File

@@ -1291,7 +1291,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && src_type->e.numeric.dimx == 1) if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && src_type->e.numeric.dimx == 1)
{ {
struct hlsl_ir_node *new_cast, *swizzle; struct hlsl_ir_node *new_cast;
dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type); dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type);
/* We need to preserve the cast since it might be doing more than just /* We need to preserve the cast since it might be doing more than just
@@ -1299,12 +1299,8 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc); new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc);
if (dst_type->e.numeric.dimx != 1) if (dst_type->e.numeric.dimx != 1)
{ hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
dst_type->e.numeric.dimx, new_cast, &cast->node.loc)))
return false;
hlsl_block_add_instr(block, swizzle);
}
return true; return true;
} }
@@ -2039,14 +2035,7 @@ static bool copy_propagation_replace_with_deref(struct hlsl_ctx *ctx,
hlsl_block_add_instr(&block, new_instr); hlsl_block_add_instr(&block, new_instr);
if (new_instr->data_type->class == HLSL_CLASS_SCALAR || new_instr->data_type->class == HLSL_CLASS_VECTOR) if (new_instr->data_type->class == HLSL_CLASS_SCALAR || new_instr->data_type->class == HLSL_CLASS_VECTOR)
{ new_instr = hlsl_block_add_swizzle(ctx, &block, ret_swizzle, instr_component_count, new_instr, &instr->loc);
struct hlsl_ir_node *swizzle_node;
if (!(swizzle_node = hlsl_new_swizzle(ctx, ret_swizzle, instr_component_count, new_instr, &instr->loc)))
goto done;
hlsl_block_add_instr(&block, swizzle_node);
new_instr = swizzle_node;
}
if (TRACE_ON()) if (TRACE_ON())
{ {
@@ -2841,18 +2830,14 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR
&& dst_type->e.numeric.dimx < src_type->e.numeric.dimx) && dst_type->e.numeric.dimx < src_type->e.numeric.dimx)
{ {
struct hlsl_ir_node *new_cast, *swizzle; struct hlsl_ir_node *new_cast;
dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->e.numeric.dimx); dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->e.numeric.dimx);
/* We need to preserve the cast since it might be doing more than just /* We need to preserve the cast since it might be doing more than just
* narrowing the vector. */ * narrowing the vector. */
new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc);
hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W),
if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
dst_type->e.numeric.dimx, new_cast, &cast->node.loc)))
return false;
hlsl_block_add_instr(block, swizzle);
return true; return true;
} }
@@ -3066,9 +3051,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
return false; return false;
hlsl_block_add_instr(block, &vector_load->node); hlsl_block_add_instr(block, &vector_load->node);
if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc))) swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc);
return false;
hlsl_block_add_instr(block, swizzle);
value.u[0].u = 0; value.u[0].u = 0;
value.u[1].u = 1; value.u[1].u = 1;
@@ -3201,11 +3184,8 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n
operands[0] = cut_index; operands[0] = cut_index;
operands[1] = const_i; operands[1] = const_i;
equals = hlsl_block_add_expr(ctx, block, HLSL_OP2_EQUAL, operands, btype, &cut_index->loc); equals = hlsl_block_add_expr(ctx, block, HLSL_OP2_EQUAL, operands, btype, &cut_index->loc);
equals = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
if (!(equals = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), var->data_type->e.numeric.dimx, equals, &cut_index->loc);
var->data_type->e.numeric.dimx, equals, &cut_index->loc)))
return false;
hlsl_block_add_instr(block, equals);
var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc); var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc);
@@ -3678,16 +3658,10 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h
{ {
mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node); mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node);
if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), add_x = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X),
instr->data_type->e.numeric.dimx, mul, &expr->node.loc))) instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
return false; add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y),
hlsl_block_add_instr(block, add_x); instr->data_type->e.numeric.dimx, mul, &expr->node.loc);
if (!(add_y = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Y, Y, Y),
instr->data_type->e.numeric.dimx, mul, &expr->node.loc)))
return false;
hlsl_block_add_instr(block, add_y);
hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y);
} }
@@ -3850,9 +3824,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
{ {
uint32_t s = hlsl_swizzle_from_writemask(1 << i); uint32_t s = hlsl_swizzle_from_writemask(1 << i);
if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, reduced, &instr->loc))) comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, reduced, &instr->loc);
return false;
hlsl_block_add_instr(block, comps[i]);
} }
if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc))) if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc)))
@@ -4372,9 +4344,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
{ {
uint32_t s = hlsl_swizzle_from_writemask(1 << i); uint32_t s = hlsl_swizzle_from_writemask(1 << i);
if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, mult, &instr->loc);
return false;
hlsl_block_add_instr(block, comps[i]);
} }
res = comps[0]; res = comps[0];