On 7/1/22 16:24, Francisco Casas wrote:
+struct hlsl_ir_node *hlsl_new_offset_from_path_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_type *type, struct hlsl_ir_node *offset, struct hlsl_ir_node *idx, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *idx_offset = NULL; + struct hlsl_ir_constant *c; + + list_init(&block->instrs); + + switch (type->type) + { + case HLSL_CLASS_VECTOR: + { + idx_offset = idx; + break; + } + + case HLSL_CLASS_MATRIX: + { + if (!(c = hlsl_new_uint_constant(ctx, 4, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_ARRAY: + { + unsigned int size = hlsl_type_get_array_element_reg_size(type->e.array.type); + + if (!(c = hlsl_new_uint_constant(ctx, size, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, &c->node, idx))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + + break; + } + + case HLSL_CLASS_STRUCT: + { + unsigned int field_i = hlsl_ir_constant(idx)->value[0].u;
Erf, that is awkward. Well, it's a temporary measure, and avoiding it would probably be worse...
+ struct hlsl_struct_field *field = &type->e.record.fields[field_i]; + + if (!(c = hlsl_new_uint_constant(ctx, field->reg_offset, loc))) + return NULL; + list_add_tail(&block->instrs, &c->node.entry); + + idx_offset = &c->node; + + break; + } + + default: + { + assert(0); + return NULL; + } + } + + if (offset) + { + if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, offset, idx_offset))) + return NULL; + list_add_tail(&block->instrs, &idx_offset->entry); + } + + return idx_offset; +} +