diff --git a/src/compiler/nir/nir_lower_gs_intrinsics.c b/src/compiler/nir/nir_lower_gs_intrinsics.c index 81044e9ae2c..171b37e6eb4 100644 --- a/src/compiler/nir/nir_lower_gs_intrinsics.c +++ b/src/compiler/nir/nir_lower_gs_intrinsics.c @@ -246,9 +246,11 @@ rewrite_intrinsics(nir_block *block, struct state *state) nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); switch (intrin->intrinsic) { case nir_intrinsic_emit_vertex: + case nir_intrinsic_emit_vertex_with_counter: rewrite_emit_vertex(intrin, state); break; case nir_intrinsic_end_primitive: + case nir_intrinsic_end_primitive_with_counter: rewrite_end_primitive(intrin, state); break; default: @@ -307,6 +309,48 @@ append_set_vertex_and_primitive_count(nir_block *end_block, struct state *state) } } +/** + * Check to see if there are any blocks that need set_vertex_and_primitive_count + * + * If every block that could need the set_vertex_and_primitive_count intrinsic + * already has one, there is nothing for this pass to do. + */ +static bool +a_block_needs_set_vertex_and_primitive_count(nir_block *end_block, bool per_stream) +{ + set_foreach(end_block->predecessors, entry) { + nir_block *pred = (nir_block *) entry->key; + + + for (unsigned stream = 0; stream < NIR_MAX_XFB_STREAMS; ++stream) { + /* When it's not per-stream, we only need to write one variable. */ + if (!per_stream && stream != 0) + continue; + + bool found = false; + + nir_foreach_instr_reverse(instr, pred) { + if (instr->type != nir_instr_type_intrinsic) + continue; + + const nir_intrinsic_instr *const intrin = + nir_instr_as_intrinsic(instr); + + if (intrin->intrinsic == nir_intrinsic_set_vertex_and_primitive_count && + intrin->const_index[0] == stream) { + found = true; + break; + } + } + + if (!found) + return true; + } + } + + return false; +} + bool nir_lower_gs_intrinsics(nir_shader *shader, nir_lower_gs_intrinsics_flags options) { @@ -327,6 +371,9 @@ nir_lower_gs_intrinsics(nir_shader *shader, nir_lower_gs_intrinsics_flags option nir_function_impl *impl = nir_shader_get_entrypoint(shader); assert(impl); + if (!a_block_needs_set_vertex_and_primitive_count(impl->end_block, per_stream)) + return false; + nir_builder b; nir_builder_init(&b, impl); state.builder = &b;