vkd3d-shader/hlsl: Introduce hlsl_new_store_index().

Signed-off-by: Francisco Casas <fcasas@codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com>
This commit is contained in:
Francisco Casas 2022-07-13 16:56:21 -04:00 committed by Alexandre Julliard
parent f3289e1661
commit 5b664c7a5c
Notes: Alexandre Julliard 2022-10-18 00:13:00 +02:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/5
3 changed files with 40 additions and 106 deletions

View File

@ -249,87 +249,6 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e
return type; return type;
} }
/* Returns the register offset of a given component within a type, given its index.
* *comp_type will be set to the type of the component. */
unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int idx, struct hlsl_type **comp_type)
{
switch (type->type)
{
case HLSL_CLASS_SCALAR:
case HLSL_CLASS_VECTOR:
{
assert(idx < type->dimx * type->dimy);
*comp_type = hlsl_get_scalar_type(ctx, type->base_type);
return idx;
}
case HLSL_CLASS_MATRIX:
{
unsigned int minor, major, x = idx % type->dimx, y = idx / type->dimx;
assert(idx < type->dimx * type->dimy);
if (hlsl_type_is_row_major(type))
{
minor = x;
major = y;
}
else
{
minor = y;
major = x;
}
*comp_type = hlsl_get_scalar_type(ctx, type->base_type);
return 4 * major + minor;
}
case HLSL_CLASS_ARRAY:
{
unsigned int elem_comp_count = hlsl_type_component_count(type->e.array.type);
unsigned int array_idx = idx / elem_comp_count;
unsigned int idx_in_elem = idx % elem_comp_count;
assert(array_idx < type->e.array.elements_count);
return array_idx * hlsl_type_get_array_element_reg_size(type->e.array.type) +
hlsl_compute_component_offset(ctx, type->e.array.type, idx_in_elem, comp_type);
}
case HLSL_CLASS_STRUCT:
{
struct hlsl_struct_field *field;
unsigned int elem_comp_count, i;
for (i = 0; i < type->e.record.field_count; ++i)
{
field = &type->e.record.fields[i];
elem_comp_count = hlsl_type_component_count(field->type);
if (idx < elem_comp_count)
{
return field->reg_offset +
hlsl_compute_component_offset(ctx, field->type, idx, comp_type);
}
idx -= elem_comp_count;
}
assert(0);
return 0;
}
case HLSL_CLASS_OBJECT:
{
assert(idx == 0);
*comp_type = type;
return 0;
}
}
assert(0);
return 0;
}
static bool type_is_single_component(const struct hlsl_type *type) static bool type_is_single_component(const struct hlsl_type *type)
{ {
return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT; return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_OBJECT;
@ -989,7 +908,39 @@ void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_va
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
{ {
return hlsl_new_store(ctx, lhs, NULL, rhs, 0, rhs->loc); struct hlsl_deref lhs_deref;
hlsl_init_simple_deref_from_var(&lhs_deref, lhs);
return hlsl_new_store_index(ctx, &lhs_deref, NULL, rhs, 0, &rhs->loc);
}
struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs,
struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_store *store;
unsigned int i;
assert(lhs);
assert(!lhs->offset.node);
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
init_node(&store->node, HLSL_IR_STORE, NULL, *loc);
if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx))
return NULL;
for (i = 0; i < lhs->path_len; ++i)
hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node);
if (idx)
hlsl_src_from_node(&store->lhs.path[lhs->path_len], idx);
hlsl_src_from_node(&store->rhs, rhs);
if (!writemask && type_is_single_reg(rhs->data_type))
writemask = (1 << rhs->data_type->dimx) - 1;
store->writemask = writemask;
return store;
} }
struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,

View File

@ -768,6 +768,8 @@ struct hlsl_ir_load *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b
const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc);
struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs);
struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs,
struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc);
struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs); const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
@ -817,8 +819,6 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
unsigned int default_majority, unsigned int modifiers); unsigned int default_majority, unsigned int modifiers);
unsigned int hlsl_type_component_count(const struct hlsl_type *type); unsigned int hlsl_type_component_count(const struct hlsl_type *type);
unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type);
unsigned int hlsl_compute_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int idx, struct hlsl_type **comp_type);
struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type,
unsigned int index); unsigned int index);
bool hlsl_type_is_row_major(const struct hlsl_type *type); bool hlsl_type_is_row_major(const struct hlsl_type *type);

View File

@ -1202,6 +1202,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
struct vkd3d_string_buffer *name; struct vkd3d_string_buffer *name;
static unsigned int counter = 0; static unsigned int counter = 0;
struct hlsl_type *vector_type; struct hlsl_type *vector_type;
struct hlsl_deref var_deref;
struct hlsl_ir_load *load; struct hlsl_ir_load *load;
struct hlsl_ir_var *var; struct hlsl_ir_var *var;
@ -1213,6 +1214,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
vkd3d_string_buffer_release(&ctx->string_buffers, name); vkd3d_string_buffer_release(&ctx->string_buffers, name);
if (!var) if (!var)
return NULL; return NULL;
hlsl_init_simple_deref_from_var(&var_deref, var);
for (i = 0; i < hlsl_type_major_size(type); ++i) for (i = 0; i < hlsl_type_major_size(type); ++i)
{ {
@ -1240,11 +1242,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc)))
return NULL; return NULL;
if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) if (!(store = hlsl_new_store_index(ctx, &var_deref, &c->node, value, 0, loc)))
return NULL;
list_add_tail(instrs, &c->node.entry);
if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc)))
return NULL; return NULL;
list_add_tail(instrs, &store->node.entry); list_add_tail(instrs, &store->node.entry);
} }
@ -1606,10 +1604,8 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
{ {
struct hlsl_type *lhs_type = lhs->data_type; struct hlsl_type *lhs_type = lhs->data_type;
struct hlsl_ir_store *store; struct hlsl_ir_store *store;
struct hlsl_ir_node *offset;
struct hlsl_ir_expr *copy; struct hlsl_ir_expr *copy;
unsigned int writemask = 0; unsigned int writemask = 0;
struct hlsl_block block;
if (assign_op == ASSIGN_OP_SUB) if (assign_op == ASSIGN_OP_SUB)
{ {
@ -1634,15 +1630,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
return NULL; return NULL;
} }
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
return NULL;
while (lhs->type != HLSL_IR_LOAD) while (lhs->type != HLSL_IR_LOAD)
{ {
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST) if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
{ {
hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS."); hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS.");
vkd3d_free(store);
return NULL; return NULL;
} }
else if (lhs->type == HLSL_IR_SWIZZLE) else if (lhs->type == HLSL_IR_SWIZZLE)
@ -1656,13 +1648,11 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (!invert_swizzle(&s, &writemask, &width)) if (!invert_swizzle(&s, &writemask, &width))
{ {
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask."); hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
vkd3d_free(store);
return NULL; return NULL;
} }
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
{ {
vkd3d_free(store);
return NULL; return NULL;
} }
list_add_tail(instrs, &new_swizzle->node.entry); list_add_tail(instrs, &new_swizzle->node.entry);
@ -1673,19 +1663,12 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
else else
{ {
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue."); hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
vkd3d_free(store);
return NULL; return NULL;
} }
} }
offset = hlsl_new_offset_instr_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc); if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc)))
list_move_tail(instrs, &block.instrs); return NULL;
init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc);
store->writemask = writemask;
store->lhs.var = hlsl_ir_load(lhs)->src.var;
hlsl_src_from_node(&store->lhs.offset, offset);
hlsl_src_from_node(&store->rhs, rhs);
list_add_tail(instrs, &store->node.entry); list_add_tail(instrs, &store->node.entry);
/* Don't use the instruction itself as a source, as this makes structure /* Don't use the instruction itself as a source, as this makes structure