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 first_write, last_read;
} *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,
@ -3718,6 +3722,17 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx,
return;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read)
{
if (var->indexable)
{
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 x%u[].\n", var->name, var->regs[HLSL_REGSET_NUMERIC].id);
}
else
{
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator,
var->first_write, var->last_read, var->data_type);
@ -3726,6 +3741,7 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx,
var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read);
}
}
}
static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx,
struct hlsl_block *block, struct register_allocator *allocator)

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);
assert(hlsl_reg.allocated);
reg->type = VKD3DSPR_TEMP;
reg->type = deref->var->indexable ? VKD3DSPR_IDXTEMP : VKD3DSPR_TEMP;
reg->dimension = VSIR_DIMENSION_VEC4;
reg->idx[0].offset = hlsl_reg.id;
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);
}
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])
{
struct sm4_instruction instr =
@ -5616,6 +5630,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
struct extern_resource *extern_resources;
unsigned int extern_resources_count, i;
const struct hlsl_buffer *cbuffer;
const struct hlsl_scope *scope;
const struct hlsl_ir_var *var;
size_t token_count_position;
struct tpf_writer tpf;
@ -5670,6 +5685,25 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
if (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_ret(&tpf);