nir/passthrough_gs: Support edge flags with points
authorKonstantin Seurer <konstantin.seurer@gmail.com>
Thu, 21 Sep 2023 17:24:49 +0000 (19:24 +0200)
committerMarge Bot <emma+marge@anholt.net>
Wed, 4 Oct 2023 23:20:52 +0000 (23:20 +0000)
Fixes: 24535ff ("nir: handle edge flags in nir_create_passthrough_gs")
Reviewed-by: Antonino Maniscalco <antonino.maniscalco@collabora.com>
Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25335>

src/compiler/nir/nir.h
src/compiler/nir/nir_passthrough_gs.c
src/gallium/drivers/zink/zink_program.c

index e958bedc0ccb3d20b0f39dc45e10856f174f1da0..accb906dea4772fb1f82e9f943bc5ee0c34b478d 100644 (file)
@@ -5374,6 +5374,7 @@ nir_shader *nir_create_passthrough_tcs(const nir_shader_compiler_options *option
 nir_shader *nir_create_passthrough_gs(const nir_shader_compiler_options *options,
                                       const nir_shader *prev_stage,
                                       enum mesa_prim primitive_type,
+                                      enum mesa_prim output_primitive_type,
                                       bool emulate_edgeflags,
                                       bool force_line_strip_out);
 
index 65270d597e5ba54497d32de1c7fec6b5578f61fa..39eade79efb166b443ddd5d894d092044a9667b2 100644 (file)
@@ -121,20 +121,23 @@ nir_shader *
 nir_create_passthrough_gs(const nir_shader_compiler_options *options,
                           const nir_shader *prev_stage,
                           enum mesa_prim primitive_type,
+                          enum mesa_prim output_primitive_type,
                           bool emulate_edgeflags,
                           bool force_line_strip_out)
 {
    unsigned int vertices_out = vertices_for_prim(primitive_type);
    emulate_edgeflags = emulate_edgeflags && (prev_stage->info.outputs_written & VARYING_BIT_EDGE);
-   bool needs_closing = (force_line_strip_out || emulate_edgeflags) && vertices_out >= 3;
-   enum mesa_prim original_our_prim = gs_out_prim_for_topology(primitive_type);
+   enum mesa_prim original_our_prim = gs_out_prim_for_topology(output_primitive_type);
    nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY,
                                                   options,
                                                   "gs passthrough");
 
+   bool output_lines = force_line_strip_out || original_our_prim == MESA_PRIM_LINE_STRIP;
+   bool needs_closing = (force_line_strip_out || (emulate_edgeflags && output_lines)) && vertices_out >= 3;
+
    nir_shader *nir = b.shader;
    nir->info.gs.input_primitive = gs_in_prim_for_topology(primitive_type);
-   nir->info.gs.output_primitive = (force_line_strip_out || emulate_edgeflags) ? MESA_PRIM_LINE_STRIP : original_our_prim;
+   nir->info.gs.output_primitive = force_line_strip_out ? MESA_PRIM_LINE_STRIP : original_our_prim;
    nir->info.gs.vertices_in = u_vertices_per_prim(primitive_type);
    nir->info.gs.vertices_out = needs_closing ? vertices_out + 1 : vertices_out;
    nir->info.gs.invocations = 1;
@@ -146,8 +149,7 @@ nir_create_passthrough_gs(const nir_shader_compiler_options *options,
       nir->xfb_info = mem_dup(prev_stage->xfb_info, nir_xfb_info_size(prev_stage->xfb_info->output_count));
    }
 
-   bool handle_flat = nir->info.gs.output_primitive == MESA_PRIM_LINE_STRIP &&
-                      nir->info.gs.output_primitive != original_our_prim;
+   bool handle_flat = output_lines && nir->info.gs.output_primitive != gs_out_prim_for_topology(primitive_type);
    nir_variable *in_vars[VARYING_SLOT_MAX * 4];
    nir_variable *out_vars[VARYING_SLOT_MAX * 4];
    unsigned num_inputs = 0, num_outputs = 0;
@@ -241,13 +243,24 @@ nir_create_passthrough_gs(const nir_shader_compiler_options *options,
          copy_vars(&b, nir_build_deref_var(&b, out_vars[oj]), value);
          ++oj;
       }
+
+      if (emulate_edgeflags && !output_lines) {
+         nir_def *edge_value = nir_channel(&b, nir_load_array_var_imm(&b, edge_var, idx), 0);
+         nir_push_if(&b, nir_feq_imm(&b, edge_value, 1.0));
+      }
+
       nir_emit_vertex(&b, 0);
+
       if (emulate_edgeflags) {
-         nir_def *edge_value = nir_channel(&b, nir_load_array_var_imm(&b, edge_var, idx), 0);
-         nir_if *edge_if = nir_push_if(&b, nir_fneu_imm(&b, edge_value, 1.0));
-         nir_end_primitive(&b, 0);
-         nir_pop_if(&b, edge_if);
+         if (nir->info.gs.output_primitive == MESA_PRIM_LINE_STRIP) {
+            nir_def *edge_value = nir_channel(&b, nir_load_array_var_imm(&b, edge_var, idx), 0);
+            nir_push_if(&b, nir_fneu_imm(&b, edge_value, 1.0));
+            nir_end_primitive(&b, 0);
+            
+         }
+         nir_pop_if(&b, NULL);
       }
+
       if (i >= end_vert)
          break;
    }
index 5441843f5abdf3576ff1cc791d771a4ca1f9964c..90aa5cbad8599e4c95eada2be59d3e86030ed634 100644 (file)
@@ -2458,6 +2458,7 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx)
                   &screen->nir_options,
                   prev_stage,
                   prim,
+                  ctx->gfx_pipeline_state.rast_prim,
                   lower_edge_flags,
                   lower_line_stipple || lower_quad_prim);
             }