ac/nir: Use es_accepted variable after culling.
authorTimur Kristóf <timur.kristof@gmail.com>
Thu, 15 Jul 2021 12:20:59 +0000 (14:20 +0200)
committerMarge Bot <eric+marge@anholt.net>
Mon, 2 Aug 2021 11:38:25 +0000 (11:38 +0000)
This avoids re-calculating the exec mask for ES vertices,
and makes it unnecessary to count the number of vertices left.

Fossil DB results on Sienna Cichlid (with NGGC on):

Totals from 58239 (45.27% of 128647) affected shaders:
CodeSize: 166521108 -> 166356072 (-0.10%); split: -0.10%, +0.00%
Instrs: 31961308 -> 31920041 (-0.13%); split: -0.13%, +0.00%
Latency: 138820463 -> 138815742 (-0.00%); split: -0.04%, +0.04%
InvThroughput: 22460177 -> 22459553 (-0.00%); split: -0.00%, +0.00%
SClause: 753744 -> 753746 (+0.00%)
Copies: 3093140 -> 3226647 (+4.32%); split: -0.03%, +4.34%

No Fossil DB changes with NGGC off.

Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11908>

src/amd/common/ac_nir_lower_ngg.c

index c15fac1..626313f 100644 (file)
@@ -610,7 +610,8 @@ compact_vertices_after_culling(nir_builder *b,
    nir_scoped_barrier(b, .execution_scope=NIR_SCOPE_WORKGROUP, .memory_scope=NIR_SCOPE_WORKGROUP,
                          .memory_semantics=NIR_MEMORY_ACQ_REL, .memory_modes=nir_var_mem_shared);
 
-   nir_if *if_packed_es_thread = nir_push_if(b, nir_ilt(b, invocation_index, num_live_vertices_in_workgroup));
+   nir_ssa_def *es_survived = nir_ilt(b, invocation_index, num_live_vertices_in_workgroup);
+   nir_if *if_packed_es_thread = nir_push_if(b, es_survived);
    {
       /* Read position from the current ES thread's LDS space (written by the exported vertex's ES thread) */
       nir_ssa_def *exported_pos = nir_build_load_shared(b, 4, 32, es_vertex_lds_addr, .base = lds_es_pos_x, .align_mul = 4u);
@@ -639,6 +640,8 @@ compact_vertices_after_culling(nir_builder *b,
       nir_store_var(b, prim_exp_arg_var, prim_exp_arg, 0x1u);
    }
    nir_pop_if(b, if_gs_accepted);
+
+   nir_store_var(b, es_accepted_var, es_survived, 0x1u);
 }
 
 static void
@@ -922,7 +925,8 @@ add_deferred_attribute_culling(nir_builder *b, nir_cf_list *original_extracted_c
 
    b->cursor = nir_before_cf_list(&impl->body);
 
-   nir_if *if_es_thread = nir_push_if(b, nir_build_has_input_vertex_amd(b));
+   nir_ssa_def *es_thread = nir_build_has_input_vertex_amd(b);
+   nir_if *if_es_thread = nir_push_if(b, es_thread);
    {
       /* Initialize the position output variable to zeroes, in case not all VS/TES invocations store the output.
        * The spec doesn't require it, but we use (0, 0, 0, 1) because some games rely on that.
@@ -953,6 +957,8 @@ add_deferred_attribute_culling(nir_builder *b, nir_cf_list *original_extracted_c
    }
    nir_pop_if(b, if_es_thread);
 
+   nir_store_var(b, es_accepted_var, es_thread, 0x1u);
+
    /* Remove all non-position outputs, and put the position output into the variable. */
    nir_metadata_preserve(impl, nir_metadata_none);
    remove_culling_shader_outputs(b->shader, nogs_state, position_value_var);
@@ -1210,8 +1216,9 @@ ac_nir_lower_ngg_nogs(nir_shader *shader,
    }
 
    nir_intrinsic_instr *export_vertex_instr;
+   nir_ssa_def *es_thread = can_cull ? nir_load_var(b, es_accepted_var) : nir_build_has_input_vertex_amd(b);
 
-   nir_if *if_es_thread = nir_push_if(b, nir_build_has_input_vertex_amd(b));
+   nir_if *if_es_thread = nir_push_if(b, es_thread);
    {
       /* Run the actual shader */
       nir_cf_reinsert(&extracted, b->cursor);
@@ -1230,7 +1237,7 @@ ac_nir_lower_ngg_nogs(nir_shader *shader,
    if (!state.early_prim_export) {
       emit_ngg_nogs_prim_export(b, &state, nir_load_var(b, prim_exp_arg_var));
       if (state.export_prim_id && shader->info.stage == MESA_SHADER_VERTEX) {
-         if_es_thread = nir_push_if(b, nir_build_has_input_vertex_amd(b));
+         if_es_thread = nir_push_if(b, can_cull ? es_thread : nir_build_has_input_vertex_amd(b));
          emit_store_ngg_nogs_es_primitive_id(b);
          nir_pop_if(b, if_es_thread);
       }