+ case VKD3DSIH_BRANCH: + { + const struct vkd3d_shader_src_param *src = ins->src, *merge; + + if (ins->src_count > 2) + { + assert(ins->src_count == 3); + shader_dump_instruction_flags(compiler, ins); + vkd3d_string_buffer_printf(buffer, " "); + shader_dump_src_param(compiler, &src[0]); + assert(src[1].reg.idx_count == 2); + shader_print_label_id(compiler, " ? ", src[1].reg.idx[0].offset); + shader_print_label_id(compiler, " : ", src[1].reg.idx[1].offset); + merge = &src[2]; + } + else + { + assert(ins->src_count); + assert(src[0].reg.idx_count == 1); + shader_print_label_id(compiler, " ", src[0].reg.idx[0].offset); + merge = (ins->src_count > 1) ? &src[1] : NULL; + } + if (merge) + { + assert(merge->reg.idx_count >= 1 && merge->reg.idx_count <= 2); + shader_print_label_id(compiler, ", merge ", merge->reg.idx[0].offset); + if (merge->reg.idx_count > 1) + shader_print_label_id(compiler, ", continue ", merge->reg.idx[1].offset); + } + break; + }
Would it be terrible to output branch instructions like any other instruction? As it is, these would be the only non-DCL instructions that need special handling, and I'm not sure that something along the lines of "branch_nz r0.x, l0, l1, l2, l3" is really much worse than something like "branch r0.x ? l0 : l1, merge l2, continue l3".
Is it necessary to flatten everything in a single commit? Or could we e.g. first do IF/ELSE/ENDIF, then LOOP/ENDLOOP/BREAK/CONTINUE, SWITCH/ENDSWITCH/CASE/etc.?
Incidentally, still not a fan of assert() in library code.