vkd3d-shader/tpf: Declare indexable temps.

If var->indexable, then the variable is given a unique register number,
regardless of its lifetime.
This commit is contained in:
Francisco Casas 2023-10-04 18:03:14 -03:00 committed by Alexandre Julliard
parent 83c313ecc6
commit eef2163375
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
2 changed files with 55 additions and 5 deletions

View File

@ -3473,6 +3473,10 @@ struct register_allocator
unsigned int writemask; unsigned int writemask;
unsigned int first_write, last_read; unsigned int first_write, last_read;
} *allocations; } *allocations;
/* Indexable temps are allocated separately and always keep their index regardless of their
* lifetime. */
size_t indexable_count;
}; };
static unsigned int get_available_writemask(const struct register_allocator *allocator, static unsigned int get_available_writemask(const struct register_allocator *allocator,
@ -3719,11 +3723,23 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx,
if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read) if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read)
{ {
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, if (var->indexable)
var->first_write, var->last_read, var->data_type); {
var->regs[HLSL_REGSET_NUMERIC].id = allocator->indexable_count++;
var->regs[HLSL_REGSET_NUMERIC].allocation_size = 1;
var->regs[HLSL_REGSET_NUMERIC].writemask = 0;
var->regs[HLSL_REGSET_NUMERIC].allocated = true;
TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', TRACE("Allocated %s to x%u[].\n", var->name, var->regs[HLSL_REGSET_NUMERIC].id);
var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); }
else
{
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator,
var->first_write, var->last_read, var->data_type);
TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r',
var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read);
}
} }
} }

View File

@ -3732,7 +3732,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re
struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref);
assert(hlsl_reg.allocated); assert(hlsl_reg.allocated);
reg->type = VKD3DSPR_TEMP; reg->type = deref->var->indexable ? VKD3DSPR_IDXTEMP : VKD3DSPR_TEMP;
reg->dimension = VSIR_DIMENSION_VEC4; reg->dimension = VSIR_DIMENSION_VEC4;
reg->idx[0].offset = hlsl_reg.id; reg->idx[0].offset = hlsl_reg.id;
reg->idx_count = 1; reg->idx_count = 1;
@ -4251,6 +4251,20 @@ static void write_sm4_dcl_temps(const struct tpf_writer *tpf, uint32_t temp_coun
write_sm4_instruction(tpf, &instr); write_sm4_instruction(tpf, &instr);
} }
static void write_sm4_dcl_indexable_temp(const struct tpf_writer *tpf, uint32_t idx,
uint32_t size, uint32_t comp_count)
{
struct sm4_instruction instr =
{
.opcode = VKD3D_SM4_OP_DCL_INDEXABLE_TEMP,
.idx = {idx, size, comp_count},
.idx_count = 3,
};
write_sm4_instruction(tpf, &instr);
}
static void write_sm4_dcl_thread_group(const struct tpf_writer *tpf, const uint32_t thread_count[3]) static void write_sm4_dcl_thread_group(const struct tpf_writer *tpf, const uint32_t thread_count[3])
{ {
struct sm4_instruction instr = struct sm4_instruction instr =
@ -5616,6 +5630,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
struct extern_resource *extern_resources; struct extern_resource *extern_resources;
unsigned int extern_resources_count, i; unsigned int extern_resources_count, i;
const struct hlsl_buffer *cbuffer; const struct hlsl_buffer *cbuffer;
const struct hlsl_scope *scope;
const struct hlsl_ir_var *var; const struct hlsl_ir_var *var;
size_t token_count_position; size_t token_count_position;
struct tpf_writer tpf; struct tpf_writer tpf;
@ -5670,6 +5685,25 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
if (ctx->temp_count) if (ctx->temp_count)
write_sm4_dcl_temps(&tpf, ctx->temp_count); write_sm4_dcl_temps(&tpf, ctx->temp_count);
LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry)
{
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
if (var->is_uniform || var->is_input_semantic || var->is_output_semantic)
continue;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
continue;
if (var->indexable)
{
unsigned int id = var->regs[HLSL_REGSET_NUMERIC].id;
unsigned int size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4;
write_sm4_dcl_indexable_temp(&tpf, id, size, 4);
}
}
}
write_sm4_block(&tpf, &entry_func->body); write_sm4_block(&tpf, &entry_func->body);
write_sm4_ret(&tpf); write_sm4_ret(&tpf);