vbo: merge more primitive types for glBegin/End (v2)
authorMarek Olšák <marek.olsak@amd.com>
Fri, 14 Feb 2020 04:22:44 +0000 (23:22 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 5 Mar 2020 00:54:43 +0000 (19:54 -0500)
v2: clean it up more

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4052>

src/mesa/vbo/vbo_exec.c
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_private.h
src/mesa/vbo/vbo_save_api.c

index 8fae73adfa221fd29aa7ccd99b961b71387610e5..c1f28822e3a54edc091b7abfe20dcf23bbecc98b 100644 (file)
@@ -168,14 +168,12 @@ vbo_try_prim_conversion(struct _mesa_prim *p)
 
 
 /**
- * Helper function for determining if two subsequent glBegin/glEnd
- * primitives can be combined.  This is only possible for GL_POINTS,
- * GL_LINES, GL_TRIANGLES and GL_QUADS.
- * If we return true, it means that we can concatenate p1 onto p0 (and
- * discard p1).
+ * Function for merging two subsequent glBegin/glEnd draws.
+ * Return true if p1 was concatenated onto p0 (to discard p1 in the caller).
  */
 bool
-vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1)
+vbo_merge_draws(struct gl_context *ctx, bool in_dlist,
+                struct _mesa_prim *p0, const struct _mesa_prim *p1)
 {
    if (!p0->begin ||
        !p1->begin ||
@@ -193,37 +191,42 @@ vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1)
 
    assert(p0->basevertex == p1->basevertex);
 
-   /* can always merge subsequent GL_POINTS primitives */
-   if (p0->mode == GL_POINTS)
-      return true;
-
-   /* independent lines with no extra vertices */
-   if (p0->mode == GL_LINES && p0->count % 2 == 0)
-      return true;
-
-   /* independent tris */
-   if (p0->mode == GL_TRIANGLES && p0->count % 3 == 0)
-      return true;
-
-   /* independent quads */
-   if (p0->mode == GL_QUADS && p0->count % 4 == 0)
-      return true;
-
-   return false;
-}
-
-
-/**
- * If we've determined that p0 and p1 can be merged, this function
- * concatenates p1 onto p0.
- */
-void
-vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1)
-{
-   assert(vbo_can_merge_prims(p0, p1));
+   switch (p0->mode) {
+   case GL_POINTS:
+      /* can always merge subsequent GL_POINTS primitives */
+      break;
+   /* check independent primitives with no extra vertices */
+   case GL_LINES:
+      if (p0->count % 2)
+         return false;
+      break;
+   case GL_TRIANGLES:
+      if (p0->count % 3)
+         return false;
+      break;
+   case GL_QUADS:
+   case GL_LINES_ADJACENCY:
+      if (p0->count % 4)
+         return false;
+      break;
+   case GL_TRIANGLES_ADJACENCY:
+      if (p0->count % 6)
+         return false;
+      break;
+   case GL_PATCHES:
+      /* "patch_vertices" can be unknown when compiling a display list. */
+      if (in_dlist ||
+          p0->count % ctx->TessCtrlProgram.patch_vertices)
+         return false;
+      break;
+   default:
+      return false;
+   }
 
+   /* Merge draws. */
    p0->count += p1->count;
    p0->end = p1->end;
+   return true;
 }
 
 /**
index 8906ddd6703a90b54637391198cfe8e24ee25b1b..6fd4c1493cf672c1560b14d99a7a8a4e62cf05fe 100644 (file)
@@ -846,14 +846,8 @@ try_vbo_merge(struct vbo_exec_context *exec)
       struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2];
       assert(prev == cur - 1);
 
-      if (vbo_can_merge_prims(prev, cur)) {
-         assert(cur->begin);
-         assert(cur->end);
-         assert(prev->begin);
-         assert(prev->end);
-         vbo_merge_prims(prev, cur);
+      if (vbo_merge_draws(exec->ctx, false, prev, cur))
          exec->vtx.prim_count--;  /* drop the last primitive */
-      }
    }
 }
 
index 93224d79ccdd45fd1804b7eb1ea78e6e7682c899..1e37df881cd8e965ec38b03328716e1713a52e22 100644 (file)
@@ -179,11 +179,8 @@ void
 vbo_try_prim_conversion(struct _mesa_prim *p);
 
 bool
-vbo_can_merge_prims(const struct _mesa_prim *p0, const struct _mesa_prim *p1);
-
-void
-vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1);
-
+vbo_merge_draws(struct gl_context *ctx, bool in_dlist,
+                struct _mesa_prim *p0, const struct _mesa_prim *p1);
 
 unsigned
 vbo_copy_vertices(struct gl_context *ctx,
index 50047f4aed53ac6eb3e08d788812b93ad2af21f4..63a5b0ebb9080cdf48690619631e2b95ceafe960 100644 (file)
@@ -273,7 +273,7 @@ reset_counters(struct gl_context *ctx)
  * previous prim.
  */
 static void
-merge_prims(struct _mesa_prim *prim_list,
+merge_prims(struct gl_context *ctx, struct _mesa_prim *prim_list,
             GLuint *prim_count)
 {
    GLuint i;
@@ -284,11 +284,10 @@ merge_prims(struct _mesa_prim *prim_list,
 
       vbo_try_prim_conversion(this_prim);
 
-      if (vbo_can_merge_prims(prev_prim, this_prim)) {
+      if (vbo_merge_draws(ctx, true, prev_prim, this_prim)) {
          /* We've found a prim that just extend the previous one.  Tack it
           * onto the previous one, and let this primitive struct get dropped.
           */
-         vbo_merge_prims(prev_prim, this_prim);
          continue;
       }
 
@@ -578,7 +577,7 @@ compile_vertex_list(struct gl_context *ctx)
       convert_line_loop_to_strip(save, node);
    }
 
-   merge_prims(node->prims, &node->prim_count);
+   merge_prims(ctx, node->prims, &node->prim_count);
 
    /* Correct the primitive starts, we can only do this here as copy_vertices
     * and convert_line_loop_to_strip above consume the uncorrected starts.