vkd3d-shader/hlsl: Express deref->offset in whole registers.

This is required to use SM4 relative addressing, because it is limited
to whole-register granularity.
This commit is contained in:
Francisco Casas 2023-10-03 19:14:54 -03:00 committed by Alexandre Julliard
parent 61a17643a2
commit 1520f327e5
Notes: Alexandre Julliard 2023-10-31 22:38:12 +01: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/396
3 changed files with 13 additions and 14 deletions

View File

@ -2437,10 +2437,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der
vkd3d_string_buffer_printf(buffer, "[");
if (show_rel)
{
dump_src(buffer, &deref->offset);
vkd3d_string_buffer_printf(buffer, "c");
}
if (show_rel && show_const)
vkd3d_string_buffer_printf(buffer, " + ");
if (show_const)

View File

@ -642,7 +642,7 @@ struct hlsl_deref
* regset) from the start of the variable, to the part of the variable that is referenced.
* This offset is stored using two fields, one for a variable part and other for a constant
* part, which are added together:
* - offset: An offset given by an instruction node, in number of register components.
* - offset: An offset given by an instruction node, in whole registers.
* - const_offset: A constant number of register components.
* Since the type information cannot longer be retrieved from the offset alone, the type is
* stored in the data_type field, which remains NULL if the deref hasn't been lowered yet. */

View File

@ -37,14 +37,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
case HLSL_CLASS_MATRIX:
{
if (!(c = hlsl_new_uint_constant(ctx, 4, loc)))
return NULL;
hlsl_block_add_instr(block, c);
if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, c, idx)))
return NULL;
hlsl_block_add_instr(block, idx_offset);
idx_offset = idx;
break;
}
@ -52,6 +45,12 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
{
unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type, regset);
if (regset == HLSL_REGSET_NUMERIC)
{
assert(size % 4 == 0);
size /= 4;
}
if (!(c = hlsl_new_uint_constant(ctx, size, loc)))
return NULL;
hlsl_block_add_instr(block, c);
@ -73,7 +72,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
{
assert(*offset_component == 0);
*offset_component = field_offset % 4;
field_offset -= *offset_component;
field_offset /= 4;
}
if (!(c = hlsl_new_uint_constant(ctx, field_offset, loc)))
@ -4470,7 +4469,10 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref
if (offset_node->type != HLSL_IR_CONSTANT)
return false;
*offset += hlsl_ir_constant(offset_node)->value.u[0].u;
if (regset == HLSL_REGSET_NUMERIC)
*offset += 4 * hlsl_ir_constant(offset_node)->value.u[0].u;
else
*offset += hlsl_ir_constant(offset_node)->value.u[0].u;
}
size = deref->var->data_type->reg_size[regset];