[Mesa-dev] [PATCH v2 4/4] vbo: fix gl_DrawID handling in glMultiDrawArrays

Nicolai Hähnle nhaehnle at gmail.com
Thu Apr 13 19:29:06 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Fixes a bug in
KHR-GL45.shader_draw_parameters_tests.ShaderMultiDrawArraysParameters.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
---
 src/mesa/vbo/vbo_exec_array.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 6858eb3..e5eeae4 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -397,36 +397,38 @@ vbo_bind_arrays(struct gl_context *ctx)
 
 
 /**
  * Helper function called by the other DrawArrays() functions below.
  * This is where we handle primitive restart for drawing non-indexed
  * arrays.  If primitive restart is enabled, it typically means
  * splitting one DrawArrays() into two.
  */
 static void
 vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
-                GLsizei count, GLuint numInstances, GLuint baseInstance)
+                GLsizei count, GLuint numInstances, GLuint baseInstance,
+                GLuint drawID)
 {
    struct vbo_context *vbo = vbo_context(ctx);
    struct _mesa_prim prim[2];
 
    vbo_bind_arrays(ctx);
 
    /* OpenGL 4.5 says that primitive restart is ignored with non-indexed
     * draws.
     */
    memset(prim, 0, sizeof(prim));
    prim[0].begin = 1;
    prim[0].end = 1;
    prim[0].mode = mode;
    prim[0].num_instances = numInstances;
    prim[0].base_instance = baseInstance;
+   prim[0].draw_id = drawID;
    prim[0].is_indirect = 0;
    prim[0].start = start;
    prim[0].count = count;
 
    vbo->draw_prims(ctx, prim, 1, NULL,
                    GL_TRUE, start, start + count - 1, NULL, 0, NULL);
 
    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
       _mesa_flush(ctx);
    }
@@ -565,21 +567,21 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
    if (MESA_VERBOSE & VERBOSE_DRAW)
       _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
                   _mesa_enum_to_string(mode), start, count);
 
    if (!_mesa_validate_DrawArrays(ctx, mode, count))
       return;
 
    if (0)
       check_draw_arrays_data(ctx, start, count);
 
-   vbo_draw_arrays(ctx, mode, start, count, 1, 0);
+   vbo_draw_arrays(ctx, mode, start, count, 1, 0, 0);
 
    if (0)
       print_draw_arrays(ctx, mode, start, count);
 }
 
 
 /**
  * Called from glDrawArraysInstanced when in immediate mode (not
  * display list mode).
  */
@@ -593,21 +595,21 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
       _mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
                   _mesa_enum_to_string(mode), start, count, numInstances);
 
    if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count,
                                            numInstances))
       return;
 
    if (0)
       check_draw_arrays_data(ctx, start, count);
 
-   vbo_draw_arrays(ctx, mode, start, count, numInstances, 0);
+   vbo_draw_arrays(ctx, mode, start, count, numInstances, 0, 0);
 
    if (0)
       print_draw_arrays(ctx, mode, start, count);
 }
 
 
 /**
  * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
  */
 static void GLAPIENTRY
@@ -623,21 +625,21 @@ vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
                   _mesa_enum_to_string(mode), first, count,
                   numInstances, baseInstance);
 
    if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
                                            numInstances))
       return;
 
    if (0)
       check_draw_arrays_data(ctx, first, count);
 
-   vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);
+   vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance, 0);
 
    if (0)
       print_draw_arrays(ctx, mode, first, count);
 }
 
 
 /**
  * Called from glMultiDrawArrays when in immediate mode.
  */
 static void GLAPIENTRY
@@ -653,21 +655,28 @@ vbo_exec_MultiDrawArrays(GLenum mode, const GLint *first,
                   _mesa_enum_to_string(mode), first, count, primcount);
 
    if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
       return;
 
    for (i = 0; i < primcount; i++) {
       if (count[i] > 0) {
          if (0)
             check_draw_arrays_data(ctx, first[i], count[i]);
 
-         vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0);
+         /* The GL_ARB_shader_draw_parameters spec adds the following after the
+          * pseudo-code describing glMultiDrawArrays:
+          *
+          *    "The index of the draw (<i> in the above pseudo-code) may be
+          *     read by a vertex shader as <gl_DrawIDARB>, as described in
+          *     Section 11.1.3.9."
+          */
+         vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0, i);
 
          if (0)
             print_draw_arrays(ctx, mode, first[i], count[i]);
       }
    }
 }
 
 
 
 /**
@@ -1255,21 +1264,21 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
    if (!_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream,
                                              numInstances)) {
       return;
    }
 
    if (ctx->Driver.GetTransformFeedbackVertexCount &&
        (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount ||
         !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) {
       GLsizei n =
          ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream);
-      vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0);
+      vbo_draw_arrays(ctx, mode, 0, n, numInstances, 0, 0);
       return;
    }
 
    vbo_bind_arrays(ctx);
 
    /* init most fields to zero */
    memset(prim, 0, sizeof(prim));
    prim[0].begin = 1;
    prim[0].end = 1;
    prim[0].mode = mode;
-- 
2.9.3



More information about the mesa-dev mailing list