diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index ef81f349..cdc0c184 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -2055,31 +2055,17 @@ static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_sh { VKD3D_ASSERT(id_idx < ARRAY_SIZE(reg->idx) - 1); - /* For a relative-addressed register index, move the id up a slot to separate it from the address, - * because rel_addr can be replaced with a constant offset in some cases. */ - if (reg->idx[id_idx].rel_addr) - { - reg->idx[id_idx + 1].rel_addr = NULL; - reg->idx[id_idx + 1].offset = reg->idx[id_idx].offset; - reg->idx[id_idx].offset -= register_index; - if (id_idx) - { - /* idx[id_idx] now contains the array index, which must be moved below the control point id. */ - struct vkd3d_shader_register_index tmp = reg->idx[id_idx]; - reg->idx[id_idx] = reg->idx[id_idx - 1]; - reg->idx[id_idx - 1] = tmp; - } - ++id_idx; - } - /* Otherwise we have no address for the arrayed register, so insert one. This happens e.g. where - * tessellation level registers are merged into an array because they're an array in SPIR-V. */ - else - { - ++id_idx; - memmove(®->idx[1], ®->idx[0], id_idx * sizeof(reg->idx[0])); - reg->idx[0].rel_addr = NULL; - reg->idx[0].offset = reg->idx[id_idx].offset - register_index; - } + /* Make room for the array index at the front of the array. */ + ++id_idx; + memmove(®->idx[1], ®->idx[0], id_idx * sizeof(reg->idx[0])); + + /* The array index inherits the register relative address, but is offsetted + * by the signature element register index. */ + reg->idx[0].rel_addr = reg->idx[id_idx].rel_addr; + reg->idx[0].offset = reg->idx[id_idx].offset - register_index; + reg->idx[id_idx].rel_addr = NULL; + + /* The signature index offset will be fixed in the caller. */ return id_idx; }