From 6dc9ff1bd8c2d03ba2a658f944323d31171fc70a Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Thu, 31 Jul 2025 18:08:07 -0400 Subject: [PATCH] vkd3d-shader/ir: Use iterators in vsir_program_ensure_diffuse(). The change in vsir_program_iterator_next() is necessary to allow us to introduce instructions before the iterator using: vsir_program_iterator_prev(&it); vsir_program_iterator_inset_after(&it, n); vsir_program_iterator_next(&it); This since (it.idx == SIZE_MAX) is equivalent to the iterator being before the beginning of the list. --- libs/vkd3d-shader/ir.c | 10 +++++----- libs/vkd3d-shader/vkd3d_shader_private.h | 11 ++++++++++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 9d93936ac..f51df529d 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1814,6 +1814,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); static const struct vkd3d_shader_location no_loc; struct vkd3d_shader_instruction *ins; unsigned int i; @@ -1825,17 +1826,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra /* Write the instruction after all LABEL, DCL, and NOP instructions. * We need to skip NOP instructions because they might result from removed * DCLs, and there could still be DCLs after NOPs. */ - for (i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &program->instructions.elements[i]; - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) break; } - if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) + vsir_program_iterator_prev(&it); + if (!vsir_program_iterator_insert_after(&it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i]; + ins = vsir_program_iterator_next(&it); vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 5eb44b297..4be52de6b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1463,12 +1463,21 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( struct vsir_program_iterator *iterator) { - if (iterator->idx < iterator->array->count) + if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX) ++iterator->idx; return vsir_program_iterator_current(iterator); } +static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( + struct vsir_program_iterator *iterator) +{ + if (iterator->idx != SIZE_MAX) + --iterator->idx; + + return vsir_program_iterator_current(iterator); +} + /* When insertion takes place, argument `it' is updated to point to the same * instruction as before the insertion, but all other iterators and pointers * to the same container are invalidated and cannot be used any more. */