mesa/es3: Add support for GL_PRIMITIVE_RESTART_FIXED_INDEX
authorIan Romanick <ian.d.romanick@intel.com>
Sat, 11 Aug 2012 05:28:27 +0000 (22:28 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 11 Jan 2013 18:57:25 +0000 (10:57 -0800)
This requires some derived state.  The cut vertex used is either the
value specified by glPrimitiveRestartIndex or it's hard-coded to ~0.
The derived state gl_array_attrib::_RestartIndex captures this value.
In addition, the derived state gl_array_attrib::_PrimitiveRestart is set
whenever either gl_array_attrib::PrimitiveRestart or
gl_array_attrib::PrimitiveRestartFixedIndex is set.

v2: Use _mesa_is_gles3.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/drivers/dri/i965/brw_primitive_restart.c
src/mesa/main/api_arrayelt.c
src/mesa/main/attrib.c
src/mesa/main/enable.c
src/mesa/main/mtypes.h
src/mesa/main/varray.c
src/mesa/state_tracker/st_draw.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_primitive_restart.c

index 38b52438c097d93cbb1e550b2e981ad00874d349..8c7219d4f925abbc7f68d5ceb3417f10d828f312 100644 (file)
@@ -52,13 +52,13 @@ can_cut_index_handle_restart_index(struct gl_context *ctx,
 
    switch (ib->type) {
    case GL_UNSIGNED_BYTE:
-      cut_index_will_work = (ctx->Array.RestartIndex & 0xff) == 0xff;
+      cut_index_will_work = (ctx->Array._RestartIndex & 0xff) == 0xff;
       break;
    case GL_UNSIGNED_SHORT:
-      cut_index_will_work = (ctx->Array.RestartIndex & 0xffff) == 0xffff;
+      cut_index_will_work = (ctx->Array._RestartIndex & 0xffff) == 0xffff;
       break;
    case GL_UNSIGNED_INT:
-      cut_index_will_work = ctx->Array.RestartIndex == 0xffffffff;
+      cut_index_will_work = ctx->Array._RestartIndex == 0xffffffff;
       break;
    default:
       cut_index_will_work = false;
@@ -157,7 +157,7 @@ brw_handle_primitive_restart(struct gl_context *ctx,
    /* If PrimitiveRestart is not enabled, then we aren't concerned about
     * handling this draw.
     */
-   if (!(ctx->Array.PrimitiveRestart)) {
+   if (!(ctx->Array._PrimitiveRestart)) {
       return GL_FALSE;
    }
 
index 0fa2429976b03ecfb6571a236847a071f4d2edc3..ea3361488cee8260c818c815d03d5e05950198da 100644 (file)
@@ -1636,7 +1636,7 @@ void GLAPIENTRY _ae_ArrayElement( GLint elt )
    /* If PrimitiveRestart is enabled and the index is the RestartIndex
     * then we call PrimitiveRestartNV and return.
     */
-   if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) {
+   if (ctx->Array._PrimitiveRestart && (elt == ctx->Array._RestartIndex)) {
       CALL_PrimitiveRestartNV((struct _glapi_table *)disp, ());
       return;
    }
index a19d610545d39ead8cebbcd1e20981236990721c..d6f298d93c6dc3a32bba9c691a10164ecca5af8d 100644 (file)
@@ -1377,7 +1377,10 @@ copy_array_attrib(struct gl_context *ctx,
    dest->LockFirst = src->LockFirst;
    dest->LockCount = src->LockCount;
    dest->PrimitiveRestart = src->PrimitiveRestart;
+   dest->PrimitiveRestartFixedIndex = src->PrimitiveRestartFixedIndex;
+   dest->_PrimitiveRestart = src->_PrimitiveRestart;
    dest->RestartIndex = src->RestartIndex;
+   dest->_RestartIndex = src->_RestartIndex;
    /* skip NewState */
    /* skip RebindArrays */
 
index b48794f950b58e951897f16ab19826b71df208fc..73257290ed8c1fa6152b4eca8b21cad37f2ff640 100644 (file)
    }
 
 
+static void
+update_derived_primitive_restart_state(struct gl_context *ctx)
+{
+   /* Update derived primitive restart state.
+    */
+   if (ctx->Array.PrimitiveRestart)
+      ctx->Array._RestartIndex = ctx->Array.RestartIndex;
+   else
+      ctx->Array._RestartIndex = ~0;
+
+   ctx->Array._PrimitiveRestart = ctx->Array.PrimitiveRestart
+      || ctx->Array.PrimitiveRestartFixedIndex;
+}
+
 /**
  * Helper to enable/disable client-side state.
  */
@@ -119,6 +133,8 @@ client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
 
    *var = state;
 
+   update_derived_primitive_restart_state(ctx);
+
    if (state)
       arrayObj->_Enabled |= flag;
    else
@@ -967,6 +983,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
          if (ctx->Array.PrimitiveRestart != state) {
             FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
             ctx->Array.PrimitiveRestart = state;
+            update_derived_primitive_restart_state(ctx);
+         }
+         break;
+
+      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+        if (!_mesa_is_gles3(ctx) && !ctx->Extensions.ARB_ES3_compatibility)
+            goto invalid_enum_error;
+         if (ctx->Array.PrimitiveRestartFixedIndex != state) {
+            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+            ctx->Array.PrimitiveRestartFixedIndex = state;
+            update_derived_primitive_restart_state(ctx);
          }
          break;
 
@@ -1542,6 +1569,12 @@ _mesa_IsEnabled( GLenum cap )
          }
          return ctx->Array.PrimitiveRestart;
 
+      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+        if (!_mesa_is_gles3(ctx) && !ctx->Extensions.ARB_ES3_compatibility) {
+            goto invalid_enum_error;
+         }
+         return ctx->Array.PrimitiveRestartFixedIndex;
+
       /* GL3.0 - GL_framebuffer_sRGB */
       case GL_FRAMEBUFFER_SRGB_EXT:
          if (!_mesa_is_desktop_gl(ctx))
index 318dcb548d895650fdc005b2f979109f66cd9dd6..f44ec4947edec52582a395b457180cc001dcfa92 100644 (file)
@@ -1634,9 +1634,20 @@ struct gl_array_attrib
    GLuint LockFirst;            /**< GL_EXT_compiled_vertex_array */
    GLuint LockCount;            /**< GL_EXT_compiled_vertex_array */
 
-   /** GL 3.1 (slightly different from GL_NV_primitive_restart) */
+   /**
+    * \name Primitive restart controls
+    *
+    * Primitive restart is enabled if either \c PrimitiveRestart or
+    * \c PrimitiveRestart is set.  If \c PrimitiveRestart is set, then
+    * \c RestartIndex is used as the cut vertex.  Otherwise ~0 is used.
+    */
+   /*@{*/
    GLboolean PrimitiveRestart;
+   GLboolean PrimitiveRestartFixedIndex;
+   GLboolean _PrimitiveRestart;
    GLuint RestartIndex;
+   GLuint _RestartIndex;
+   /*@}*/
 
    /* GL_ARB_vertex_buffer_object */
    struct gl_buffer_object *ArrayBufferObj;
index 5e4d6c3e638544c86a0213558aadb11f3000bc55..e453b3b0e640186960268d8823f4fa7509fb4b3d 100644 (file)
@@ -1113,9 +1113,10 @@ _mesa_PrimitiveRestartIndex(GLuint index)
 
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
-   if (ctx->Array.RestartIndex != index) {
+   ctx->Array.RestartIndex = index;
+   if (ctx->Array.PrimitiveRestart && ctx->Array._RestartIndex != index) {
       FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
-      ctx->Array.RestartIndex = index;
+      ctx->Array._RestartIndex = index;
    }
 }
 
index 4800e1c879f3ac29f69e71205670e4e1a9ab55a7..7de2bb9b853c79dd5940194f3bbde18b27566517 100644 (file)
@@ -230,8 +230,8 @@ st_draw_vbo(struct gl_context *ctx,
       /* The VBO module handles restart for the non-indexed GLDrawArrays
        * so we only set these fields for indexed drawing:
        */
-      info.primitive_restart = ctx->Array.PrimitiveRestart;
-      info.restart_index = ctx->Array.RestartIndex;
+      info.primitive_restart = ctx->Array._PrimitiveRestart;
+      info.restart_index = ctx->Array._RestartIndex;
    }
    else {
       /* Transform feedback drawing is always non-indexed. */
index 4b2c5298d1c94322c8ccc5359c3451192e3aff0d..7e61f7b31fdae5fbdbd5a878deb5221291d9c399 100644 (file)
@@ -90,8 +90,8 @@ vbo_get_minmax_index(struct gl_context *ctx,
                     GLuint *min_index, GLuint *max_index,
                     const GLuint count)
 {
-   const GLboolean restart = ctx->Array.PrimitiveRestart;
-   const GLuint restartIndex = ctx->Array.RestartIndex;
+   const GLboolean restart = ctx->Array._PrimitiveRestart;
+   const GLuint restartIndex = ctx->Array._RestartIndex;
    const int index_size = vbo_sizeof_ib_type(ib->type);
    const char *indices;
    GLuint i;
@@ -536,7 +536,7 @@ vbo_handle_primitive_restart(struct gl_context *ctx,
 
    if ((ib != NULL) &&
        ctx->Const.PrimitiveRestartInSoftware &&
-       ctx->Array.PrimitiveRestart) {
+       ctx->Array._PrimitiveRestart) {
       /* Handle primitive restart in software */
       vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
    } else {
@@ -572,10 +572,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
    prim[0].base_instance = baseInstance;
 
    /* Implement the primitive restart index */
-   if (ctx->Array.PrimitiveRestart && ctx->Array.RestartIndex < count) {
+   if (ctx->Array._PrimitiveRestart && ctx->Array._RestartIndex < count) {
       GLuint primCount = 0;
 
-      if (ctx->Array.RestartIndex == start) {
+      if (ctx->Array._RestartIndex == start) {
          /* special case: RestartIndex at beginning */
          if (count > 1) {
             prim[0].start = start + 1;
@@ -583,7 +583,7 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
             primCount = 1;
          }
       }
-      else if (ctx->Array.RestartIndex == start + count - 1) {
+      else if (ctx->Array._RestartIndex == start + count - 1) {
          /* special case: RestartIndex at end */
          if (count > 1) {
             prim[0].start = start;
@@ -594,10 +594,10 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
       else {
          /* general case: RestartIndex in middle, split into two prims */
          prim[0].start = start;
-         prim[0].count = ctx->Array.RestartIndex - start;
+         prim[0].count = ctx->Array._RestartIndex - start;
 
          prim[1] = prim[0];
-         prim[1].start = ctx->Array.RestartIndex + 1;
+         prim[1].start = ctx->Array._RestartIndex + 1;
          prim[1].count = count - prim[1].start;
 
          primCount = 2;
index 6f9d61c9bbc271223150e77d3cb4f442dee4687b..a6a0149ca63521238e2d99800b785d22a6a9393e 100644 (file)
@@ -171,7 +171,7 @@ vbo_sw_primitive_restart(struct gl_context *ctx,
    GLuint sub_prim_num;
    GLuint end_index;
    GLuint sub_end_index;
-   GLuint restart_index = ctx->Array.RestartIndex;
+   GLuint restart_index = ctx->Array._RestartIndex;
    struct _mesa_prim temp_prim;
    struct vbo_context *vbo = vbo_context(ctx);
    vbo_draw_func draw_prims_func = vbo->draw_prims;