From 20e183247b7cd2ba19048f6a1b712c94b88dd548 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 5 Sep 2025 09:30:19 +1000 Subject: [PATCH] Updated vkd3d to 0096ae43e114e5bab8a6ff1093b509588a49e38a. --- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 375 ++++++++++++-------- libs/vkd3d/libs/vkd3d-shader/ir.c | 51 +-- libs/vkd3d/libs/vkd3d-shader/spirv.c | 18 +- libs/vkd3d/libs/vkd3d-shader/tpf.c | 2 + 6 files changed, 268 insertions(+), 187 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index df1333f55a6..a3e8ccc1e2a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -233,6 +233,9 @@ struct hlsl_type /* Offset where the type's description starts in the output bytecode, in bytes. */ size_t bytecode_offset; + /* Offset where the type's packed description starts in the output bytecode, in bytes. */ + size_t packed_bytecode_offset; + bool is_typedef; uint32_t is_minimum_precision : 1; @@ -1184,8 +1187,8 @@ struct hlsl_ctx } constant_defs; /* 'c' registers where the constants expected by SM2 sincos are stored. */ struct hlsl_reg d3dsincosconst1, d3dsincosconst2; - /* Number of allocated SSA and temp IDs, used in translation to vsir. */ - unsigned int ssa_count, temp_count; + /* Number of allocated registers, used in translation to vsir. */ + unsigned int ssa_count, temp_count, indexable_temp_count; /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 41aeb7f22f6..d83ad9fe7d8 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -8115,7 +8115,7 @@ resource_format: { uint32_t modifiers = $1; - if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, false, &@1))) + if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 5d413c43374..9a682a7550d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -175,12 +175,29 @@ static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) } } +static unsigned int struct_field_get_packed_offset(const struct hlsl_type *record, unsigned int field_idx) +{ + unsigned int offset = 0; + + VKD3D_ASSERT(record->class == HLSL_CLASS_STRUCT); + VKD3D_ASSERT(field_idx < record->e.record.field_count); + + for (unsigned int i = 0; i < field_idx; ++i) + { + struct hlsl_struct_field *field = &record->e.record.fields[i]; + offset = align(offset, hlsl_type_get_packed_alignment(field->type)) + hlsl_type_get_packed_size(field->type); + } + + return align(offset, hlsl_type_get_packed_alignment(record->e.record.fields[field_idx].type)); +} + + static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, struct hlsl_type *type, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *idx_offset = NULL, *c; - unsigned int field_idx, offset, size, i; + unsigned int field_idx, offset, size; switch (type->class) { @@ -203,15 +220,7 @@ static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hls case HLSL_CLASS_STRUCT: field_idx = hlsl_ir_constant(idx)->value.u[0].u; - for (i = 0, offset = 0; i < field_idx; ++i) - { - struct hlsl_struct_field *field = &type->e.record.fields[i]; - - offset = align(offset, hlsl_type_get_packed_alignment(field->type)) - + hlsl_type_get_packed_size(field->type); - } - - offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); + offset = struct_field_get_packed_offset(type, field_idx); idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); break; @@ -5912,7 +5921,6 @@ struct register_allocator { uint32_t reg; unsigned int writemask; - unsigned int first_write, last_read; /* Two allocations with different mode can't share the same register. */ int mode; @@ -5922,11 +5930,7 @@ struct register_allocator } *allocations; size_t count, capacity; - /* Indexable temps are allocated separately and always keep their index regardless of their - * lifetime. */ - uint32_t indexable_count; - - /* Total number of registers allocated so far. Used to declare sm4 temp count. */ + /* Total number of registers allocated so far. */ uint32_t reg_count; /* Special flag so allocations that can share registers prioritize those @@ -5938,7 +5942,7 @@ struct register_allocator }; static unsigned int get_available_writemask(const struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, uint32_t reg_idx, int mode, bool vip) + uint32_t reg_idx, int mode, bool vip) { unsigned int writemask = VKD3DSP_WRITEMASK_ALL; size_t i; @@ -5947,12 +5951,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all { const struct allocation *allocation = &allocator->allocations[i]; - /* We do not overlap if first write == last read: - * this is the case where we are allocating the result of that - * expression, e.g. "add r0, r0, r1". */ - - if (allocation->reg == reg_idx - && first_write < allocation->last_read && last_read > allocation->first_write) + if (allocation->reg == reg_idx) { writemask &= ~allocation->writemask; if (allocation->mode != mode) @@ -5969,7 +5968,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all } static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *allocator, uint32_t reg_idx, - unsigned int writemask, unsigned int first_write, unsigned int last_read, int mode, bool vip) + unsigned int writemask, int mode, bool vip) { struct allocation *allocation; @@ -5980,8 +5979,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a allocation = &allocator->allocations[allocator->count++]; allocation->reg = reg_idx; allocation->writemask = writemask; - allocation->first_write = first_write; - allocation->last_read = last_read; allocation->mode = mode; allocation->vip = vip; @@ -6000,8 +5997,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a * 'vip' can be used so that no new allocations can be made in the given register * unless they are 'vip' as well. */ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, unsigned int reg_size, - unsigned int component_count, int mode, bool force_align, bool vip) + unsigned int reg_size, unsigned int component_count, int mode, bool force_align, bool vip) { struct hlsl_reg ret = {.allocation_size = 1, .allocated = true}; unsigned int required_size = force_align ? 4 : reg_size; @@ -6014,8 +6010,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a { for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx) { - unsigned int available_writemask = get_available_writemask(allocator, - first_write, last_read, reg_idx, mode, vip); + unsigned int available_writemask = get_available_writemask(allocator, reg_idx, mode, vip); if (vkd3d_popcount(available_writemask) >= pref) { @@ -6027,7 +6022,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a ret.writemask = hlsl_combine_writemasks(writemask, vkd3d_write_mask_from_component_count(component_count)); - record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx, writemask, mode, vip); return ret; } } @@ -6037,39 +6032,12 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a ret.id = allocator->reg_count; ret.writemask = vkd3d_write_mask_from_component_count(component_count); record_allocation(ctx, allocator, allocator->reg_count, - vkd3d_write_mask_from_component_count(reg_size), first_write, last_read, mode, vip); - return ret; -} - -/* Allocate a register with writemask, while reserving reg_writemask. */ -static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, - struct register_allocator *allocator, unsigned int first_write, unsigned int last_read, - uint32_t reg_writemask, uint32_t writemask, int mode, bool vip) -{ - struct hlsl_reg ret = {0}; - uint32_t reg_idx; - - VKD3D_ASSERT((reg_writemask & writemask) == writemask); - - for (reg_idx = 0;; ++reg_idx) - { - if ((get_available_writemask(allocator, first_write, last_read, - reg_idx, mode, vip) & reg_writemask) == reg_writemask) - break; - } - - record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip); - - ret.type = VKD3DSPR_TEMP; - ret.id = reg_idx; - ret.allocation_size = 1; - ret.writemask = writemask; - ret.allocated = true; + vkd3d_write_mask_from_component_count(reg_size), mode, vip); return ret; } -static bool is_range_available(const struct register_allocator *allocator, unsigned int first_write, - unsigned int last_read, uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) +static bool is_range_available(const struct register_allocator *allocator, + uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) { unsigned int last_reg_mask = (1u << (reg_size % 4)) - 1; unsigned int writemask; @@ -6077,18 +6045,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig for (i = 0; i < (reg_size / 4); ++i) { - writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + i, mode, vip); + writemask = get_available_writemask(allocator, reg_idx + i, mode, vip); if (writemask != VKD3DSP_WRITEMASK_ALL) return false; } - writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + (reg_size / 4), mode, vip); + writemask = get_available_writemask(allocator, reg_idx + (reg_size / 4), mode, vip); if ((writemask & last_reg_mask) != last_reg_mask) return false; return true; } -static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, unsigned int reg_size, int mode, bool vip) +static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, + struct register_allocator *allocator, unsigned int reg_size, int mode, bool vip) { struct hlsl_reg ret = {0}; uint32_t reg_idx; @@ -6096,15 +6064,14 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo for (reg_idx = 0;; ++reg_idx) { - if (is_range_available(allocator, first_write, last_read, reg_idx, reg_size, mode, vip)) + if (is_range_available(allocator, reg_idx, reg_size, mode, vip)) break; } for (i = 0; i < reg_size / 4; ++i) - record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, mode, vip); if (reg_size % 4) - record_allocation(ctx, allocator, reg_idx + (reg_size / 4), - (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, mode, vip); ret.type = allocator->type; ret.id = reg_idx; @@ -6113,22 +6080,17 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo return ret; } -static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) +static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, + struct register_allocator *allocator, const struct hlsl_type *type) { unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; - struct hlsl_reg ret; /* FIXME: We could potentially pack structs or arrays more efficiently... */ if (type->class <= HLSL_CLASS_VECTOR) - ret = allocate_register(ctx, allocator, first_write, last_read, - type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); + return allocate_register(ctx, allocator, type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); else - ret = allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); - if (allocator->type == VKD3DSPR_TEMP) - ctx->temp_count = max(ctx->temp_count, ret.id + ret.allocation_size); - return ret; + return allocate_range(ctx, allocator, reg_size, 0, false); } static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) @@ -6293,10 +6255,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) } } -static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - struct hlsl_ir_node *instr, struct register_allocator *allocator) +static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr) { - unsigned int reg_writemask = 0, dst_writemask = 0; + unsigned int dst_writemask = 0; bool is_per_component = false; if (instr->reg.allocated || !instr->last_read) @@ -6308,12 +6269,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, { case HLSL_OP1_COS_REDUCED: dst_writemask = VKD3DSP_WRITEMASK_0; - reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_0; break; case HLSL_OP1_SIN_REDUCED: dst_writemask = VKD3DSP_WRITEMASK_1; - reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; break; case HLSL_OP1_EXP2: @@ -6335,11 +6294,13 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); - if (reg_writemask) + if (dst_writemask) { - instr->reg = allocate_register_with_masks(ctx, allocator, - instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); - ctx->temp_count = max(ctx->temp_count, instr->reg.id + 1); + instr->reg.writemask = dst_writemask; + instr->reg.allocation_size = 1; + instr->reg.allocated = true; + instr->reg.type = VKD3DSPR_TEMP; + instr->reg.id = ctx->temp_count++; } else if (is_per_component) { @@ -6348,8 +6309,6 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, instr->reg.allocated = true; instr->reg.type = VKD3DSPR_TEMP; instr->reg.id = ctx->temp_count++; - - record_allocation(ctx, allocator, ctx->temp_count - 1, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); } else { @@ -6360,12 +6319,11 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, instr->reg.id = ctx->ssa_count++; } - TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, - debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); + TRACE("Allocated anonymous expression @%u to %s.\n", instr->index, + debug_register(instr->reg, instr->data_type)); } -static void allocate_variable_temp_register(struct hlsl_ctx *ctx, - struct hlsl_ir_var *var, struct register_allocator *allocator) +static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) { struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; @@ -6376,7 +6334,7 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, { if (var->indexable) { - reg->id = allocator->indexable_count++; + reg->id = ctx->indexable_temp_count++; reg->allocation_size = 1; reg->writemask = 0; reg->allocated = true; @@ -6392,19 +6350,15 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, reg->writemask = vkd3d_write_mask_from_component_count(var->data_type->e.numeric.dimx); reg->allocated = true; - for (unsigned int i = 0; i < reg->allocation_size; ++i) - record_allocation(ctx, allocator, ctx->temp_count + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); - ctx->temp_count += reg->allocation_size; - TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); + TRACE("Allocated %s to %s.\n", var->name, + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } } } -static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - struct hlsl_block *block, struct register_allocator *allocator) +static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block) { struct hlsl_ir_node *instr; @@ -6414,15 +6368,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) continue; - allocate_instr_temp_register(ctx, instr, allocator); + allocate_instr_temp_register(ctx, instr); switch (instr->type) { case HLSL_IR_IF: { struct hlsl_ir_if *iff = hlsl_ir_if(instr); - allocate_temp_registers_recurse(ctx, &iff->then_block, allocator); - allocate_temp_registers_recurse(ctx, &iff->else_block, allocator); + allocate_temp_registers_recurse(ctx, &iff->then_block); + allocate_temp_registers_recurse(ctx, &iff->else_block); break; } @@ -6431,21 +6385,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_load *load = hlsl_ir_load(instr); /* We need to at least allocate a variable for undefs. * FIXME: We should probably find a way to remove them instead. */ - allocate_variable_temp_register(ctx, load->src.var, allocator); + allocate_variable_temp_register(ctx, load->src.var); break; } case HLSL_IR_LOOP: { struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - allocate_temp_registers_recurse(ctx, &loop->body, allocator); + allocate_temp_registers_recurse(ctx, &loop->body); break; } case HLSL_IR_STORE: { struct hlsl_ir_store *store = hlsl_ir_store(instr); - allocate_variable_temp_register(ctx, store->lhs.var, allocator); + allocate_variable_temp_register(ctx, store->lhs.var); break; } @@ -6456,7 +6410,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) { - allocate_temp_registers_recurse(ctx, &c->body, allocator); + allocate_temp_registers_recurse(ctx, &c->body); } break; } @@ -6580,7 +6534,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, break; } - constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); + constant->reg = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); for (unsigned int x = 0, i = 0; x < 4; ++x) @@ -6677,14 +6631,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl { type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); - ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); + ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); - ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); + ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); @@ -6721,15 +6675,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo { if (i < bind_count) { - if (get_available_writemask(&allocator_used, 1, UINT_MAX, - reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) + if (get_available_writemask(&allocator_used, reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Overlapping register() reservations on 'c%u'.", reg_idx + i); } - record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); + record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); } - record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); + record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); } var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; @@ -6753,7 +6706,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo if (!var->regs[HLSL_REGSET_NUMERIC].allocated) { - var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); + var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, alloc_size, 0, false); TRACE("Allocated %s to %s.\n", var->name, debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } @@ -6772,10 +6725,11 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo * does not handle constants. */ static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) { - struct register_allocator allocator = {.type = VKD3DSPR_TEMP}; struct hlsl_scope *scope; struct hlsl_ir_var *var; + ctx->indexable_temp_count = 0; + /* Reset variable temp register allocations. */ LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { @@ -6793,16 +6747,13 @@ static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *bod { if (var->is_output_semantic) { - record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, - var->first_write, UINT_MAX, 0, false); ctx->temp_count = 1; break; } } } - allocate_temp_registers_recurse(ctx, body, &allocator); - vkd3d_free(allocator.allocations); + allocate_temp_registers_recurse(ctx, body); } static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, @@ -6941,7 +6892,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if (special_interpolation) mode = VKD3DSIM_NONE; - var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, + var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, reg_size, component_count, mode, var->force_align, vip_allocation); TRACE("Allocated %s to %s (mode %d).\n", var->name, @@ -9763,8 +9714,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP3_CMP: - if (!hlsl_type_is_floating_point(type)) - goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); break; @@ -11735,6 +11684,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, const struct vkd3d_shader_version *version = &program->shader_version; const struct hlsl_ir_node *sample_index = load->sample_index.node; const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *byte_offset = load->byte_offset.node; const struct hlsl_ir_node *coords = load->coords.node; unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; const struct hlsl_deref *resource = &load->resource; @@ -11742,20 +11692,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim = load->sampling_dim; bool tgsm = load->resource.var->is_tgsm; struct vkd3d_shader_instruction *ins; + bool multisampled, raw, structured; enum vkd3d_shader_opcode opcode; - bool multisampled, raw; VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); - if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) - { - hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); - return false; - } - multisampled = resource_type->class == HLSL_CLASS_TEXTURE && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); + structured = resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; if (!tgsm) { @@ -11766,15 +11711,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); return false; } + VKD3D_ASSERT(!(structured && multisampled)); - if (uav) + if (structured) + opcode = VSIR_OP_LD_STRUCTURED; + else if (uav) opcode = VSIR_OP_LD_UAV_TYPED; else if (raw) opcode = VSIR_OP_LD_RAW; else opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD; - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, + &instr->loc, opcode, 1, 2 + multisampled + structured))) return false; if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) @@ -11802,10 +11751,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, coords_writemask); if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, - &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc)) + &ins->src[structured ? 2 : 1], resource, ins->dst[0].write_mask, &instr->loc)) return false; - if (multisampled) + if (structured) + { + VKD3D_ASSERT(byte_offset); + vsir_src_from_hlsl_node(&ins->src[1], ctx, byte_offset, VKD3DSP_WRITEMASK_ALL); + } + else if (multisampled) { if (sample_index->type == HLSL_IR_CONSTANT) vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, @@ -12889,6 +12843,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, { switch (component_type->sampler_dim) { + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + opcode = VSIR_OP_DCL_RESOURCE_STRUCTURED; + break; case HLSL_SAMPLER_DIM_RAW_BUFFER: opcode = VSIR_OP_DCL_RESOURCE_RAW; break; @@ -12944,7 +12901,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) { ins->structured = true; - ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; + ins->resource_stride = hlsl_type_get_packed_size(component_type->e.resource.format); ins->declaration.structured_resource.byte_stride = ins->resource_stride; } else @@ -13214,14 +13171,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) { + bool structured = type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + switch (type->class) { case HLSL_CLASS_SAMPLER: return D3D_SIT_SAMPLER; case HLSL_CLASS_TEXTURE: - return D3D_SIT_TEXTURE; + return structured ? D3D_SIT_STRUCTURED : D3D_SIT_TEXTURE; case HLSL_CLASS_UAV: - return D3D_SIT_UAV_RWTYPED; + return structured ? D3D_SIT_UAV_RWSTRUCTURED : D3D_SIT_UAV_RWTYPED; default: break; } @@ -13297,7 +13256,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) vkd3d_unreachable(); } -static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) +static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + struct hlsl_type *type, bool structured) { const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type); const char *name = array_type->name ? array_type->name : ""; @@ -13306,7 +13266,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b size_t name_offset = 0; size_t i; - if (type->bytecode_offset) + if (!structured && type->bytecode_offset) + return; + + if (structured && type->packed_bytecode_offset) return; if (profile->major_version >= 5) @@ -13328,7 +13291,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b continue; field->name_bytecode_offset = put_string(buffer, field->name); - write_sm4_type(ctx, buffer, field->type); + write_sm4_type(ctx, buffer, field->type, structured); ++field_count; } @@ -13337,15 +13300,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b for (i = 0; i < array_type->e.record.field_count; ++i) { struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + unsigned int field_type_offset, offset; if (!field->type->reg_size[HLSL_REGSET_NUMERIC]) continue; put_u32(buffer, field->name_bytecode_offset); - put_u32(buffer, field->type->bytecode_offset); - put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float)); + + if (!structured) + field_type_offset = field->type->bytecode_offset; + else + field_type_offset = field->type->packed_bytecode_offset; + put_u32(buffer, field_type_offset); + + if (!structured) + offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float); + else + offset = struct_field_get_packed_offset(array_type, i); + put_u32(buffer, offset); } - type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); + if (!structured) + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); + else + type->packed_bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); put_u32(buffer, vkd3d_make_u32(array_size, field_count)); put_u32(buffer, fields_offset); @@ -13353,7 +13330,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b else { VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC); - type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); + if (!structured) + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); + else + type->packed_bytecode_offset = put_u32(buffer, + vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx)); put_u32(buffer, vkd3d_make_u32(array_size, 0)); put_u32(buffer, 1); @@ -13372,9 +13353,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef) { uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t); - size_t cbuffers_offset, resources_offset, creator_offset, string_offset; - unsigned int cbuffer_count = 0, extern_resources_count, i, j; + size_t buffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; + unsigned int buffer_count = 0, extern_resources_count, i, j; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; struct extern_resource *extern_resources; @@ -13396,10 +13377,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) - ++cbuffer_count; + ++buffer_count; + } + + for (i = 0; i < extern_resources_count; ++i) + { + const struct extern_resource *resource = &extern_resources[i]; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + ++buffer_count; } - put_u32(&buffer, cbuffer_count); + put_u32(&buffer, buffer_count); cbuffer_position = put_u32(&buffer, 0); put_u32(&buffer, extern_resources_count); resource_position = put_u32(&buffer, 0); @@ -13440,12 +13431,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, sm4_resource_type(resource->component_type)); if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) { + bool structured = resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx; put_u32(&buffer, sm4_data_type(resource->component_type)); put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); - put_u32(&buffer, ~0u); /* FIXME: multisample count */ - flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; + + if (structured) + put_u32(&buffer, hlsl_type_get_packed_size(resource->component_type->e.resource.format)); + else + put_u32(&buffer, ~0u); /* FIXME: multisample count */ + + if (!structured) + flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } else { @@ -13474,8 +13472,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd /* Buffers. */ - cbuffers_offset = bytecode_align(&buffer); - set_u32(&buffer, cbuffer_position, cbuffers_offset); + buffers_offset = bytecode_align(&buffer); + set_u32(&buffer, cbuffer_position, buffers_offset); LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { unsigned int var_count = 0; @@ -13497,6 +13495,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER); } + for (i = 0; i < extern_resources_count; ++i) + { + const struct extern_resource *resource = &extern_resources[i]; + struct hlsl_type *resource_type; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + resource_type = resource->component_type->e.resource.format; + + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, 1); /* var count */ + put_u32(&buffer, 0); /* variable offset */ + put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); /* size */ + put_u32(&buffer, 0); /* FIXME: flags */ + put_u32(&buffer, D3D_CT_RESOURCE_BIND_INFO); + } + i = 0; LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { @@ -13504,7 +13520,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd continue; string_offset = put_string(&buffer, cbuffer->name); - set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); + set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); + } + + for (j = 0; j < extern_resources_count; ++j) + { + const struct extern_resource *resource = &extern_resources[j]; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + string_offset = put_string(&buffer, resource->name); + set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); } i = 0; @@ -13515,7 +13542,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd if (!cbuffer->reg.allocated) continue; - set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); + set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -13554,7 +13581,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd string_offset = put_string(&buffer, var->name); set_u32(&buffer, var_offset, string_offset); - write_sm4_type(ctx, &buffer, var->data_type); + write_sm4_type(ctx, &buffer, var->data_type, false); set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); if (var->default_values) @@ -13597,6 +13624,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd } } + for (j = 0; j < extern_resources_count; ++j) + { + const struct extern_resource *resource = &extern_resources[j]; + struct hlsl_type *resource_type; + size_t vars_start; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + resource_type = resource->component_type->e.resource.format; + + vars_start = bytecode_align(&buffer); + + set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); + + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, 0); /* offset */ + put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); + put_u32(&buffer, D3D_SVF_USED); + put_u32(&buffer, 0); /* type */ + put_u32(&buffer, 0); /* default value */ + + if (profile->major_version >= 5) + { + put_u32(&buffer, ~0u); /* texture start */ + put_u32(&buffer, 0); /* texture count */ + put_u32(&buffer, ~0u); /* sampler start */ + put_u32(&buffer, 0); /* sampler count */ + } + + string_offset = put_string(&buffer, "$Element"); + set_u32(&buffer, vars_start, string_offset); + write_sm4_type(ctx, &buffer, resource_type, true); + set_u32(&buffer, vars_start + 4 * sizeof(uint32_t), resource_type->packed_bytecode_offset); + } + creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); set_u32(&buffer, creator_position, creator_offset); diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index b120801d5f9..3e06e887096 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -9758,9 +9758,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a SSA register: " - "it has already been seen with data type %#x at instruction %zu.", - reg->data_type, data->data_type, data->first_seen); + "Invalid data type \"%s\" (%#x) for SSA register %u: " + "it has already been seen with data type \"%s\" (%#x) at instruction %zu.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type, reg->idx[0].offset, + vsir_data_type_get_name(data->data_type, ""), data->data_type, data->first_seen); } } @@ -10008,7 +10009,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, default: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); + "Invalid data type \"%s\" (%#x) for destination with saturate modifier.", + vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); break; } @@ -10027,7 +10029,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, case 15: if (dst->reg.data_type != VSIR_DATA_F32) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for destination with shift.", dst->reg.data_type); + "Invalid data type \"%s\" (%#x) for destination with shift.", + vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); break; default: @@ -10165,7 +10168,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, { if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, - "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type); + "Source has invalid modifier %#x for data type \"%s\" (%#x).", + src->modifiers, vsir_data_type_get_name(src->reg.data_type, ""), src->reg.data_type); } switch (src->reg.type) @@ -10817,7 +10821,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, static void vsir_validate_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { - enum vsir_data_type dst_data_type; + enum vsir_data_type dst_data_type, src_data_type; unsigned int i; if (instruction->dst_count < 1) @@ -10830,16 +10834,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, if (!types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for elementwise operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for elementwise operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); for (i = 0; i < instruction->src_count; ++i) { - if (instruction->src[i].reg.data_type != dst_data_type) + if ((src_data_type = instruction->src[i].reg.data_type) != dst_data_type) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Data type %#x for operand %u doesn't match the destination data type %#x " + "Data type \"%s\" (%#x) for operand %u doesn't match the destination data type \"%s\" (%#x) " "for elementwise operation \"%s\" (%#x).", - instruction->src[i].reg.data_type, i, dst_data_type, + vsir_data_type_get_name(src_data_type, ""), src_data_type, i, + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } @@ -10896,7 +10902,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context static void vsir_validate_comparison_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { - enum vsir_data_type dst_data_type, src_data_type; + enum vsir_data_type dst_data_type, src_data_type, data_type; unsigned int i; if (instruction->dst_count < 1) @@ -10906,8 +10912,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for result of comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); if (instruction->src_count == 0) return; @@ -10919,16 +10926,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (!types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for comparison operation \"%s\" (%#x).", - src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); for (i = 1; i < instruction->src_count; ++i) { - if (instruction->src[i].reg.data_type != src_data_type) + if ((data_type = instruction->src[i].reg.data_type) != src_data_type) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Data type %#x for operand %u doesn't match the first operands data type %#x " - "for comparison operation \"%s\" (%#x).", - instruction->src[i].reg.data_type, i, src_data_type, + "Data type \"%s\" (%#x) for operand %u doesn't match the first " + "operands data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(data_type, ""), data_type, i, + vsir_data_type_get_name(src_data_type, ""), src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 058a631f25e..9cd9aafb587 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -4145,10 +4145,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); if (reg_index->offset) { - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, - addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, + spirv_compiler_get_constant_uint(compiler, reg_index->offset)); } + return addr_id; } @@ -4294,7 +4295,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) { index_ids[0] = compiler->descriptor_offsets_member_id; @@ -4492,8 +4493,9 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, data_type == VSIR_DATA_U64 ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) @@ -4508,7 +4510,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -4521,7 +4524,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, component_count); false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index e2123656557..24a28886b00 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -4225,6 +4225,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_DCL: case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: case VSIR_OP_DCL_UAV_RAW: case VSIR_OP_DCL_UAV_STRUCTURED: case VSIR_OP_DCL_UAV_TYPED: @@ -4308,6 +4309,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_LD: case VSIR_OP_LD2DMS: case VSIR_OP_LD_RAW: + case VSIR_OP_LD_STRUCTURED: case VSIR_OP_LD_UAV_TYPED: case VSIR_OP_LOG: case VSIR_OP_LOOP: -- 2.51.0