vbo: deduplicate copy_vertices functions
authorMarek Olšák <marek.olsak@amd.com>
Tue, 18 Feb 2020 23:37:36 +0000 (18:37 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 5 Mar 2020 00:54:42 +0000 (19:54 -0500)
There are some differences in exec, but those look like bug fixes not ported
to vbo_save.

Reviewed-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
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_draw.c
src/mesa/vbo/vbo_private.h
src/mesa/vbo/vbo_save_api.c

index 359483949e329eba5c165df86c2958d4593891c7..627b4a262d845171f4be6506d18aa4f23e932c1b 100644 (file)
@@ -225,3 +225,105 @@ vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1)
    p0->count += p1->count;
    p0->end = p1->end;
 }
+
+/**
+ * Copy zero, one or two vertices from the current vertex buffer into
+ * the temporary "copy" buffer.
+ * This is used when a single primitive overflows a vertex buffer and
+ * we need to continue the primitive in a new vertex buffer.
+ * The temporary "copy" buffer holds the vertices which need to get
+ * copied from the old buffer to the new one.
+ */
+unsigned
+vbo_copy_vertices(struct gl_context *ctx,
+                  GLenum mode,
+                  struct _mesa_prim *last_prim,
+                  unsigned vertex_size,
+                  bool in_dlist,
+                  fi_type *dst,
+                  const fi_type *src)
+{
+   const unsigned count = last_prim->count;
+   unsigned copy = 0;
+
+   switch (mode) {
+   case GL_POINTS:
+      return 0;
+   case GL_LINES:
+   case GL_TRIANGLES:
+   case GL_QUADS:
+      if (mode == GL_LINES)
+         copy = count % 2;
+      else if (mode == GL_TRIANGLES)
+         copy = count % 3;
+      else if (mode == GL_QUADS)
+         copy = count % 4;
+
+      for (unsigned i = 0; i < copy; i++) {
+         memcpy(dst + i * vertex_size, src + (count - copy + i) * vertex_size,
+                vertex_size * sizeof(GLfloat));
+      }
+      return copy;
+   case GL_LINE_STRIP:
+      if (count == 0)
+         return 0;
+
+      memcpy(dst, src + (count - 1) * vertex_size,
+             vertex_size * sizeof(GLfloat));
+      return 1;
+   case GL_LINE_LOOP:
+      if (!in_dlist && last_prim->begin == 0) {
+         /* We're dealing with the second or later section of a split/wrapped
+          * GL_LINE_LOOP.  Since we're converting line loops to line strips,
+          * we've already incremented the last_prim->start counter by one to
+          * skip the 0th vertex in the loop.  We need to undo that (effectively
+          * subtract one from last_prim->start) so that we copy the 0th vertex
+          * to the next vertex buffer.
+          */
+         assert(last_prim->start > 0);
+         src -= vertex_size;
+      }
+      /* fall-through */
+   case GL_TRIANGLE_FAN:
+   case GL_POLYGON:
+      if (count == 0) {
+         return 0;
+      } else if (count == 1) {
+         memcpy(dst, src + 0, vertex_size * sizeof(GLfloat));
+         return 1;
+      } else {
+         memcpy(dst, src + 0, vertex_size * sizeof(GLfloat));
+         memcpy(dst + vertex_size, src + (count - 1) * vertex_size,
+                vertex_size * sizeof(GLfloat));
+         return 2;
+      }
+   case GL_TRIANGLE_STRIP:
+      /* no parity issue, but need to make sure the tri is not drawn twice */
+      if (count & 1) {
+         last_prim->count--;
+      }
+      /* fallthrough */
+   case GL_QUAD_STRIP:
+      switch (count) {
+      case 0:
+         copy = 0;
+         break;
+      case 1:
+         copy = 1;
+         break;
+      default:
+         copy = 2 + (count & 1);
+         break;
+      }
+      for (unsigned i = 0; i < copy; i++) {
+         memcpy(dst + i * vertex_size, src + (count - copy + i) * vertex_size,
+                vertex_size * sizeof(GLfloat));
+      }
+      return copy;
+   case PRIM_OUTSIDE_BEGIN_END:
+      return 0;
+   default:
+      unreachable("Unexpected primitive type");
+      return 0;
+   }
+}
index 87e7db18d6789190e8798890b922ff170be16869..035c11636123cb49e4d5e300b23659fa821c27dc 100644 (file)
@@ -65,104 +65,16 @@ vbo_exec_debug_verts(struct vbo_exec_context *exec)
 }
 
 
-/**
- * Copy zero, one or two vertices from the current vertex buffer into
- * the temporary "copy" buffer.
- * This is used when a single primitive overflows a vertex buffer and
- * we need to continue the primitive in a new vertex buffer.
- * The temporary "copy" buffer holds the vertices which need to get
- * copied from the old buffer to the new one.
- */
 static GLuint
-vbo_copy_vertices(struct vbo_exec_context *exec)
+vbo_exec_copy_vertices(struct vbo_exec_context *exec)
 {
    struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
-   const GLuint nr = last_prim->count;
-   GLuint ovf, i;
    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;
 
-   switch (exec->ctx->Driver.CurrentExecPrimitive) {
-   case GL_POINTS:
-      return 0;
-   case GL_LINES:
-      ovf = nr&1;
-      for (i = 0 ; i < ovf ; i++)
-         memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat));
-      return i;
-   case GL_TRIANGLES:
-      ovf = nr%3;
-      for (i = 0 ; i < ovf ; i++)
-         memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat));
-      return i;
-   case GL_QUADS:
-      ovf = nr&3;
-      for (i = 0 ; i < ovf ; i++)
-         memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat));
-      return i;
-   case GL_LINE_STRIP:
-      if (nr == 0) {
-         return 0;
-      }
-      else {
-         memcpy(dst, src+(nr-1)*sz, sz * sizeof(GLfloat));
-         return 1;
-      }
-   case GL_LINE_LOOP:
-      if (last_prim->begin == 0) {
-         /* We're dealing with the second or later section of a split/wrapped
-          * GL_LINE_LOOP.  Since we're converting line loops to line strips,
-          * we've already increment the last_prim->start counter by one to
-          * skip the 0th vertex in the loop.  We need to undo that (effectively
-          * subtract one from last_prim->start) so that we copy the 0th vertex
-          * to the next vertex buffer.
-          */
-         assert(last_prim->start > 0);
-         src -= sz;
-      }
-      /* fall-through */
-   case GL_TRIANGLE_FAN:
-   case GL_POLYGON:
-      if (nr == 0) {
-         return 0;
-      }
-      else if (nr == 1) {
-         memcpy(dst, src+0, sz * sizeof(GLfloat));
-         return 1;
-      }
-      else {
-         memcpy(dst, src+0, sz * sizeof(GLfloat));
-         memcpy(dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat));
-         return 2;
-      }
-   case GL_TRIANGLE_STRIP:
-      /* no parity issue, but need to make sure the tri is not drawn twice */
-      if (nr & 1) {
-         last_prim->count--;
-      }
-      /* fallthrough */
-   case GL_QUAD_STRIP:
-      switch (nr) {
-      case 0:
-         ovf = 0;
-         break;
-      case 1:
-         ovf = 1;
-         break;
-      default:
-         ovf = 2 + (nr & 1);
-         break;
-      }
-      for (i = 0 ; i < ovf ; i++)
-         memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat));
-      return i;
-   case PRIM_OUTSIDE_BEGIN_END:
-      return 0;
-   default:
-      unreachable("Unexpected primitive type");
-      return 0;
-   }
+   return vbo_copy_vertices(exec->ctx, exec->ctx->Driver.CurrentExecPrimitive,
+                            last_prim, sz, false, dst, src);
 }
 
 
@@ -392,7 +304,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
    if (exec->vtx.prim_count &&
        exec->vtx.vert_count) {
 
-      exec->vtx.copied.nr = vbo_copy_vertices(exec);
+      exec->vtx.copied.nr = vbo_exec_copy_vertices(exec);
 
       if (exec->vtx.copied.nr != exec->vtx.vert_count) {
          struct gl_context *ctx = exec->ctx;
index c94215a20f556cf99cf98030702a85370553099d..93224d79ccdd45fd1804b7eb1ea78e6e7682c899 100644 (file)
@@ -185,6 +185,15 @@ void
 vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1);
 
 
+unsigned
+vbo_copy_vertices(struct gl_context *ctx,
+                  GLenum mode,
+                  struct _mesa_prim *last_prim,
+                  unsigned vertex_size,
+                  bool in_dlist,
+                  fi_type *dst,
+                  const fi_type *src);
+
 /**
  * Get the filter mask for vbo draws depending on the vertex_processing_mode.
  */
index 1ef6043ad0cdf4acaa9d549e243ca4eee7e6e388..50047f4aed53ac6eb3e08d788812b93ad2af21f4 100644 (file)
@@ -111,79 +111,15 @@ copy_vertices(struct gl_context *ctx,
               const fi_type * src_buffer)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
-   const struct _mesa_prim *prim = &node->prims[node->prim_count - 1];
-   GLuint nr = prim->count;
+   struct _mesa_prim *prim = &node->prims[node->prim_count - 1];
    GLuint sz = save->vertex_size;
    const fi_type *src = src_buffer + prim->start * sz;
    fi_type *dst = save->copied.buffer;
-   GLuint ovf, i;
 
    if (prim->end)
       return 0;
 
-   switch (prim->mode) {
-   case GL_POINTS:
-      return 0;
-   case GL_LINES:
-      ovf = nr & 1;
-      for (i = 0; i < ovf; i++)
-         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
-                sz * sizeof(GLfloat));
-      return i;
-   case GL_TRIANGLES:
-      ovf = nr % 3;
-      for (i = 0; i < ovf; i++)
-         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
-                sz * sizeof(GLfloat));
-      return i;
-   case GL_QUADS:
-      ovf = nr & 3;
-      for (i = 0; i < ovf; i++)
-         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
-                sz * sizeof(GLfloat));
-      return i;
-   case GL_LINE_STRIP:
-      if (nr == 0)
-         return 0;
-      else {
-         memcpy(dst, src + (nr - 1) * sz, sz * sizeof(GLfloat));
-         return 1;
-      }
-   case GL_LINE_LOOP:
-   case GL_TRIANGLE_FAN:
-   case GL_POLYGON:
-      if (nr == 0)
-         return 0;
-      else if (nr == 1) {
-         memcpy(dst, src + 0, sz * sizeof(GLfloat));
-         return 1;
-      }
-      else {
-         memcpy(dst, src + 0, sz * sizeof(GLfloat));
-         memcpy(dst + sz, src + (nr - 1) * sz, sz * sizeof(GLfloat));
-         return 2;
-      }
-   case GL_TRIANGLE_STRIP:
-   case GL_QUAD_STRIP:
-      switch (nr) {
-      case 0:
-         ovf = 0;
-         break;
-      case 1:
-         ovf = 1;
-         break;
-      default:
-         ovf = 2 + (nr & 1);
-         break;
-      }
-      for (i = 0; i < ovf; i++)
-         memcpy(dst + i * sz, src + (nr - ovf + i) * sz,
-                sz * sizeof(GLfloat));
-      return i;
-   default:
-      unreachable("Unexpected primitive type");
-      return 0;
-   }
+   return vbo_copy_vertices(ctx, prim->mode, prim, sz, true, dst, src);
 }