summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorFredrik Höglund <[email protected]>2012-06-18 22:50:01 +0200
committerBrian Paul <[email protected]>2012-06-19 07:57:22 -0600
commitae5d7d5e8970f90b9713897387d7d46a2b4485ab (patch)
tree613e018da02dea4c833b03259ecf1c5c9e80ed58 /src/mesa
parentee99647e02fe5b947838cfea276f095775eb1537 (diff)
mesa: Add support for GL_ARB_base_instance
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/dd.h10
-rw-r--r--src/mesa/main/dlist.c45
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/mtypes.h1
-rw-r--r--src/mesa/main/vtxfmt.c3
-rw-r--r--src/mesa/vbo/vbo.h1
-rw-r--r--src/mesa/vbo/vbo_exec_api.c1
-rw-r--r--src/mesa/vbo/vbo_exec_array.c114
-rw-r--r--src/mesa/vbo/vbo_save_api.c2
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c6
10 files changed, 173 insertions, 11 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 1582a8c81ec..5bcf36bfa71 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -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);
/*@}*/
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index e04f7ae6bbe..a0d84cfdc55 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -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
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 0e8178397d9..07931614500 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -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 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 3d18b7c4869..d52ab151aa4 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -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;
diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c
index 6fb016b9edf..a27596a9864 100644
--- a/src/mesa/main/vtxfmt.c
+++ b/src/mesa/main/vtxfmt.c
@@ -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 */
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h
index 4387e10b7b5..eb06bf9b5ac 100644
--- a/src/mesa/vbo/vbo.h
+++ b/src/mesa/vbo/vbo.h
@@ -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
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 28d2c4de902..bfa1b1db826 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -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;
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index 3fb7c6480bf..ebf00853621 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -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,7 +703,7 @@ 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);
@@ -710,6 +711,40 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei 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
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index f202375caa4..b2c9dd5f027 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -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);
diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c
index 00464049ddd..686b30a7663 100644
--- a/src/mesa/vbo/vbo_split_inplace.c
+++ b/src/mesa/vbo/vbo_split_inplace.c
@@ -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);