From 1d1eb9578716913f4133786b30c6e6edc69a8a0c Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 15 Jan 2011 10:32:34 -0700 Subject: [PATCH] mesa: support for GL_ARB_instanced_arrays --- src/mesa/main/api_exec.c | 2 ++ src/mesa/main/dlist.c | 27 ++++++++++++++++++++++++++ src/mesa/main/mtypes.h | 1 + src/mesa/main/varray.c | 42 +++++++++++++++++++++++++++++++++++++--- src/mesa/main/varray.h | 4 ++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index f1e4f7361f4..2f88946fbb0 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c @@ -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; } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 6c0c556ad8d..b28e36ac096 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -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; } diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 1522332e8a1..7b4c1161f5a 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 */ diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index bcde65adc70..29d8a8827e3 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -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; diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index af9324134ec..53e68c89667 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -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, -- 2.30.2