mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
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:
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
@ -249,87 +249,6 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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,
|
||||
|
@ -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);
|
||||
|
||||
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,
|
||||
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 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_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,
|
||||
unsigned int index);
|
||||
bool hlsl_type_is_row_major(const struct hlsl_type *type);
|
||||
|
@ -1202,6 +1202,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
struct vkd3d_string_buffer *name;
|
||||
static unsigned int counter = 0;
|
||||
struct hlsl_type *vector_type;
|
||||
struct hlsl_deref var_deref;
|
||||
struct hlsl_ir_load *load;
|
||||
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);
|
||||
if (!var)
|
||||
return NULL;
|
||||
hlsl_init_simple_deref_from_var(&var_deref, var);
|
||||
|
||||
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)))
|
||||
return NULL;
|
||||
|
||||
if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &c->node.entry);
|
||||
|
||||
if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc)))
|
||||
if (!(store = hlsl_new_store_index(ctx, &var_deref, &c->node, value, 0, loc)))
|
||||
return NULL;
|
||||
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_ir_store *store;
|
||||
struct hlsl_ir_node *offset;
|
||||
struct hlsl_ir_expr *copy;
|
||||
unsigned int writemask = 0;
|
||||
struct hlsl_block block;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!(store = hlsl_alloc(ctx, sizeof(*store))))
|
||||
return NULL;
|
||||
|
||||
while (lhs->type != HLSL_IR_LOAD)
|
||||
{
|
||||
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_OP1_CAST)
|
||||
{
|
||||
hlsl_fixme(ctx, &lhs->loc, "Cast on the LHS.");
|
||||
vkd3d_free(store);
|
||||
return NULL;
|
||||
}
|
||||
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))
|
||||
{
|
||||
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
|
||||
vkd3d_free(store);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
|
||||
{
|
||||
vkd3d_free(store);
|
||||
return NULL;
|
||||
}
|
||||
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
|
||||
{
|
||||
hlsl_error(ctx, &lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
|
||||
vkd3d_free(store);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
offset = hlsl_new_offset_instr_from_deref(ctx, &block, &hlsl_ir_load(lhs)->src, &lhs->loc);
|
||||
list_move_tail(instrs, &block.instrs);
|
||||
|
||||
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);
|
||||
if (!(store = hlsl_new_store_index(ctx, &hlsl_ir_load(lhs)->src, NULL, rhs, writemask, &rhs->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &store->node.entry);
|
||||
|
||||
/* Don't use the instruction itself as a source, as this makes structure
|
||||
|
Loading…
Reference in New Issue
Block a user