vbo: switch immediate Begin/End to DrawGallium
authorMarek Olšák <marek.olsak@amd.com>
Mon, 2 Nov 2020 07:00:37 +0000 (02:00 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Tue, 5 Jan 2021 00:22:33 +0000 (19:22 -0500)
This makes gallium faster because st/mesa doesn't have to translate
_mesa_prim.

Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7679>

src/mesa/vbo/vbo.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_draw.c

index 5237e0f..da9c5e4 100644 (file)
@@ -37,6 +37,7 @@
 #include "main/draw.h"
 #include "main/macros.h"
 #include "vbo_attrib.h"
+#include "gallium/include/pipe/p_state.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -80,20 +81,42 @@ struct vbo_exec_copied_vtx {
    GLuint nr;
 };
 
+struct vbo_markers
+{
+   /**
+    * If false and the primitive is a line loop, the first vertex is
+    * the beginning of the line loop and it won't be drawn.
+    * Instead, it will be moved to the end.
+    *
+    * Drivers shouldn't reset the line stipple pattern walker if begin is
+    * false and mode is a line strip.
+    */
+   bool begin;
+
+   /**
+    * If true and the primitive is a line loop, it will be closed.
+    */
+   bool end;
+};
+
 struct vbo_exec_context
 {
    GLvertexformat vtxfmt;
    GLvertexformat vtxfmt_noop;
 
    struct {
+      /* Multi draw where the mode can vary between draws. */
+      struct pipe_draw_info info;
+      struct pipe_draw_start_count draw[VBO_MAX_PRIM];
+      GLubyte mode[VBO_MAX_PRIM];            /**< primitive modes per draw */
+      struct vbo_markers markers[VBO_MAX_PRIM];
+      unsigned prim_count;
+
       struct gl_buffer_object *bufferobj;
 
       GLuint vertex_size;       /* in dwords */
       GLuint vertex_size_no_pos;
 
-      struct _mesa_prim prim[VBO_MAX_PRIM];
-      GLuint prim_count;
-
       fi_type *buffer_map;
       fi_type *buffer_ptr;              /* cursor, points into buffer */
       GLuint   buffer_used;             /* in bytes */
index c25a7ea..c9a36b0 100644 (file)
@@ -82,29 +82,30 @@ vbo_exec_wrap_buffers(struct vbo_exec_context *exec)
    }
    else {
       struct gl_context *ctx = gl_context_from_vbo_exec(exec);
-      struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
-      const GLuint last_begin = last_prim->begin;
+      unsigned last = exec->vtx.prim_count - 1;
+      struct pipe_draw_start_count *last_draw = &exec->vtx.draw[last];
+      const bool last_begin = exec->vtx.markers[last].begin;
       GLuint last_count = 0;
 
       if (_mesa_inside_begin_end(ctx)) {
-         last_prim->count = exec->vtx.vert_count - last_prim->start;
-         last_count = last_prim->count;
-         last_prim->end = 0;
+         last_draw->count = exec->vtx.vert_count - last_draw->start;
+         last_count = last_draw->count;
+         exec->vtx.markers[last].end = 0;
       }
 
       /* Special handling for wrapping GL_LINE_LOOP */
-      if (last_prim->mode == GL_LINE_LOOP &&
+      if (exec->vtx.mode[last] == GL_LINE_LOOP &&
           last_count > 0 &&
-          !last_prim->end) {
+          !exec->vtx.markers[last].end) {
          /* draw this section of the incomplete line loop as a line strip */
-         last_prim->mode = GL_LINE_STRIP;
-         if (!last_prim->begin) {
+         exec->vtx.mode[last] = GL_LINE_STRIP;
+         if (!last_begin) {
             /* This is not the first section of the line loop, so don't
              * draw the 0th vertex.  We're saving it until we draw the
              * very last section of the loop.
              */
-            last_prim->start++;
-            last_prim->count--;
+            last_draw->start++;
+            last_draw->count--;
          }
       }
 
@@ -122,13 +123,13 @@ vbo_exec_wrap_buffers(struct vbo_exec_context *exec)
       assert(exec->vtx.prim_count == 0);
 
       if (_mesa_inside_begin_end(ctx)) {
-         exec->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive;
-         exec->vtx.prim[0].begin = 0;
-         exec->vtx.prim[0].start = 0;
+         exec->vtx.mode[0] = ctx->Driver.CurrentExecPrimitive;
+         exec->vtx.draw[0].start = 0;
+         exec->vtx.markers[0].begin = 0;
          exec->vtx.prim_count++;
 
          if (exec->vtx.copied.nr == last_count)
-            exec->vtx.prim[0].begin = last_begin;
+            exec->vtx.markers[0].begin = last_begin;
       }
    }
 }
@@ -836,9 +837,9 @@ vbo_exec_Begin(GLenum mode)
       vbo_exec_FlushVertices_internal(exec, FLUSH_STORED_VERTICES);
 
    i = exec->vtx.prim_count++;
-   exec->vtx.prim[i].mode = mode;
-   exec->vtx.prim[i].begin = 1;
-   exec->vtx.prim[i].start = exec->vtx.vert_count;
+   exec->vtx.mode[i] = mode;
+   exec->vtx.draw[i].start = exec->vtx.vert_count;
+   exec->vtx.markers[i].begin = 1;
 
    ctx->Driver.CurrentExecPrimitive = mode;
 
@@ -864,22 +865,27 @@ vbo_exec_Begin(GLenum mode)
 static void
 try_vbo_merge(struct vbo_exec_context *exec)
 {
-   struct _mesa_prim *cur =  &exec->vtx.prim[exec->vtx.prim_count - 1];
+   unsigned cur = exec->vtx.prim_count - 1;
 
    assert(exec->vtx.prim_count >= 1);
 
-   vbo_try_prim_conversion(&cur->mode, &cur->count);
+   vbo_try_prim_conversion(&exec->vtx.mode[cur], &exec->vtx.draw[cur].count);
 
    if (exec->vtx.prim_count >= 2) {
       struct gl_context *ctx = gl_context_from_vbo_exec(exec);
-      struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2];
-      assert(prev == cur - 1);
+      unsigned prev = cur - 1;
 
       if (vbo_merge_draws(ctx, false,
-                          prev->mode, cur->mode, prev->start, cur->start,
-                          &prev->count, cur->count,
-                          prev->basevertex, cur->basevertex,
-                          &prev->end, cur->begin, cur->end))
+                          exec->vtx.mode[prev],
+                          exec->vtx.mode[cur],
+                          exec->vtx.draw[prev].start,
+                          exec->vtx.draw[cur].start,
+                          &exec->vtx.draw[prev].count,
+                          exec->vtx.draw[cur].count,
+                          0, 0,
+                          &exec->vtx.markers[prev].end,
+                          exec->vtx.markers[cur].begin,
+                          exec->vtx.markers[cur].end))
          exec->vtx.prim_count--;  /* drop the last primitive */
    }
 }
@@ -910,31 +916,33 @@ vbo_exec_End(void)
 
    if (exec->vtx.prim_count > 0) {
       /* close off current primitive */
-      struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
-      unsigned count = exec->vtx.vert_count - last_prim->start;
+      unsigned last = exec->vtx.prim_count - 1;
+      struct pipe_draw_start_count *last_draw = &exec->vtx.draw[last];
+      unsigned count = exec->vtx.vert_count - last_draw->start;
 
-      last_prim->end = 1;
-      last_prim->count = count;
+      last_draw->count = count;
+      exec->vtx.markers[last].end = 1;
 
       if (count)
          ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
 
       /* Special handling for GL_LINE_LOOP */
-      if (last_prim->mode == GL_LINE_LOOP && last_prim->begin == 0) {
+      if (exec->vtx.mode[last] == GL_LINE_LOOP &&
+          exec->vtx.markers[last].begin == 0) {
          /* We're finishing drawing a line loop.  Append 0th vertex onto
           * end of vertex buffer so we can draw it as a line strip.
           */
          const fi_type *src = exec->vtx.buffer_map +
-            last_prim->start * exec->vtx.vertex_size;
+            last_draw->start * exec->vtx.vertex_size;
          fi_type *dst = exec->vtx.buffer_map +
             exec->vtx.vert_count * exec->vtx.vertex_size;
 
          /* copy 0th vertex to end of buffer */
          memcpy(dst, src, exec->vtx.vertex_size * sizeof(fi_type));
 
-         last_prim->start++;  /* skip vertex0 */
-         /* note that last_prim->count stays unchanged */
-         last_prim->mode = GL_LINE_STRIP;
+         last_draw->start++;  /* skip vertex0 */
+         /* note that the count stays unchanged */
+         exec->vtx.mode[last] = GL_LINE_STRIP;
 
          /* Increment the vertex count so the next primitive doesn't
           * overwrite the last vertex which we just added.
@@ -1037,6 +1045,9 @@ vbo_exec_vtx_init(struct vbo_exec_context *exec, bool use_buffer_objects)
 
    exec->vtx.enabled = u_bit_consecutive64(0, VBO_ATTRIB_MAX); /* reset all */
    vbo_reset_all_attr(exec);
+
+   exec->vtx.info.instance_count = 1;
+   exec->vtx.info.max_index = ~0;
 }
 
 
index 1932da0..d4eb380 100644 (file)
@@ -53,14 +53,13 @@ vbo_exec_debug_verts(struct vbo_exec_context *exec)
           exec->vtx.vertex_size);
 
    for (i = 0 ; i < exec->vtx.prim_count ; i++) {
-      struct _mesa_prim *prim = &exec->vtx.prim[i];
       printf("   prim %d: %s %d..%d %s %s\n",
              i,
-             _mesa_lookup_prim_by_nr(prim->mode),
-             prim->start,
-             prim->start + prim->count,
-             prim->begin ? "BEGIN" : "(wrap)",
-             prim->end ? "END" : "(wrap)");
+             _mesa_lookup_prim_by_nr(exec->vtx.mode[i]),
+             exec->vtx.draw[i].start,
+             exec->vtx.draw[i].start + exec->vtx.draw[i].count,
+             exec->vtx.markers[i].begin ? "BEGIN" : "(wrap)",
+             exec->vtx.markers[i].end ? "END" : "(wrap)");
    }
 }
 
@@ -69,14 +68,17 @@ static GLuint
 vbo_exec_copy_vertices(struct vbo_exec_context *exec)
 {
    struct gl_context *ctx = gl_context_from_vbo_exec(exec);
-   struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
    const GLuint sz = exec->vtx.vertex_size;
    fi_type *dst = exec->vtx.copied.buffer;
-   const fi_type *src = exec->vtx.buffer_map + last_prim->start * sz;
+   unsigned last = exec->vtx.prim_count - 1;
+   unsigned start = exec->vtx.draw[last].start;
+   const fi_type *src = exec->vtx.buffer_map + start * sz;
 
    return vbo_copy_vertices(ctx, ctx->Driver.CurrentExecPrimitive,
-                            last_prim->start, &last_prim->count,
-                            last_prim->begin, sz, false, dst, src);
+                            start,
+                            &exec->vtx.draw[last].count,
+                            exec->vtx.markers[last].begin,
+                            sz, false, dst, src);
 }
 
 
@@ -328,8 +330,14 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
             printf("%s %d %d\n", __func__, exec->vtx.prim_count,
                    exec->vtx.vert_count);
 
-         ctx->Driver.Draw(ctx, exec->vtx.prim, exec->vtx.prim_count, NULL,
-                          true, false, 0, 0, exec->vtx.vert_count - 1, 1, 0);
+         exec->vtx.info.vertices_per_patch =
+            ctx->TessCtrlProgram.patch_vertices;
+
+         ctx->Driver.DrawGalliumComplex(ctx, &exec->vtx.info,
+                                        exec->vtx.draw,
+                                        exec->vtx.mode,
+                                        NULL,
+                                        exec->vtx.prim_count);
 
          /* Get new storage -- unless asked not to. */
          if (!persistent_mapping)