mesa: support for GL_ARB_instanced_arrays
authorBrian Paul <brianp@vmware.com>
Sat, 15 Jan 2011 17:32:34 +0000 (10:32 -0700)
committerBrian Paul <brianp@vmware.com>
Sun, 16 Jan 2011 00:37:41 +0000 (17:37 -0700)
src/mesa/main/api_exec.c
src/mesa/main/dlist.c
src/mesa/main/mtypes.h
src/mesa/main/varray.c
src/mesa/main/varray.h

index f1e4f7361f4c77744e499788f182fe6ee5ca02ad..2f88946fbb0e6a55db1026ae2c16e4e7a4c8f1dc 100644 (file)
@@ -711,6 +711,8 @@ _mesa_create_exec_table(void)
    SET_GetStringi(exec, _mesa_GetStringi);
    SET_ClampColor(exec, _mesa_ClampColorARB);
 
+   /* GL_ARB_instanced_arrays */
+   SET_VertexAttribDivisorARB(exec, _mesa_VertexAttribDivisor);
 
    return exec;
 }
index 6c0c556ad8d54fe2f0b85fbb923aeda5170ed8e2..b28e36ac0963188cb11489614659c3cceccf25cd 100644 (file)
@@ -421,6 +421,9 @@ typedef enum
    OPCODE_ACTIVE_PROGRAM_EXT,
    OPCODE_USE_SHADER_PROGRAM_EXT,
 
+   /* GL_ARB_instanced_arrays */
+   OPCODE_VERTEX_ATTRIB_DIVISOR,
+
    /* The following three are meta instructions */
    OPCODE_ERROR,                /* raise compiled-in error */
    OPCODE_CONTINUE,
@@ -6927,6 +6930,22 @@ exec_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
 }
 
 
+/* GL_ARB_instanced_arrays */
+static void
+save_VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   Node *n;
+   ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+   n = alloc_instruction(ctx, OPCODE_VERTEX_ATTRIB_DIVISOR, 2);
+   if (n) {
+      n[1].ui = index;
+      n[2].ui = divisor;
+   }
+   if (ctx->ExecuteFlag) {
+      CALL_VertexAttribDivisorARB(ctx->Exec, (index, divisor));
+   }
+}
 
 
 
@@ -8080,6 +8099,11 @@ execute_list(struct gl_context *ctx, GLuint list)
             }
             break;
 
+         case OPCODE_VERTEX_ATTRIB_DIVISOR:
+            /* GL_ARB_instanced_arrays */
+            CALL_VertexAttribDivisorARB(ctx->Exec, (n[1].ui, n[2].ui));
+            break;
+
          case OPCODE_CONTINUE:
             n = (Node *) n[1].next;
             break;
@@ -9749,6 +9773,9 @@ _mesa_create_save_table(void)
    (void) save_Uniform4uiv;
 #endif
 
+   /* GL_ARB_instanced_arrays */
+   SET_VertexAttribDivisorARB(table, save_VertexAttribDivisor);
+
    return table;
 }
 
index 1522332e8a11f2e284bd3d8d51e9916dd61382d2..7b4c1161f5af47b562d9ba96f4ae0def67da71c5 100644 (file)
@@ -1546,6 +1546,7 @@ struct gl_client_array
    GLboolean Enabled;          /**< Enabled flag is a boolean */
    GLboolean Normalized;        /**< GL_ARB_vertex_program */
    GLboolean Integer;           /**< Integer-valued? */
+   GLuint InstanceDivisor;      /**< GL_ARB_instanced_arrays */
    GLuint _ElementSize;         /**< size of each element in bytes */
 
    struct gl_buffer_object *BufferObj;/**< GL_ARB_vertex_buffer_object */
index bcde65adc70107948b6a06f37ffdae56d290b15e..29d8a8827e385d78e35a5af0db259f13aab3082d 100644 (file)
@@ -534,11 +534,19 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
       if (ctx->Extensions.EXT_gpu_shader4) {
          return array->Integer;
       }
-      /* fall-through */
+      goto error;
+   case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
+      if (ctx->Extensions.ARB_instanced_arrays) {
+         return array->InstanceDivisor;
+      }
+      goto error;
    default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
-      return 0;
+      ; /* fall-through */
    }
+
+error:
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
+   return 0;
 }
 
 
@@ -1065,6 +1073,33 @@ _mesa_PrimitiveRestartIndex(GLuint index)
 }
 
 
+/**
+ * See GL_ARB_instanced_arrays.
+ * Note that the instance divisor only applies to generic arrays, not
+ * the legacy vertex arrays.
+ */
+void GLAPIENTRY
+_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (!ctx->Extensions.ARB_instanced_arrays) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
+      return;
+   }
+
+   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)",
+                  index);
+      return;
+   }
+
+   ctx->Array.ArrayObj->VertexAttrib[index].InstanceDivisor = divisor;
+}
+
+
+
 /**
  * Copy one client vertex array to another.
  */
@@ -1082,6 +1117,7 @@ _mesa_copy_client_array(struct gl_context *ctx,
    dst->Enabled = src->Enabled;
    dst->Normalized = src->Normalized;
    dst->Integer = src->Integer;
+   dst->InstanceDivisor = src->InstanceDivisor;
    dst->_ElementSize = src->_ElementSize;
    _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
    dst->_MaxElement = src->_MaxElement;
index af9324134ec77b721696eee7fe6aeee5e30909ba..53e68c896671ad8f7f4930275fa0cf4f10912ee8 100644 (file)
@@ -218,6 +218,10 @@ extern void GLAPIENTRY
 _mesa_PrimitiveRestartIndex(GLuint index);
 
 
+extern void GLAPIENTRY
+_mesa_VertexAttribDivisor(GLuint index, GLuint divisor);
+
+
 extern void
 _mesa_copy_client_array(struct gl_context *ctx,
                         struct gl_client_array *dst,