Mesa (master): vbo/dlist: create an index buffer in compile_vertex_list

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Dec 8 09:42:18 UTC 2020


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

Author: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
Date:   Thu Oct  8 14:43:57 2020 +0200

vbo/dlist: create an index buffer in compile_vertex_list

This will be useful to implement other optimizations.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7078>

---

 src/mesa/vbo/vbo_save.h      |  8 +++---
 src/mesa/vbo/vbo_save_api.c  | 58 ++++++++++++++++++++++++++++++++++++++++++++
 src/mesa/vbo/vbo_save_draw.c |  7 +++---
 3 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
index a9842514011..d63a9c22cf3 100644
--- a/src/mesa/vbo/vbo_save.h
+++ b/src/mesa/vbo/vbo_save.h
@@ -67,6 +67,9 @@ struct vbo_save_vertex_list {
    struct _mesa_prim *prims;
    GLuint prim_count;
 
+   struct _mesa_index_buffer ib;
+   GLuint min_index, max_index;
+
    struct vbo_save_primitive_store *prim_store;
 };
 
@@ -88,7 +91,7 @@ static inline GLuint
 _vbo_save_get_min_index(const struct vbo_save_vertex_list *node)
 {
    assert(node->prim_count > 0);
-   return node->prims[0].start;
+   return node->min_index;
 }
 
 
@@ -99,8 +102,7 @@ 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 node->max_index;
 }
 
 
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index b00981a3651..b76b35fa52f 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -599,6 +599,63 @@ compile_vertex_list(struct gl_context *ctx)
       node->prims[i].start += start_offset;
    }
 
+   /* Create an index buffer. */
+   node->min_index = node->max_index = 0;
+   if (save->vert_count) {
+      int end = node->prims[node->prim_count - 1].start +
+                node->prims[node->prim_count - 1].count;
+      int total_vert_count = end - node->prims[0].start;
+      int max_indices_count = total_vert_count;
+      int size = max_indices_count * sizeof(uint32_t);
+      uint32_t* indices = (uint32_t*) malloc(size);
+      uint32_t max_index = 0, min_index = 0xFFFFFFFF;
+
+      int idx = 0;
+
+      /* Construct indices array. */
+      for (unsigned i = 0; i < node->prim_count; i++) {
+         assert(node->prims[i].basevertex == 0);
+         int vertex_count = node->prims[i].count;
+         int start = idx;
+
+         for (unsigned j = 0; j < vertex_count; j++) {
+            indices[idx++] = node->prims[i].start + j;
+         }
+
+         min_index = MIN2(min_index, indices[start]);
+         max_index = MAX2(max_index, indices[idx - 1]);
+
+         node->prims[i].start = start;
+      }
+
+      assert(idx <= max_indices_count);
+
+      node->ib.ptr = NULL;
+      node->ib.count = idx;
+      node->ib.index_size_shift = (GL_UNSIGNED_INT - GL_UNSIGNED_BYTE) >> 1;
+
+      node->min_index = min_index;
+      node->max_index = max_index;
+
+      node->ib.obj = ctx->Driver.NewBufferObject(ctx, VBO_BUF_ID + 1);
+      bool success = ctx->Driver.BufferData(ctx,
+                                            GL_ELEMENT_ARRAY_BUFFER_ARB,
+                                            idx * sizeof(uint32_t), indices,
+                                            GL_STATIC_DRAW_ARB, GL_MAP_WRITE_BIT,
+                                            node->ib.obj);
+      assert(success);
+      if (!success) {
+         node->min_index = node->max_index = 0;
+         ctx->Driver.DeleteBuffer(ctx, node->ib.obj);
+         node->ib.obj = NULL;
+         node->vertex_count = 0;
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "IB allocation");
+      }
+      free(indices);
+   } else {
+      node->ib.obj = NULL;
+   }
+
    /* Deal with GL_COMPILE_AND_EXECUTE:
     */
    if (ctx->ExecuteFlag) {
@@ -1709,6 +1766,7 @@ vbo_destroy_vertex_list(struct gl_context *ctx, void *data)
    if (--node->prim_store->refcount == 0)
       free(node->prim_store);
 
+   _mesa_reference_buffer_object(ctx, &node->ib.obj, NULL);
    free(node->current_data);
    node->current_data = NULL;
 }
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 97938514494..e178df247ef 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -31,6 +31,7 @@
 #include "main/glheader.h"
 #include "main/bufferobj.h"
 #include "main/context.h"
+#include "main/enable.h"
 #include "main/mesa_private.h"
 #include "main/macros.h"
 #include "main/light.h"
@@ -210,10 +211,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
       assert(ctx->NewState == 0);
 
       if (node->vertex_count > 0) {
-         GLuint min_index = _vbo_save_get_min_index(node);
-         GLuint max_index = _vbo_save_get_max_index(node);
-         ctx->Driver.Draw(ctx, node->prims, node->prim_count, NULL, true,
-                          false, 0, min_index, max_index, 1, 0);
+         ctx->Driver.Draw(ctx, node->prims, node->prim_count, &node->ib, true,
+                          false, 0, node->min_index, node->max_index, 1, 0);
       }
    }
 



More information about the mesa-commit mailing list