mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Use a structure for matrix swizzles.
This commit is contained in:
parent
70e2148fcb
commit
a905a78a96
Notes:
Henri Verbeet
2024-12-12 17:48:24 +01:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1297
@ -1854,22 +1854,45 @@ struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct
|
||||
return &store->node;
|
||||
}
|
||||
|
||||
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components,
|
||||
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
|
||||
struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_swizzle *swizzle;
|
||||
struct hlsl_type *type;
|
||||
|
||||
VKD3D_ASSERT(val->data_type->class <= HLSL_CLASS_VECTOR);
|
||||
|
||||
if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle))))
|
||||
return NULL;
|
||||
VKD3D_ASSERT(hlsl_is_numeric_type(val->data_type));
|
||||
if (components == 1)
|
||||
type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type);
|
||||
if (component_count > 1)
|
||||
type = hlsl_get_vector_type(ctx, val->data_type->e.numeric.type, component_count);
|
||||
else
|
||||
type = hlsl_get_vector_type(ctx, val->data_type->e.numeric.type, components);
|
||||
type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type);
|
||||
init_node(&swizzle->node, HLSL_IR_SWIZZLE, type, loc);
|
||||
hlsl_src_from_node(&swizzle->val, val);
|
||||
swizzle->swizzle = s;
|
||||
swizzle->u.vector = s;
|
||||
|
||||
return &swizzle->node;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct hlsl_ir_swizzle *swizzle;
|
||||
struct hlsl_type *type;
|
||||
|
||||
VKD3D_ASSERT(val->data_type->class == HLSL_CLASS_MATRIX);
|
||||
|
||||
if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle))))
|
||||
return NULL;
|
||||
if (component_count > 1)
|
||||
type = hlsl_get_vector_type(ctx, val->data_type->e.numeric.type, component_count);
|
||||
else
|
||||
type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type);
|
||||
init_node(&swizzle->node, HLSL_IR_SWIZZLE, type, loc);
|
||||
hlsl_src_from_node(&swizzle->val, val);
|
||||
swizzle->u.matrix = s;
|
||||
|
||||
return &swizzle->node;
|
||||
}
|
||||
|
||||
@ -2331,7 +2354,11 @@ static struct hlsl_ir_node *clone_store(struct hlsl_ctx *ctx, struct clone_instr
|
||||
static struct hlsl_ir_node *clone_swizzle(struct hlsl_ctx *ctx,
|
||||
struct clone_instr_map *map, struct hlsl_ir_swizzle *src)
|
||||
{
|
||||
return hlsl_new_swizzle(ctx, src->swizzle, src->node.data_type->dimx,
|
||||
if (src->val.node->data_type->class == HLSL_CLASS_MATRIX)
|
||||
return hlsl_new_matrix_swizzle(ctx, src->u.matrix, src->node.data_type->dimx,
|
||||
map_instr(map, src->val.node), &src->node.loc);
|
||||
else
|
||||
return hlsl_new_swizzle(ctx, src->u.vector, src->node.data_type->dimx,
|
||||
map_instr(map, src->val.node), &src->node.loc);
|
||||
}
|
||||
|
||||
@ -3412,11 +3439,12 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, ".");
|
||||
for (i = 0; i < swizzle->node.data_type->dimx; ++i)
|
||||
vkd3d_string_buffer_printf(buffer, "_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf);
|
||||
vkd3d_string_buffer_printf(buffer, "_m%u%u",
|
||||
swizzle->u.matrix.components[i].y, swizzle->u.matrix.components[i].x);
|
||||
}
|
||||
else
|
||||
{
|
||||
vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_swizzle(swizzle->swizzle, swizzle->node.data_type->dimx));
|
||||
vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_swizzle(swizzle->u.vector, swizzle->node.data_type->dimx));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -802,9 +802,17 @@ struct hlsl_ir_swizzle
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
struct hlsl_src val;
|
||||
/* For vectors, a swizzle described by hlsl_swizzle_get_component().
|
||||
* For matrices, a swizzle described by hlsl_matrix_swizzle_get_component(). */
|
||||
uint32_t swizzle;
|
||||
union
|
||||
{
|
||||
uint32_t vector;
|
||||
struct hlsl_matrix_swizzle
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t x, y;
|
||||
} components[4];
|
||||
} matrix;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct hlsl_ir_index
|
||||
@ -1564,6 +1572,8 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v
|
||||
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter,
|
||||
struct hlsl_block *block, enum hlsl_loop_unroll_type unroll_type,
|
||||
unsigned int unroll_limit, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s,
|
||||
unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
|
||||
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource,
|
||||
|
@ -845,6 +845,7 @@ static struct hlsl_ir_node *get_swizzle(struct hlsl_ctx *ctx, struct hlsl_ir_nod
|
||||
if (value->data_type->class == HLSL_CLASS_MATRIX)
|
||||
{
|
||||
/* Matrix swizzle */
|
||||
struct hlsl_matrix_swizzle s;
|
||||
bool m_swizzle;
|
||||
unsigned int inc, x, y;
|
||||
|
||||
@ -875,10 +876,11 @@ static struct hlsl_ir_node *get_swizzle(struct hlsl_ctx *ctx, struct hlsl_ir_nod
|
||||
|
||||
if (x >= value->data_type->dimx || y >= value->data_type->dimy)
|
||||
return NULL;
|
||||
swiz |= (y << 4 | x) << component * 8;
|
||||
s.components[component].x = x;
|
||||
s.components[component].y = y;
|
||||
component++;
|
||||
}
|
||||
return hlsl_new_swizzle(ctx, swiz, component, value, loc);
|
||||
return hlsl_new_matrix_swizzle(ctx, s, component, value, loc);
|
||||
}
|
||||
|
||||
/* Vector swizzle */
|
||||
@ -2112,22 +2114,22 @@ static bool invert_swizzle(uint32_t *swizzle, unsigned int *writemask, unsigned
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool invert_swizzle_matrix(uint32_t *swizzle, unsigned int *writemask, unsigned int *ret_width)
|
||||
static bool invert_swizzle_matrix(const struct hlsl_matrix_swizzle *swizzle,
|
||||
uint32_t *ret_inverted, unsigned int *writemask, unsigned int *ret_width)
|
||||
{
|
||||
/* swizzle is 8 bits per component, each component is (from LSB) 4 bits X, then 4 bits Y.
|
||||
* components are indexed by their sources. i.e. the first component comes from the first
|
||||
* component of the rhs. */
|
||||
unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0, new_swizzle = 0;
|
||||
unsigned int i, j, bit = 0, inverted = 0, width, new_writemask = 0;
|
||||
struct hlsl_matrix_swizzle new_swizzle = {0};
|
||||
|
||||
/* First, we filter the swizzle to remove components that aren't enabled by writemask. */
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
if (*writemask & (1 << i))
|
||||
{
|
||||
unsigned int s = (*swizzle >> (i * 8)) & 0xff;
|
||||
unsigned int x = s & 0xf, y = (s >> 4) & 0xf;
|
||||
unsigned int x = swizzle->components[i].x;
|
||||
unsigned int y = swizzle->components[i].y;
|
||||
unsigned int idx = x + y * 4;
|
||||
new_swizzle |= s << (bit++ * 8);
|
||||
|
||||
new_swizzle.components[bit++] = swizzle->components[i];
|
||||
if (new_writemask & (1 << idx))
|
||||
return false;
|
||||
new_writemask |= 1 << idx;
|
||||
@ -2135,22 +2137,22 @@ static bool invert_swizzle_matrix(uint32_t *swizzle, unsigned int *writemask, un
|
||||
}
|
||||
width = bit;
|
||||
|
||||
/* Then we invert the swizzle. The resulting swizzle has 2 bits per component, because it's for the
|
||||
* incoming vector. */
|
||||
/* Then we invert the swizzle. The resulting swizzle uses a uint32_t
|
||||
* vector format, because it's for the incoming vector. */
|
||||
bit = 0;
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
for (j = 0; j < width; ++j)
|
||||
{
|
||||
unsigned int s = (new_swizzle >> (j * 8)) & 0xff;
|
||||
unsigned int x = s & 0xf, y = (s >> 4) & 0xf;
|
||||
unsigned int x = new_swizzle.components[j].x;
|
||||
unsigned int y = new_swizzle.components[j].y;
|
||||
unsigned int idx = x + y * 4;
|
||||
if (idx == i)
|
||||
inverted |= j << (bit++ * 2);
|
||||
}
|
||||
}
|
||||
|
||||
*swizzle = inverted;
|
||||
*ret_inverted = inverted;
|
||||
*writemask = new_writemask;
|
||||
*ret_width = width;
|
||||
return true;
|
||||
@ -2204,29 +2206,35 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
|
||||
{
|
||||
struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs);
|
||||
struct hlsl_ir_node *new_swizzle;
|
||||
uint32_t s = swizzle->swizzle;
|
||||
uint32_t s;
|
||||
|
||||
VKD3D_ASSERT(!matrix_writemask);
|
||||
|
||||
if (swizzle->val.node->data_type->class == HLSL_CLASS_MATRIX)
|
||||
{
|
||||
struct hlsl_matrix_swizzle ms = swizzle->u.matrix;
|
||||
|
||||
if (swizzle->val.node->type != HLSL_IR_LOAD && swizzle->val.node->type != HLSL_IR_INDEX)
|
||||
{
|
||||
hlsl_fixme(ctx, &lhs->loc, "Unhandled source of matrix swizzle.");
|
||||
return false;
|
||||
}
|
||||
if (!invert_swizzle_matrix(&s, &writemask, &width))
|
||||
if (!invert_swizzle_matrix(&ms, &s, &writemask, &width))
|
||||
{
|
||||
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask for matrix.");
|
||||
return false;
|
||||
}
|
||||
matrix_writemask = true;
|
||||
}
|
||||
else if (!invert_swizzle(&s, &writemask, &width))
|
||||
else
|
||||
{
|
||||
s = swizzle->u.vector;
|
||||
if (!invert_swizzle(&s, &writemask, &width))
|
||||
{
|
||||
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
|
||||
return false;
|
||||
|
@ -1076,7 +1076,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
||||
struct hlsl_deref var_deref;
|
||||
struct hlsl_type *matrix_type;
|
||||
struct hlsl_ir_var *var;
|
||||
unsigned int x, y, k, i;
|
||||
unsigned int k, i;
|
||||
|
||||
if (instr->type != HLSL_IR_SWIZZLE)
|
||||
return false;
|
||||
@ -1094,9 +1094,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
|
||||
struct hlsl_block store_block;
|
||||
struct hlsl_ir_node *load;
|
||||
|
||||
y = (swizzle->swizzle >> (8 * i + 4)) & 0xf;
|
||||
x = (swizzle->swizzle >> 8 * i) & 0xf;
|
||||
k = y * matrix_type->dimx + x;
|
||||
k = swizzle->u.matrix.components[i].y * matrix_type->dimx + swizzle->u.matrix.components[i].x;
|
||||
|
||||
if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc)))
|
||||
return false;
|
||||
@ -1757,10 +1755,10 @@ static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx,
|
||||
return false;
|
||||
load = hlsl_ir_load(swizzle->val.node);
|
||||
|
||||
if (copy_propagation_replace_with_constant_vector(ctx, state, load, swizzle->swizzle, &swizzle->node))
|
||||
if (copy_propagation_replace_with_constant_vector(ctx, state, load, swizzle->u.vector, &swizzle->node))
|
||||
return true;
|
||||
|
||||
if (copy_propagation_replace_with_single_instr(ctx, state, load, swizzle->swizzle, &swizzle->node))
|
||||
if (copy_propagation_replace_with_single_instr(ctx, state, load, swizzle->u.vector, &swizzle->node))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -2442,8 +2440,8 @@ static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
||||
struct hlsl_ir_node *new_swizzle;
|
||||
uint32_t combined_swizzle;
|
||||
|
||||
combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->swizzle,
|
||||
swizzle->swizzle, instr->data_type->dimx);
|
||||
combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->u.vector,
|
||||
swizzle->u.vector, instr->data_type->dimx);
|
||||
next_instr = hlsl_ir_swizzle(next_instr)->val.node;
|
||||
|
||||
if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, instr->data_type->dimx, next_instr, &instr->loc)))
|
||||
@ -2470,7 +2468,7 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i
|
||||
return false;
|
||||
|
||||
for (i = 0; i < instr->data_type->dimx; ++i)
|
||||
if (hlsl_swizzle_get_component(swizzle->swizzle, i) != i)
|
||||
if (hlsl_swizzle_get_component(swizzle->u.vector, i) != i)
|
||||
return false;
|
||||
|
||||
hlsl_replace_node(instr, swizzle->val.node);
|
||||
@ -7895,7 +7893,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
|
||||
dst_param->write_mask = instr->reg.writemask;
|
||||
|
||||
swizzle = hlsl_swizzle_from_writemask(val->reg.writemask);
|
||||
swizzle = hlsl_combine_swizzles(swizzle, swizzle_instr->swizzle, instr->data_type->dimx);
|
||||
swizzle = hlsl_combine_swizzles(swizzle, swizzle_instr->u.vector, instr->data_type->dimx);
|
||||
swizzle = hlsl_map_swizzle(swizzle, ins->dst[0].write_mask);
|
||||
swizzle = vsir_swizzle_from_hlsl(swizzle);
|
||||
|
||||
|
@ -1705,7 +1705,7 @@ bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
||||
src = hlsl_ir_constant(swizzle->val.node);
|
||||
|
||||
for (i = 0; i < swizzle->node.data_type->dimx; ++i)
|
||||
value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->swizzle, i)];
|
||||
value.u[i] = src->value.u[hlsl_swizzle_get_component(swizzle->u.vector, i)];
|
||||
|
||||
if (!(dst = hlsl_new_constant(ctx, instr->data_type, &value, &instr->loc)))
|
||||
return false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user