TLDR: Run discard last. All other shaders in the pass before shaders with discard. Never put discard in shader if it doesn't need it! It slows down massively even if branched out!
Two level bitfield approach for sparse index. You can inner join these super efficiently. Fast empty space skipping (21845 elements per cache line at top level). Binary AND + tzcnt loop. Lower bit mask + popcnt for index calc. We already used this trick 12 years ago at Ubisoft...