Minor nit-picks below.

On 02/26/2018 11:12 PM, mathias.froehl...@gmx.net wrote:
From: Mathias Fröhlich <mathias.froehl...@web.de>

Use the information already present in the VAO to replay a display list
node using immediate mode draw commands. Use a hand full of helper methods
that will be useful for the next patches also.

Signed-off-by: Mathias Fröhlich <mathias.froehl...@web.de>
---
  src/mesa/vbo/vbo_save.h          |  53 ++++++++++++++---
  src/mesa/vbo/vbo_save_api.c      |  42 ++++++--------
  src/mesa/vbo/vbo_save_draw.c     |  28 +++------
  src/mesa/vbo/vbo_save_loopback.c | 119 +++++++++++++++++++++++++--------------
  4 files changed, 149 insertions(+), 93 deletions(-)

diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
index 14ac831ffd..0672557c0e 100644
--- a/src/mesa/vbo/vbo_save.h
+++ b/src/mesa/vbo/vbo_save.h
@@ -100,6 +100,50 @@ aligned_vertex_buffer_offset(const struct 
vbo_save_vertex_list *node)
  }
+/**
+ * Return the stride in bytes of the display list node.
+ */
+static inline GLsizei
+_vbo_save_get_stride(const struct vbo_save_vertex_list *node)
+{
+   return node->VAO[0]->BufferBinding[0].Stride;
+}
+
+
+/**
+ * Return the first referenced vertex index in the display list node.
+ */
+static inline GLuint
+_vbo_save_get_min_index(const struct vbo_save_vertex_list *node)
+{
+   const struct _mesa_prim *first_prim = &node->prims[0];
+   return first_prim->start;

Maybe just  return node->prims[0].start;


+}
+
+
+/**
+ * Return the last referenced vertex index in the display list node.
+ */
+static inline GLuint
+_vbo_save_get_max_index(const struct vbo_save_vertex_list *node)
+{

assert (node->prim_count > 0);

+   const struct _mesa_prim *last_prim = &node->prims[node->prim_count - 1];
+   return last_prim->start + last_prim->count - 1;
+}
+
+
+/**
+ * Return the vertex count in the display list node.
+ */
+static inline GLuint
+_vbo_save_get_vertex_count(const struct vbo_save_vertex_list *node)
+{
+   const struct _mesa_prim *first_prim = &node->prims[0];

assert (node->prim_count > 0);

+   const struct _mesa_prim *last_prim = &node->prims[node->prim_count - 1];
+   return last_prim->start - first_prim->start + last_prim->count;
+}
+
+
  /* These buffers should be a reasonable size to support upload to
   * hardware.  Current vbo implementation will re-upload on any
   * changes, so don't make too big or apps which dynamically create
@@ -178,13 +222,8 @@ void vbo_save_fallback(struct gl_context *ctx, GLboolean 
fallback);
/* save_loopback.c:
   */
-void vbo_loopback_vertex_list(struct gl_context *ctx,
-                              const GLfloat *buffer,
-                              const GLubyte *attrsz,
-                              const struct _mesa_prim *prim,
-                              GLuint prim_count,
-                              GLuint wrap_count,
-                              GLuint vertex_size);
+void _vbo_loopback_vertex_list(struct gl_context *ctx,
+                               const struct vbo_save_vertex_list* node);
/* Callbacks:
   */
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index b6fc7daa35..dc248934f7 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -641,6 +641,22 @@ compile_vertex_list(struct gl_context *ctx)
merge_prims(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.
+    * On the other hand the _vbo_loopback_vertex_list call below needs the
+    * primitves to be corrected already.
+    */
+   if (aligned_vertex_buffer_offset(node)) {
+      const unsigned start_offset =
+         node->buffer_offset / (node->vertex_size * sizeof(GLfloat));
+      for (unsigned i = 0; i < node->prim_count; i++) {
+         node->prims[i].start += start_offset;
+      }
+      node->start_vertex = start_offset;
+   } else {
+      node->start_vertex = 0;
+   }
+
     /* Deal with GL_COMPILE_AND_EXECUTE:
      */
     if (ctx->ExecuteFlag) {
@@ -648,13 +664,8 @@ compile_vertex_list(struct gl_context *ctx)
_glapi_set_dispatch(ctx->Exec); - const GLfloat *buffer = (const GLfloat *)
-         ((const char *) save->vertex_store->buffer_map +
-          node->buffer_offset);
-
-      vbo_loopback_vertex_list(ctx, buffer,
-                               node->attrsz, node->prims, node->prim_count,
-                               node->wrap_count, node->vertex_size);
+      /* Note that the range of referenced vertices must be mapped already */
+      _vbo_loopback_vertex_list(ctx, node);
_glapi_set_dispatch(dispatch);
     }
@@ -693,23 +704,6 @@ compile_vertex_list(struct gl_context *ctx)
        save->prim_store = alloc_prim_store();
     }
- /*
-    * If the vertex buffer offset is a multiple of the vertex size,
-    * we can use the _mesa_prim::start value to indicate where the
-    * vertices starts, instead of the buffer offset.  Also see the
-    * bind_vertex_list() function.
-    */
-   if (aligned_vertex_buffer_offset(node)) {
-      const unsigned start_offset =
-         node->buffer_offset / (node->vertex_size * sizeof(GLfloat));
-      for (unsigned i = 0; i < save->prim_count; i++) {
-         save->prims[i].start += start_offset;
-      }
-      node->start_vertex = start_offset;
-   } else {
-      node->start_vertex = 0;
-   }
-
     /* Reset our structures for the next run of vertices:
      */
     reset_counters(ctx);
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 7cb6799668..0358ecd2f9 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -144,26 +144,14 @@ static void
  loopback_vertex_list(struct gl_context *ctx,
                       const struct vbo_save_vertex_list *list)
  {
-   const char *buffer =
-      ctx->Driver.MapBufferRange(ctx, 0,
-                                 list->vertex_store->bufferobj->Size,
-                                 GL_MAP_READ_BIT, /* ? */
-                                 list->vertex_store->bufferobj,
-                                 MAP_INTERNAL);
-
-   unsigned buffer_offset =
-      aligned_vertex_buffer_offset(list) ? 0 : list->buffer_offset;
-
-   vbo_loopback_vertex_list(ctx,
-                            (const GLfloat *) (buffer + buffer_offset),
-                            list->attrsz,
-                            list->prims,
-                            list->prim_count,
-                            list->wrap_count,
-                            list->vertex_size);
-
-   ctx->Driver.UnmapBuffer(ctx, list->vertex_store->bufferobj,
-                           MAP_INTERNAL);
+   struct gl_buffer_object *bo = list->VAO[0]->BufferBinding[0].BufferObj;
+   ctx->Driver.MapBufferRange(ctx, 0, bo->Size, GL_MAP_READ_BIT, /* ? */
+                              bo, MAP_INTERNAL);
+
+   /* Note that the range of referenced vertices must be mapped already */
+   _vbo_loopback_vertex_list(ctx, list);
+
+   ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL);
  }
diff --git a/src/mesa/vbo/vbo_save_loopback.c b/src/mesa/vbo/vbo_save_loopback.c
index 43d458a7c0..55a6fb8180 100644
--- a/src/mesa/vbo/vbo_save_loopback.c
+++ b/src/mesa/vbo/vbo_save_loopback.c
@@ -81,8 +81,8 @@ static attr_func vert_attrfunc[4] = {
struct loopback_attr {
-   GLint index;
-   GLint sz;
+   enum vbo_attrib index;
+   GLuint offset;
     attr_func func;
  };
@@ -94,17 +94,15 @@ struct loopback_attr {
   */
  static void
  loopback_prim(struct gl_context *ctx,
-              const GLfloat *buffer,
+              const GLubyte *buffer,
                const struct _mesa_prim *prim,
                GLuint wrap_count,
-              GLuint vertex_size,
+              GLuint stride,
                const struct loopback_attr *la, GLuint nr)
  {
-   GLint start = prim->start;
-   GLint end = start + prim->count;
-   const GLfloat *data;
-   GLint j;
-   GLuint k;
+   GLuint start = prim->start;
+   GLuint end = start + prim->count;

const on those two?

-Brian


+   const GLubyte *data;
if (0)
        printf("loopback prim %s(%s,%s) verts %d..%d  vsize %d\n",
@@ -112,7 +110,7 @@ loopback_prim(struct gl_context *ctx,
               prim->begin ? "begin" : "..",
               prim->end ? "end" : "..",
               start, end,
-             vertex_size);
+             stride);
if (prim->begin) {
        CALL_Begin(GET_DISPATCH(), (prim->mode));
@@ -121,20 +119,13 @@ loopback_prim(struct gl_context *ctx,
        start += wrap_count;
     }
- data = buffer + start * vertex_size;
+   data = buffer + start * stride;
- for (j = start; j < end; j++) {
-      const GLfloat *tmp = data + la[0].sz;
+   for (GLuint j = start; j < end; j++) {
+      for (GLuint k = 0; k < nr; k++)
+         la[k].func(ctx, la[k].index, (const GLfloat *)(data + la[k].offset));
- for (k = 1; k < nr; k++) {
-         la[k].func(ctx, la[k].index, tmp);
-         tmp += la[k].sz;
-      }
-
-      /* Fire the vertex
-       */
-      la[0].func(ctx, VBO_ATTRIB_POS, data);
-      data = tmp;
+      data += stride;
     }
if (prim->end) {
@@ -167,36 +158,80 @@ loopback_weak_prim(struct gl_context *ctx,
  }
+static inline void
+append_attr(GLuint *nr, struct loopback_attr la[], int i, int shift,
+            const struct gl_vertex_array_object *vao)
+{
+   la[*nr].index = shift + i;
+   la[*nr].offset = vao->VertexAttrib[i].RelativeOffset;
+   la[*nr].func = vert_attrfunc[vao->VertexAttrib[i].Size - 1];
+   (*nr)++;
+}
+
+
  void
-vbo_loopback_vertex_list(struct gl_context *ctx,
-                         const GLfloat *buffer,
-                         const GLubyte *attrsz,
-                         const struct _mesa_prim *prim,
-                         GLuint prim_count,
-                         GLuint wrap_count,
-                         GLuint vertex_size)
+_vbo_loopback_vertex_list(struct gl_context *ctx,
+                          const struct vbo_save_vertex_list* node)
  {
     struct loopback_attr la[VBO_ATTRIB_MAX];
-   GLuint i, nr = 0;
+   GLuint nr = 0;
/* All Legacy, NV, ARB and Material attributes are routed through
      * the NV attributes entrypoints:
      */
-   for (i = 0; i < VBO_ATTRIB_MAX; i++) {
-      if (attrsz[i]) {
-         la[nr].index = i;
-         la[nr].sz = attrsz[i];
-         la[nr].func = vert_attrfunc[attrsz[i]-1];
-         nr++;
-      }
+   const struct gl_vertex_array_object *vao = node->VAO[VP_MODE_FF];
+   GLbitfield mask = vao->_Enabled & VERT_BIT_MAT_ALL;
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      append_attr(&nr, la, i, VBO_MATERIAL_SHIFT, vao);
+   }
+
+   vao = node->VAO[VP_MODE_SHADER];
+   mask = vao->_Enabled & ~(VERT_BIT_POS | VERT_BIT_GENERIC0);
+   while (mask) {
+      const int i = u_bit_scan(&mask);
+      append_attr(&nr, la, i, 0, vao);
+   }
+
+   /* The last in the list should be the vertex provoking attribute */
+   if (vao->_Enabled & VERT_BIT_GENERIC0) {
+      append_attr(&nr, la, VERT_ATTRIB_GENERIC0, 0, vao);
+   } else if (vao->_Enabled & VERT_BIT_POS) {
+      append_attr(&nr, la, VERT_ATTRIB_POS, 0, vao);
+   }
+
+   const GLuint wrap_count = node->wrap_count;
+   const GLuint stride = _vbo_save_get_stride(node);
+   const GLubyte *buffer = NULL;
+   if (0 < nr) {
+      /* Compute the minimal offset into the vertex buffer object */
+      GLuint offset = ~0u;
+      for (GLuint i = 0; i < nr; ++i)
+         offset = MIN2(offset, la[i].offset);
+      for (GLuint i = 0; i < nr; ++i)
+         la[i].offset -= offset;
+
+      /* Get the mapped base pointer, assert sufficient mapping */
+      struct gl_buffer_object *bufferobj = vao->BufferBinding[0].BufferObj;
+      assert(bufferobj && bufferobj->Mappings[MAP_INTERNAL].Pointer);
+      buffer = bufferobj->Mappings[MAP_INTERNAL].Pointer;
+      assert(bufferobj->Mappings[MAP_INTERNAL].Offset
+             <= vao->BufferBinding[0].Offset + offset
+             + stride*(_vbo_save_get_min_index(node) + wrap_count));
+      buffer += vao->BufferBinding[0].Offset + offset
+         - bufferobj->Mappings[MAP_INTERNAL].Offset;
+      assert(stride*(_vbo_save_get_vertex_count(node) - wrap_count)
+             <= bufferobj->Mappings[MAP_INTERNAL].Length);
     }
- for (i = 0; i < prim_count; i++) {
-      if ((prim[i].mode & VBO_SAVE_PRIM_WEAK) &&
-          _mesa_inside_begin_end(ctx)) {
-         loopback_weak_prim(ctx, &prim[i]);
+   /* Replay the primitives */
+   const struct _mesa_prim *prims = node->prims;
+   const GLuint prim_count = node->prim_count;
+   for (GLuint i = 0; i < prim_count; i++) {
+      if ((prims[i].mode & VBO_SAVE_PRIM_WEAK) && _mesa_inside_begin_end(ctx)) 
{
+         loopback_weak_prim(ctx, &prims[i]);
        } else {
-         loopback_prim(ctx, buffer, &prim[i], wrap_count, vertex_size, la, nr);
+         loopback_prim(ctx, buffer, &prims[i], wrap_count, stride, la, nr);
        }
     }
  }


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to