Mesa (master): draw/gs: reverse the polarity of the invocation/prims execution

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 7 20:37:18 UTC 2020


Module: Mesa
Branch: master
Commit: 3e455d6ad31400f4733a2f859cc5ecade7efdbe1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3e455d6ad31400f4733a2f859cc5ecade7efdbe1

Author: Dave Airlie <airlied at redhat.com>
Date:   Tue Apr 14 12:39:42 2020 +1000

draw/gs: reverse the polarity of the invocation/prims execution

The current code runs primitives per invocation, but the spec wants
invocations per primitive. However it means having to flush
after each invocation to get correct XFB behaviour

Fixes:
GTF-GL41.gtf40.GL3Tests.transform_feedback3.transform_feedback3_geometry_instanced

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5555>

---

 src/gallium/auxiliary/draw/draw_gs.c | 57 +++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 30 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index f648a96db7b..2d11430b274 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -69,7 +69,7 @@ draw_gs_get_input_index(int semantic, int index,
 static inline boolean
 draw_gs_should_flush(struct draw_geometry_shader *shader)
 {
-   return (shader->fetched_prim_count == shader->vector_length);
+   return (shader->fetched_prim_count == shader->vector_length || shader->num_invocations > 1);
 }
 
 /*#define DEBUG_OUTPUTS 1*/
@@ -192,15 +192,8 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
                             const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
 {
    struct tgsi_exec_machine *machine = shader->machine;
-   int j;
    tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
                                   constants, constants_size);
-
-   if (shader->info.uses_invocationid) {
-      unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
-      for (j = 0; j < TGSI_QUAD_SIZE; j++)
-         machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id;
-   }
 }
 
 static void tgsi_gs_run(struct draw_geometry_shader *shader,
@@ -210,6 +203,12 @@ static void tgsi_gs_run(struct draw_geometry_shader *shader,
    struct tgsi_exec_machine *machine = shader->machine;
    int i;
 
+   if (shader->info.uses_invocationid) {
+      unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID];
+      for (int j = 0; j < TGSI_QUAD_SIZE; j++)
+         machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id;
+   }
+
    /* run interpreter */
    tgsi_exec_machine_run(machine, 0);
 
@@ -437,10 +436,13 @@ static void gs_flush(struct draw_geometry_shader *shader)
    debug_assert(input_primitives > 0 &&
                 input_primitives <= 4);
 
-   shader->run(shader, input_primitives, out_prim_count);
-   for (i = 0; i < shader->num_vertex_streams; i++) {
-      shader->fetch_outputs(shader, i, out_prim_count[i],
-                            &shader->stream[i].tmp_output);
+   for (unsigned invocation = 0; invocation < shader->num_invocations; invocation++) {
+      shader->invocation_id = invocation;
+      shader->run(shader, input_primitives, out_prim_count);
+      for (i = 0; i < shader->num_vertex_streams; i++) {
+         shader->fetch_outputs(shader, i, out_prim_count[i],
+                               &shader->stream[i].tmp_output);
+      }
    }
 
 #if 0
@@ -592,7 +594,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
     * overflown vertices into some area where they won't harm anyone */
    unsigned total_verts_per_buffer = shader->primitive_boundary *
       num_in_primitives;
-   unsigned invocation;
    int i;
    //Assume at least one primitive
    max_out_prims = MAX2(max_out_prims, 1);
@@ -666,26 +667,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    }
 #endif
 
-   for (invocation = 0; invocation < shader->num_invocations; invocation++) {
-      shader->invocation_id = invocation;
+   shader->prepare(shader, constants, constants_size);
 
-      shader->prepare(shader, constants, constants_size);
+   if (input_prim->linear)
+      gs_run(shader, input_prim, input_verts,
+             output_prims, output_verts);
+   else
+      gs_run_elts(shader, input_prim, input_verts,
+                  output_prims, output_verts);
 
-      if (input_prim->linear)
-         gs_run(shader, input_prim, input_verts,
-                output_prims, output_verts);
-      else
-         gs_run_elts(shader, input_prim, input_verts,
-                     output_prims, output_verts);
-
-      /* Flush the remaining primitives. Will happen if
-       * num_input_primitives % 4 != 0
-       */
-      if (shader->fetched_prim_count > 0) {
-         gs_flush(shader);
-      }
-      debug_assert(shader->fetched_prim_count == 0);
+   /* Flush the remaining primitives. Will happen if
+    * num_input_primitives % 4 != 0
+    */
+   if (shader->fetched_prim_count > 0) {
+      gs_flush(shader);
    }
+   debug_assert(shader->fetched_prim_count == 0);
 
    /* Update prim_info:
     */



More information about the mesa-commit mailing list