+ if (options->can_cull) {
+ /* Replace uniforms. */
+ apply_reusable_variables(b, &state);
+
+ /* Remove the redundant position output. */
+ remove_extra_pos_outputs(shader, &state);
+
+ /* After looking at the performance in apps eg. Doom Eternal, and The Witcher 3,
+ * it seems that it's best to put the position export always at the end, and
+ * then let ACO schedule it up (slightly) only when early prim export is used.
+ */
+ b->cursor = nir_before_instr(&export_vertex_instr->instr);
+
+ nir_ssa_def *pos_val = nir_load_var(b, state.position_value_var);
+ nir_io_semantics io_sem = { .location = VARYING_SLOT_POS, .num_slots = 1 };
+ nir_store_output(b, pos_val, nir_imm_int(b, 0), .base = state.position_store_base,
+ .component = 0, .io_semantics = io_sem, .src_type = nir_type_float32);
+ }
+
+ /* Gather outputs data and types */
+ b->cursor = nir_after_cf_list(&if_es_thread->then_list);
+ ngg_nogs_gather_outputs(b, &if_es_thread->then_list, &state);
+
+ if (state.has_user_edgeflags)
+ ngg_nogs_store_edgeflag_to_lds(b, &state);
+