mesa: Add support for GL_ARB_base_instance
authorFredrik Höglund <fredrik@kde.org>
Mon, 18 Jun 2012 20:50:01 +0000 (22:50 +0200)
committerBrian Paul <brianp@vmware.com>
Tue, 19 Jun 2012 13:57:22 +0000 (07:57 -0600)
Reviewed-by: Brian Paul <brianp@vmware.com>
13 files changed:
src/mapi/glapi/gen/ARB_base_instance.xml [new file with mode: 0644]
src/mapi/glapi/gen/Makefile
src/mapi/glapi/gen/gl_API.xml
src/mesa/main/dd.h
src/mesa/main/dlist.c
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/vtxfmt.c
src/mesa/vbo/vbo.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_split_inplace.c

diff --git a/src/mapi/glapi/gen/ARB_base_instance.xml b/src/mapi/glapi/gen/ARB_base_instance.xml
new file mode 100644 (file)
index 0000000..8e81553
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_ARB_base_instance" number="107">
+
+  <function name="DrawArraysInstancedBaseInstance" offset="assign">
+    <param name="mode" type="GLenum"/>
+    <param name="first" type="GLint"/>
+    <param name="count" type="GLsizei"/>
+    <param name="primcount" type="GLsizei"/>
+    <param name="baseinstance" type="GLuint"/>
+  </function>
+
+  <function name="DrawElementsInstancedBaseInstance" offset="assign">
+    <param name="mode" type="GLenum"/>
+    <param name="count" type="GLsizei"/>
+    <param name="type" type="GLenum"/>
+    <param name="indices" type="const GLvoid *"/>
+    <param name="primcount" type="GLsizei"/>
+    <param name="baseinstance" type="GLuint"/>
+  </function>
+
+  <function name="DrawElementsInstancedBaseVertexBaseInstance" offset="assign">
+    <param name="mode" type="GLenum"/>
+    <param name="count" type="GLsizei"/>
+    <param name="type" type="GLenum"/>
+    <param name="indices" type="const GLvoid *"/>
+    <param name="primcount" type="GLsizei"/>
+    <param name="basevertex" type="GLint"/>
+    <param name="baseinstance" type="GLuint"/>
+  </function>
+
+</category>
+
+</OpenGLAPI>
index 75dbb14468c589f027d04c31f0927c7a9b58e187..0ac7989575192ba83e035eb054c8bcfb78b18766 100644 (file)
@@ -63,6 +63,7 @@ XORG_OUTPUTS = \
 
 API_XML = \
        gl_API.xml \
+       ARB_base_instance.xml \
        ARB_color_buffer_float.xml \
        ARB_copy_buffer.xml \
        ARB_debug_output.xml \
index 4bd0fc6b255983a49f9c2df22106be0f443122a7..c96b2a00fd7131636117569277254acf05f3bc8b 100644 (file)
 
 <!-- ARB extensions #106...#116 -->
 
-<xi:include href="ARB_texture_storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="ARB_base_instance.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<xi:include href="ARB_texture_storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
 <!-- Non-ARB extensions sorted by extension number. -->
 
index 1582a8c81ec9ce7f54ea3b0f1c52ed87e4c50610..5bcf36bfa71d0e2519e79a6c9950e97b579aab17 100644 (file)
@@ -1029,12 +1029,22 @@ typedef struct {
                                                   const GLint *basevertex);
    void (GLAPIENTRYP DrawArraysInstanced)(GLenum mode, GLint first,
                                           GLsizei count, GLsizei primcount);
+   void (GLAPIENTRYP DrawArraysInstancedBaseInstance)(GLenum mode, GLint first,
+                                                      GLsizei count, GLsizei primcount,
+                                                      GLuint baseinstance);
    void (GLAPIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count,
                                             GLenum type, const GLvoid *indices,
                                             GLsizei primcount);
+   void (GLAPIENTRYP DrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count,
+                                                        GLenum type, const GLvoid *indices,
+                                                        GLsizei primcount, GLuint baseinstance);
    void (GLAPIENTRYP DrawElementsInstancedBaseVertex)(GLenum mode, GLsizei count,
                                             GLenum type, const GLvoid *indices,
                                             GLsizei primcount, GLint basevertex);
+   void (GLAPIENTRYP DrawElementsInstancedBaseVertexBaseInstance)(GLenum mode, GLsizei count,
+                                                                  GLenum type, const GLvoid *indices,
+                                                                  GLsizei primcount, GLint basevertex,
+                                                                  GLuint baseinstance);
    void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint name);
    /*@}*/
 
index e04f7ae6bbe947ce4f69b5939c602adc11a9a995..a0d84cfdc55857c9073ce456ac32fb57911838bd 100644 (file)
@@ -1337,6 +1337,46 @@ save_DrawElementsInstancedBaseVertexARB(GLenum mode,
               "glDrawElementsInstancedBaseVertex() during display list compile");
 }
 
+/* GL_ARB_base_instance. */
+static void GLAPIENTRY
+save_DrawArraysInstancedBaseInstance(GLenum mode,
+                                     GLint first,
+                                     GLsizei count,
+                                     GLsizei primcount,
+                                     GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawArraysInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseInstance(GLenum mode,
+                                       GLsizei count,
+                                       GLenum type,
+                                       const void *indices,
+                                       GLsizei primcount,
+                                       GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstancedBaseInstance() during display list compile");
+}
+
+static void APIENTRY
+save_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
+                                                 GLsizei count,
+                                                 GLenum type,
+                                                 const void *indices,
+                                                 GLsizei primcount,
+                                                 GLint basevertex,
+                                                 GLuint baseinstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+              "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile");
+}
+
 static void invalidate_saved_current_state( struct gl_context *ctx )
 {
    GLint i;
@@ -10816,6 +10856,11 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt)
    /* GL_ARB_draw_elements_base_vertex */
    vfmt->DrawElementsInstancedBaseVertex = save_DrawElementsInstancedBaseVertexARB;
 
+   /* GL_ARB_base_instance */
+   vfmt->DrawArraysInstancedBaseInstance = save_DrawArraysInstancedBaseInstance;
+   vfmt->DrawElementsInstancedBaseInstance = save_DrawElementsInstancedBaseInstance;
+   vfmt->DrawElementsInstancedBaseVertexBaseInstance = save_DrawElementsInstancedBaseVertexBaseInstance;
+
    /* The driver is required to implement these as
     * 1) They can probably do a better job.
     * 2) A lot of new mechanisms would have to be added to this module
index 0e8178397d9e90a5825fc3f0274faa530da5d3b7..07931614500ec83860e68de09f7dce6001010d1a 100644 (file)
@@ -78,6 +78,7 @@ struct extension {
 static const struct extension extension_table[] = {
    /* ARB Extensions */
    { "GL_ARB_ES2_compatibility",                   o(ARB_ES2_compatibility),                   GL,             2009 },
+   { "GL_ARB_base_instance",                       o(ARB_base_instance),                       GL,             2011 },
    { "GL_ARB_blend_func_extended",                 o(ARB_blend_func_extended),                 GL,             2009 },
    { "GL_ARB_color_buffer_float",                  o(ARB_color_buffer_float),                  GL,             2004 },
    { "GL_ARB_copy_buffer",                         o(ARB_copy_buffer),                         GL,             2008 },
index 3d18b7c4869ab9fdeb6789009b12fa9188adcdb5..d52ab151aa4c538c919c432b394f28956bfd73a7 100644 (file)
@@ -2869,6 +2869,7 @@ struct gl_extensions
    GLboolean dummy_true;  /* Set true by _mesa_init_extensions(). */
    GLboolean dummy_false; /* Set false by _mesa_init_extensions(). */
    GLboolean ARB_ES2_compatibility;
+   GLboolean ARB_base_instance;
    GLboolean ARB_blend_func_extended;
    GLboolean ARB_color_buffer_float;
    GLboolean ARB_conservative_depth;
index 6fb016b9edf02aa9deca0da23ba27cff0603deeb..a27596a9864992c949245ecb225260a33bffd48b 100644 (file)
@@ -105,8 +105,11 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
    SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex);
    SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex);
    SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced);
+   SET_DrawArraysInstancedBaseInstance(tab, vfmt->DrawArraysInstancedBaseInstance);
    SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced);
+   SET_DrawElementsInstancedBaseInstance(tab, vfmt->DrawElementsInstancedBaseInstance);
    SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex);
+   SET_DrawElementsInstancedBaseVertexBaseInstance(tab, vfmt->DrawElementsInstancedBaseVertexBaseInstance);
    SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback);
 
    /* GL_NV_vertex_program */
index 4387e10b7b51400a882aa5809b9411876f6e395b..eb06bf9b5acffecdbe3fa9126f6d8474a3895641 100644 (file)
@@ -51,6 +51,7 @@ struct _mesa_prim {
    GLuint count;
    GLint basevertex;
    GLsizei num_instances;
+   GLuint base_instance;
 };
 
 /* Would like to call this a "vbo_index_buffer", but this would be
index 28d2c4de9021e93e0332a1fd5d4b6acf6b85eb36..bfa1b1db8266d1c2c10d63ef71f1cdb33fbfc50c 100644 (file)
@@ -827,6 +827,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
       exec->vtx.prim[i].start = exec->vtx.vert_count;
       exec->vtx.prim[i].count = 0;
       exec->vtx.prim[i].num_instances = 1;
+      exec->vtx.prim[i].base_instance = 0;
 
       ctx->Driver.CurrentExecPrimitive = mode;
    }
index 3fb7c6480bf5ba0a376280f2bd339c06d14ca928..ebf008536218d6e82c1c09e7b3d26b2014f79a84 100644 (file)
@@ -581,7 +581,7 @@ vbo_handle_primitive_restart(struct gl_context *ctx,
  */
 static void
 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
-                GLsizei count, GLuint numInstances)
+                GLsizei count, GLuint numInstances, GLuint baseInstance)
 {
    struct vbo_context *vbo = vbo_context(ctx);
    struct vbo_exec_context *exec = &vbo->exec;
@@ -595,6 +595,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
    prim[0].end = 1;
    prim[0].mode = mode;
    prim[0].num_instances = numInstances;
+   prim[0].base_instance = baseInstance;
 
    /* Implement the primitive restart index */
    if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) {
@@ -673,7 +674,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
    if (0)
       check_draw_arrays_data(ctx, start, count);
 
-   vbo_draw_arrays(ctx, mode, start, count, 1);
+   vbo_draw_arrays(ctx, mode, start, count, 1, 0);
 
    if (0)
       print_draw_arrays(ctx, mode, start, count);
@@ -702,13 +703,47 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
    if (0)
       check_draw_arrays_data(ctx, start, count);
 
-   vbo_draw_arrays(ctx, mode, start, count, numInstances);
+   vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
 
    if (0)
       print_draw_arrays(ctx, mode, start, count);
 }
 
 
+/**
+ * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
+ */
+static void GLAPIENTRY
+vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
+                                         GLsizei numInstances, GLuint baseInstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_DRAW)
+      _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
+                  _mesa_lookup_enum_by_nr(mode), first, count,
+                  numInstances, baseInstance);
+
+   if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
+                                           numInstances))
+      return;
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!_mesa_valid_to_render(ctx, "glDrawArraysInstancedBaseInstance"))
+      return;
+
+   if (0)
+      check_draw_arrays_data(ctx, first, count);
+
+   vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
+
+   if (0)
+      print_draw_arrays(ctx, mode, first, count);
+}
+
+
+
 /**
  * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
  * For debugging.
@@ -779,7 +814,8 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
                                GLuint start, GLuint end,
                                GLsizei count, GLenum type,
                                const GLvoid *indices,
-                               GLint basevertex, GLint numInstances)
+                               GLint basevertex, GLint numInstances,
+                               GLuint baseInstance)
 {
    struct vbo_context *vbo = vbo_context(ctx);
    struct vbo_exec_context *exec = &vbo->exec;
@@ -803,6 +839,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
    prim[0].indexed = 1;
    prim[0].basevertex = basevertex;
    prim[0].num_instances = numInstances;
+   prim[0].base_instance = baseInstance;
 
    /* Need to give special consideration to rendering a range of
     * indices starting somewhere above zero.  Typically the
@@ -927,7 +964,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
 #endif
 
    vbo_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end,
-                                  count, type, indices, basevertex, 1);
+                                  count, type, indices, basevertex, 1, 0);
 }
 
 
@@ -971,7 +1008,7 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
       return;
 
    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
-                                  count, type, indices, 0, 1);
+                                  count, type, indices, 0, 1, 0);
 }
 
 
@@ -996,7 +1033,7 @@ vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
       return;
 
    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
-                                  count, type, indices, basevertex, 1);
+                                  count, type, indices, basevertex, 1, 0);
 }
 
 
@@ -1021,9 +1058,10 @@ vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
       return;
 
    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
-                                  count, type, indices, 0, numInstances);
+                                  count, type, indices, 0, numInstances, 0);
 }
 
+
 /**
  * Called by glDrawElementsInstancedBaseVertex() in immediate mode.
  */
@@ -1047,7 +1085,59 @@ vbo_exec_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type
       return;
 
    vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
-                                  count, type, indices, basevertex, numInstances);
+                                  count, type, indices, basevertex, numInstances, 0);
+}
+
+
+/**
+ * Called by glDrawElementsInstancedBaseInstance() in immediate mode.
+ */
+static void GLAPIENTRY
+vbo_exec_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type,
+                                           const GLvoid *indices, GLsizei numInstances,
+                                           GLuint baseInstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_DRAW)
+      _mesa_debug(ctx, "glDrawElementsInstancedBaseInstance(%s, %d, %s, %p, %d, %d)\n",
+                  _mesa_lookup_enum_by_nr(mode), count,
+                  _mesa_lookup_enum_by_nr(type), indices,
+                  numInstances, baseInstance);
+
+   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
+                                             numInstances, 0))
+      return;
+
+   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+                                   count, type, indices, 0, numInstances,
+                                   baseInstance);
+}
+
+
+/**
+ * Called by glDrawElementsInstancedBaseVertexBaseInstance() in immediate mode.
+ */
+static void GLAPIENTRY
+vbo_exec_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei count, GLenum type,
+                                                     const GLvoid *indices, GLsizei numInstances,
+                                                     GLint basevertex, GLuint baseInstance)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (MESA_VERBOSE & VERBOSE_DRAW)
+      _mesa_debug(ctx, "glDrawElementsInstancedBaseVertexBaseInstance(%s, %d, %s, %p, %d, %d, %d)\n",
+                  _mesa_lookup_enum_by_nr(mode), count,
+                  _mesa_lookup_enum_by_nr(type), indices,
+                  numInstances, basevertex, baseInstance);
+
+   if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
+                                             numInstances, basevertex))
+      return;
+
+   vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+                                   count, type, indices, basevertex, numInstances,
+                                   baseInstance);
 }
 
 
@@ -1128,6 +1218,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
         prim[i].count = count[i];
         prim[i].indexed = 1;
          prim[i].num_instances = 1;
+         prim[i].base_instance = 0;
         if (basevertex != NULL)
            prim[i].basevertex = basevertex[i];
         else
@@ -1154,6 +1245,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
         prim[0].count = count[i];
         prim[0].indexed = 1;
          prim[0].num_instances = 1;
+         prim[0].base_instance = 0;
         if (basevertex != NULL)
            prim[0].basevertex = basevertex[i];
         else
@@ -1236,6 +1328,7 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
    prim[0].end = 1;
    prim[0].mode = mode;
    prim[0].num_instances = numInstances;
+   prim[0].base_instance = 0;
 
    /* Maybe we should do some primitive splitting for primitive restart
     * (like in DrawArrays), but we have no way to know how many vertices
@@ -1295,8 +1388,11 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
    exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
    exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
    exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
+   exec->vtxfmt.DrawArraysInstancedBaseInstance = vbo_exec_DrawArraysInstancedBaseInstance;
    exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
+   exec->vtxfmt.DrawElementsInstancedBaseInstance = vbo_exec_DrawElementsInstancedBaseInstance;
    exec->vtxfmt.DrawElementsInstancedBaseVertex = vbo_exec_DrawElementsInstancedBaseVertex;
+   exec->vtxfmt.DrawElementsInstancedBaseVertexBaseInstance = vbo_exec_DrawElementsInstancedBaseVertexBaseInstance;
 #if FEATURE_EXT_transform_feedback
    exec->vtxfmt.DrawTransformFeedback = vbo_exec_DrawTransformFeedback;
 #endif
index f202375caa4613fb781b74ca96e2134b76b78088..b2c9dd5f027b6f9a03898422effe9b4b9ee06503 100644 (file)
@@ -471,6 +471,7 @@ _save_wrap_buffers(struct gl_context *ctx)
    save->prim[0].start = 0;
    save->prim[0].count = 0;
    save->prim[0].num_instances = 1;
+   save->prim[0].base_instance = 0;
    save->prim_count = 1;
 }
 
@@ -907,6 +908,7 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
    save->prim[i].start = save->vert_count;
    save->prim[i].count = 0;
    save->prim[i].num_instances = 1;
+   save->prim[i].base_instance = 0;
 
    if (save->out_of_memory) {
       _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
index 00464049dddf62a77890cfa3fa838178745ab956..686b30a7663b9ed591c576aa30ddb53e682ee98f 100644 (file)
@@ -180,13 +180,14 @@ static void split_prims( struct split_context *split)
 
            nr = MIN2( available, remaining );
            nr -= (nr - first) % incr;
-           
+
            outprim->mode = prim->mode;
            outprim->begin = (j == 0 && prim->begin);
            outprim->end = (nr == remaining && prim->end);
            outprim->start = prim->start + j;
            outprim->count = nr;
             outprim->num_instances = prim->num_instances;
+            outprim->base_instance = prim->base_instance;
 
            update_index_bounds(split, outprim);
 
@@ -225,12 +226,13 @@ static void split_prims( struct split_context *split)
         ib.type = GL_UNSIGNED_INT;
         ib.obj = split->ctx->Shared->NullBufferObj;
         ib.ptr = elts;
-           
+
         tmpprim = *prim;
         tmpprim.indexed = 1;
         tmpprim.start = 0;
         tmpprim.count = count;
          tmpprim.num_instances = 1;
+         tmpprim.base_instance = 0;
 
         flush_vertex(split);