From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 5 ++-- libs/vkd3d-shader/hlsl.h | 6 ++++- libs/vkd3d-shader/hlsl_codegen.c | 40 +++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index d2a4666a..18141ae8 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1809,12 +1809,13 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
for (i = 0; i < ctx->constant_defs.count; ++i) { + const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i]; uint32_t token = D3DSIO_DEF; const struct sm1_dst_register reg = { .type = D3DSPR_CONST, .writemask = VKD3DSP_WRITEMASK_ALL, - .reg = i, + .reg = constant_reg->index, };
if (ctx->profile->major_version > 1) @@ -1823,7 +1824,7 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
write_sm1_dst_register(buffer, ®); for (x = 0; x < 4; ++x) - put_f32(buffer, ctx->constant_defs.values[i].f[x]); + put_f32(buffer, constant_reg->value.f[x]); } }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 28c7c691..8dedacc7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -806,7 +806,11 @@ struct hlsl_ctx * Only used for SM1 profiles. */ struct hlsl_constant_defs { - struct hlsl_vec4 *values; + struct hlsl_constant_register + { + uint32_t index; + struct hlsl_vec4 value; + } *regs; size_t count, size; } constant_defs; /* Number of temp. registers required for the shader to run, i.e. the largest temp register diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index ce673d1d..8927e291 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -3254,10 +3254,33 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, } }
+static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, float f) +{ + struct hlsl_constant_defs *defs = &ctx->constant_defs; + struct hlsl_constant_register *reg; + size_t i; + + for (i = 0; i < defs->count; ++i) + { + reg = &defs->regs[i]; + if (reg->index == (component_index / 4)) + { + reg->value.f[component_index % 4] = f; + return; + } + } + + if (!hlsl_array_reserve(ctx, (void **)&defs->regs, &defs->size, defs->count + 1, sizeof(*defs->regs))) + return; + reg = &defs->regs[defs->count++]; + memset(reg, 0, sizeof(*reg)); + reg->index = component_index / 4; + reg->value.f[component_index % 4] = f; +} + static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct register_allocator *allocator) { - struct hlsl_constant_defs *defs = &ctx->constant_defs; struct hlsl_ir_node *instr;
LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) @@ -3268,21 +3291,11 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); const struct hlsl_type *type = instr->data_type; - unsigned int x, i, end_reg; + unsigned int x, i;
constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type));
- if (!hlsl_array_reserve(ctx, (void **)&defs->values, &defs->size, - constant->reg.id + 1, sizeof(*defs->values))) - return; - end_reg = constant->reg.id + 1; - if (end_reg > defs->count) - { - memset(&defs->values[defs->count], 0, sizeof(*defs->values) * (end_reg - defs->count)); - defs->count = end_reg; - } - assert(type->class <= HLSL_CLASS_LAST_NUMERIC); assert(type->dimy == 1); assert(constant->reg.writemask); @@ -3322,7 +3335,8 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, default: vkd3d_unreachable(); } - defs->values[constant->reg.id].f[x] = f; + + record_constant(ctx, constant->reg.id * 4 + x, f); }
break;