Mesa (master): vbo: Make use of _DrawVAO from immediate mode draw

Mathias Fröhlich frohlich at kemper.freedesktop.org
Fri Feb 23 06:11:38 UTC 2018


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

Author: Mathias Fröhlich <mathias.froehlich at web.de>
Date:   Wed Feb  7 08:59:13 2018 +0100

vbo: Make use of _DrawVAO from immediate mode draw

Finally use an internal VAO to execute immediate mode draws. Avoid
duplicate state validation for immediate mode draws. Remove client arrays
previously used exclusively for immediate mode draws.

Signed-off-by: Mathias Fröhlich <Mathias.Froehlich at web.de>
Reviewed-by: Brian Paul <brianp at vmware.com>

---

 src/mesa/vbo/vbo_context.c   |   8 +++
 src/mesa/vbo/vbo_exec.h      |   8 ---
 src/mesa/vbo/vbo_exec_api.c  |  47 +----------------
 src/mesa/vbo/vbo_exec_draw.c | 117 ++++++++++++++++++++++++-------------------
 src/mesa/vbo/vbo_private.h   |   2 +
 5 files changed, 78 insertions(+), 104 deletions(-)

diff --git a/src/mesa/vbo/vbo_context.c b/src/mesa/vbo/vbo_context.c
index 222bdcf1f2..3dc3222c0d 100644
--- a/src/mesa/vbo/vbo_context.c
+++ b/src/mesa/vbo/vbo_context.c
@@ -30,6 +30,8 @@
 #include "math/m_eval.h"
 #include "main/vtxfmt.h"
 #include "main/api_arrayelt.h"
+#include "main/arrayobj.h"
+#include "main/varray.h"
 #include "vbo.h"
 #include "vbo_private.h"
 
@@ -252,6 +254,11 @@ _vbo_CreateContext(struct gl_context *ctx)
    if (ctx->API == API_OPENGL_COMPAT)
       vbo_save_init(ctx);
 
+   vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0));
+   /* The exec VAO assumes to have all arributes bound to binding 0 */
+   for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i)
+      _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0, false);
+
    _math_init_eval();
 
    return GL_TRUE;
@@ -278,6 +285,7 @@ _vbo_DestroyContext(struct gl_context *ctx)
       vbo_exec_destroy(ctx);
       if (ctx->API == API_OPENGL_COMPAT)
          vbo_save_destroy(ctx);
+      _mesa_reference_vao(ctx, &vbo->VAO, NULL);
       free(vbo);
       ctx->vbo_context = NULL;
    }
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index b00045c7c8..07ab5cc837 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -101,14 +101,6 @@ struct vbo_exec_context
 
       /** pointers into the current 'vertex' array, declared above */
       fi_type *attrptr[VBO_ATTRIB_MAX];
-
-      struct gl_vertex_array arrays[VERT_ATTRIB_MAX];
-
-      /* According to program mode, the values above plus current
-       * values are squashed down to the 32 attributes passed to the
-       * vertex program below:
-       */
-      const struct gl_vertex_array *inputs[VERT_ATTRIB_MAX];
    } vtx;
 
    struct {
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 64e792bfa2..317fc43d1c 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -758,7 +758,8 @@ static void GLAPIENTRY
 vbo_exec_Begin(GLenum mode)
 {
    GET_CURRENT_CONTEXT(ctx);
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
+   struct vbo_context *vbo = vbo_context(ctx);
+   struct vbo_exec_context *exec = &vbo->exec;
    int i;
 
    if (_mesa_inside_begin_end(ctx)) {
@@ -770,8 +771,6 @@ vbo_exec_Begin(GLenum mode)
       return;
    }
 
-   _mesa_set_drawing_arrays(ctx, exec->vtx.inputs);
-
    if (ctx->NewState) {
       _mesa_update_state(ctx);
 
@@ -1162,7 +1161,6 @@ void
 vbo_exec_vtx_init(struct vbo_exec_context *exec)
 {
    struct gl_context *ctx = exec->ctx;
-   struct vbo_context *vbo = vbo_context(ctx);
    GLuint i;
 
    /* Allocate a buffer object.  Will just reuse this object
@@ -1189,38 +1187,6 @@ vbo_exec_vtx_init(struct vbo_exec_context *exec)
       assert(i < ARRAY_SIZE(exec->vtx.active_sz));
       exec->vtx.active_sz[i] = 0;
    }
-   for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
-      assert(i < ARRAY_SIZE(exec->vtx.inputs));
-      assert(i < ARRAY_SIZE(exec->vtx.arrays));
-      exec->vtx.inputs[i] = &exec->vtx.arrays[i];
-   }
-
-   {
-      struct gl_vertex_array *arrays = exec->vtx.arrays;
-      unsigned i;
-
-      memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS],
-             VERT_ATTRIB_FF_MAX * sizeof(arrays[0]));
-      for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) {
-         struct gl_vertex_array *array;
-         array = &arrays[VERT_ATTRIB_FF(i)];
-         array->BufferObj = NULL;
-         _mesa_reference_buffer_object(ctx, &array->BufferObj,
-                                       vbo->currval[VBO_ATTRIB_POS+i].BufferObj);
-      }
-
-      memcpy(arrays + VERT_ATTRIB_GENERIC(0),
-             &vbo->currval[VBO_ATTRIB_GENERIC0],
-             VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0]));
-
-      for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) {
-         struct gl_vertex_array *array;
-         array = &arrays[VERT_ATTRIB_GENERIC(i)];
-         array->BufferObj = NULL;
-         _mesa_reference_buffer_object(ctx, &array->BufferObj,
-                           vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj);
-      }
-   }
 
    exec->vtx.vertex_size = 0;
 
@@ -1233,7 +1199,6 @@ vbo_exec_vtx_destroy(struct vbo_exec_context *exec)
 {
    /* using a real VBO for vertex data */
    struct gl_context *ctx = exec->ctx;
-   unsigned i;
 
    /* True VBOs should already be unmapped
     */
@@ -1247,14 +1212,6 @@ vbo_exec_vtx_destroy(struct vbo_exec_context *exec)
       }
    }
 
-   /* Drop any outstanding reference to the vertex buffer
-    */
-   for (i = 0; i < ARRAY_SIZE(exec->vtx.arrays); i++) {
-      _mesa_reference_buffer_object(ctx,
-                                    &exec->vtx.arrays[i].BufferObj,
-                                    NULL);
-   }
-
    /* Free the vertex buffer.  Unmap first if needed.
     */
    if (_mesa_bufferobj_mapped(exec->vtx.bufferobj, MAP_INTERNAL)) {
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 4421496072..d02b33c8ee 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -33,6 +33,7 @@
 #include "main/context.h"
 #include "main/enums.h"
 #include "main/state.h"
+#include "main/varray.h"
 #include "main/vtxfmt.h"
 
 #include "vbo_noop.h"
@@ -173,61 +174,73 @@ static void
 vbo_exec_bind_arrays(struct gl_context *ctx)
 {
    struct vbo_context *vbo = vbo_context(ctx);
+   struct gl_vertex_array_object *vao = vbo->VAO;
    struct vbo_exec_context *exec = &vbo->exec;
-   struct gl_vertex_array *arrays = exec->vtx.arrays;
-   GLuint attr;
-   GLbitfield varying_inputs = 0x0;
-
-   const gl_vertex_processing_mode processing_mode
-      = ctx->VertexProgram._VPMode;
-   const GLubyte * const map = _vbo_attribute_alias_map[processing_mode];
-
-   /* Grab VERT_ATTRIB_{POS,GENERIC0} from VBO_ATTRIB_POS */
-   const gl_attribute_map_mode mode = ATTRIBUTE_MAP_MODE_POSITION;
-   const GLubyte *const array_map = _mesa_vao_attribute_map[mode];
-   for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
-      const GLuint src = map[array_map[attr]];
-      const GLubyte size = exec->vtx.attrsz[src];
-
-      if (size == 0) {
-         exec->vtx.inputs[attr] = &vbo->currval[map[attr]];
-      } else {
-         GLsizeiptr offset = (GLbyte *)exec->vtx.attrptr[src] -
-            (GLbyte *)exec->vtx.vertex;
-
-         /* override the default array set above */
-         assert(attr < ARRAY_SIZE(exec->vtx.inputs));
-         assert(attr < ARRAY_SIZE(exec->vtx.arrays)); /* arrays[] */
-         exec->vtx.inputs[attr] = &arrays[attr];
-
-         if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
-            /* a real buffer obj: Ptr is an offset, not a pointer */
-            assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer);
-            assert(offset >= 0);
-            arrays[attr].Ptr = (GLubyte *)
-               exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset + offset;
-         }
-         else {
-            /* Ptr into ordinary app memory */
-            arrays[attr].Ptr = (GLubyte *)exec->vtx.buffer_map + offset;
-         }
-         arrays[attr].Size = size;
-         arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
-         const GLenum16 type = exec->vtx.attrtype[src];
-         arrays[attr].Type = type;
-         arrays[attr].Integer = vbo_attrtype_to_integer_flag(type);
-         arrays[attr].Format = GL_RGBA;
-         arrays[attr]._ElementSize = size * sizeof(GLfloat);
-         _mesa_reference_buffer_object(ctx,
-                                       &arrays[attr].BufferObj,
-                                       exec->vtx.bufferobj);
-
-         varying_inputs |= VERT_BIT(attr);
-      }
+
+   GLintptr buffer_offset;
+   if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
+      assert(exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Pointer);
+      buffer_offset = exec->vtx.bufferobj->Mappings[MAP_INTERNAL].Offset;
+   } else {
+      /* Ptr into ordinary app memory */
+      buffer_offset = (GLbyte *)exec->vtx.buffer_map - (GLbyte *)NULL;
+   }
+
+   const gl_vertex_processing_mode mode = ctx->VertexProgram._VPMode;
+
+   /* Compute the bitmasks of vao_enabled arrays */
+   GLbitfield vao_enabled = _vbo_get_vao_enabled_from_vbo(mode, exec->vtx.enabled);
+
+   /* At first disable arrays no longer needed */
+   GLbitfield mask = vao->_Enabled & ~vao_enabled;
+   while (mask) {
+      const int vao_attr = u_bit_scan(&mask);
+      _mesa_disable_vertex_array_attrib(ctx, vao, vao_attr, false);
    }
+   assert((~vao_enabled & vao->_Enabled) == 0);
 
-   _mesa_set_varying_vp_inputs(ctx, varying_inputs);
+   /* Bind the buffer object */
+   _mesa_bind_vertex_buffer(ctx, vao, 0, exec->vtx.bufferobj, buffer_offset,
+                            exec->vtx.vertex_size*sizeof(GLfloat), false);
+
+   /* Retrieve the mapping from VBO_ATTRIB to VERT_ATTRIB space
+    * Note that the position/generic0 aliasing is done in the VAO.
+    */
+   const GLubyte *const vao_to_vbo_map = _vbo_attribute_alias_map[mode];
+   /* Now set the enabled arrays */
+   mask = vao_enabled;
+   while (mask) {
+      const int vao_attr = u_bit_scan(&mask);
+      const GLubyte vbo_attr = vao_to_vbo_map[vao_attr];
+
+      const GLubyte size = exec->vtx.attrsz[vbo_attr];
+      const GLenum16 type = exec->vtx.attrtype[vbo_attr];
+      const GLuint offset = (GLuint)((GLbyte *)exec->vtx.attrptr[vbo_attr] -
+                                     (GLbyte *)exec->vtx.vertex);
+
+      /* Set and enable */
+      _vbo_set_attrib_format(ctx, vao, vao_attr, buffer_offset,
+                             size, type, offset);
+      if ((vao->_Enabled & VERT_BIT(vao_attr)) == 0)
+         _mesa_enable_vertex_array_attrib(ctx, vao, vao_attr, false);
+
+      /* The vao is initially created with all bindings set to 0. */
+      assert(vao->VertexAttrib[vao_attr].BufferBindingIndex == 0);
+   }
+   assert(vao_enabled == vao->_Enabled);
+   assert(!_mesa_is_bufferobj(exec->vtx.bufferobj) ||
+          (vao_enabled & ~vao->VertexAttribBufferMask) == 0);
+
+   _mesa_update_vao_derived_arrays(ctx, vao);
+   vao->NewArrays = 0;
+
+   _mesa_set_draw_vao(ctx, vao, _vbo_get_vao_filter(mode));
+   /* The exec VAO is not immutable, so we need to set manually */
    ctx->NewDriverState |= ctx->DriverFlags.NewArray;
+
+   _mesa_set_drawing_arrays(ctx, vbo->draw_arrays.inputs);
+   /* Finally update the inputs array */
+   _vbo_update_inputs(ctx, &vbo->draw_arrays);
 }
 
 
@@ -379,6 +392,8 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
 
          vbo_exec_vtx_unmap(exec);
 
+         assert(ctx->NewState == 0);
+
          if (0)
             printf("%s %d %d\n", __func__, exec->vtx.prim_count,
                    exec->vtx.vert_count);
diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h
index 2640f3e21f..1f3d31f577 100644
--- a/src/mesa/vbo/vbo_private.h
+++ b/src/mesa/vbo/vbo_private.h
@@ -48,6 +48,8 @@ struct vbo_context {
    /* The array of inputs used for _DrawVAO draws. */
    struct vbo_inputs draw_arrays;
 
+   struct gl_vertex_array_object *VAO;
+
    struct vbo_exec_context exec;
    struct vbo_save_context save;
 




More information about the mesa-commit mailing list