mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 13:38:06 +02:00
mesa: implement core Mesa support for GL_ARB_draw_instanced
This commit is contained in:
parent
cf3193ad1c
commit
3b7ac45162
7 changed files with 118 additions and 4 deletions
|
|
@ -1186,6 +1186,11 @@ typedef struct {
|
|||
const GLvoid **indices,
|
||||
GLsizei primcount,
|
||||
const GLint *basevertex);
|
||||
void (GLAPIENTRYP DrawArraysInstanced)(GLenum mode, GLint first,
|
||||
GLsizei count, GLsizei primcount);
|
||||
void (GLAPIENTRYP DrawElementsInstanced)(GLenum mode, GLsizei count,
|
||||
GLenum type, const GLvoid *indices,
|
||||
GLsizei primcount);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
|
|||
SET_DrawElementsBaseVertex(tab, vfmt->DrawElementsBaseVertex);
|
||||
SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex);
|
||||
SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex);
|
||||
SET_DrawArraysInstanced(tab, vfmt->DrawArraysInstanced);
|
||||
SET_DrawElementsInstanced(tab, vfmt->DrawElementsInstanced);
|
||||
|
||||
/* GL_NV_vertex_program */
|
||||
SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV);
|
||||
|
|
|
|||
|
|
@ -391,6 +391,25 @@ static void GLAPIENTRY TAG(MultiDrawElementsBaseVertex)( GLenum mode,
|
|||
primcount, basevertex ));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(DrawArraysInstanced)(GLenum mode, GLint first,
|
||||
GLsizei count, GLsizei primcount)
|
||||
{
|
||||
PRE_LOOPBACK( DrawArraysInstanced );
|
||||
CALL_DrawArraysInstanced(GET_DISPATCH(), (mode, first, count, primcount));
|
||||
}
|
||||
|
||||
static void GLAPIENTRY
|
||||
TAG(DrawElementsInstanced)(GLenum mode, GLsizei count,
|
||||
GLenum type, const GLvoid *indices,
|
||||
GLsizei primcount)
|
||||
{
|
||||
PRE_LOOPBACK( DrawElementsInstanced );
|
||||
CALL_DrawElementsInstanced(GET_DISPATCH(),
|
||||
(mode, count, type, indices, primcount));
|
||||
}
|
||||
|
||||
|
||||
static void GLAPIENTRY TAG(EvalMesh1)( GLenum mode, GLint i1, GLint i2 )
|
||||
{
|
||||
PRE_LOOPBACK( EvalMesh1 );
|
||||
|
|
@ -574,6 +593,8 @@ static GLvertexformat TAG(vtxfmt) = {
|
|||
TAG(DrawElementsBaseVertex),
|
||||
TAG(DrawRangeElementsBaseVertex),
|
||||
TAG(MultiDrawElementsBaseVertex),
|
||||
TAG(DrawArraysInstanced),
|
||||
TAG(DrawElementsInstanced),
|
||||
TAG(EvalMesh1),
|
||||
TAG(EvalMesh2)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ struct _mesa_prim {
|
|||
GLuint start;
|
||||
GLuint count;
|
||||
GLint basevertex;
|
||||
GLsizei num_instances;
|
||||
};
|
||||
|
||||
/* Would like to call this a "vbo_index_buffer", but this would be
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
|
|||
exec->vtx.prim[i].pad = 0;
|
||||
exec->vtx.prim[i].start = exec->vtx.vert_count;
|
||||
exec->vtx.prim[i].count = 0;
|
||||
exec->vtx.prim[i].num_instances = 1;
|
||||
|
||||
ctx->Driver.CurrentExecPrimitive = mode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -520,6 +520,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
prim[0].count = count;
|
||||
prim[0].indexed = 0;
|
||||
prim[0].basevertex = 0;
|
||||
prim[0].num_instances = 1;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
|
||||
GL_TRUE, start, start + count - 1 );
|
||||
|
|
@ -532,6 +533,62 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
|
|||
}
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
|
||||
GLsizei primcount)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
struct vbo_context *vbo = vbo_context(ctx);
|
||||
struct vbo_exec_context *exec = &vbo->exec;
|
||||
struct _mesa_prim prim[1];
|
||||
|
||||
if (MESA_VERBOSE & VERBOSE_DRAW)
|
||||
_mesa_debug(ctx, "glDrawArraysInstanced(%s, %d, %d, %d)\n",
|
||||
_mesa_lookup_enum_by_nr(mode), start, count, primcount);
|
||||
|
||||
if (!_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, primcount))
|
||||
return;
|
||||
|
||||
FLUSH_CURRENT( ctx, 0 );
|
||||
|
||||
if (!_mesa_valid_to_render(ctx, "glDrawArraysInstanced")) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0 /* debug */
|
||||
check_draw_arrays_data(ctx, start, count);
|
||||
#endif
|
||||
|
||||
bind_arrays( ctx );
|
||||
|
||||
/* Again... because we may have changed the bitmask of per-vertex varying
|
||||
* attributes. If we regenerate the fixed-function vertex program now
|
||||
* we may be able to prune down the number of vertex attributes which we
|
||||
* need in the shader.
|
||||
*/
|
||||
if (ctx->NewState)
|
||||
_mesa_update_state( ctx );
|
||||
|
||||
prim[0].begin = 1;
|
||||
prim[0].end = 1;
|
||||
prim[0].weak = 0;
|
||||
prim[0].pad = 0;
|
||||
prim[0].mode = mode;
|
||||
prim[0].start = start;
|
||||
prim[0].count = count;
|
||||
prim[0].indexed = 0;
|
||||
prim[0].basevertex = 0;
|
||||
prim[0].num_instances = primcount;
|
||||
|
||||
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
|
||||
GL_TRUE, start, start + count - 1 );
|
||||
|
||||
#if 0 /* debug */
|
||||
print_draw_arrays(ctx, exec, mode, start, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Map GL_ELEMENT_ARRAY_BUFFER and print contents.
|
||||
*/
|
||||
|
|
@ -595,7 +652,7 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
|
|||
GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type,
|
||||
const GLvoid *indices,
|
||||
GLint basevertex)
|
||||
GLint basevertex, GLint primcount)
|
||||
{
|
||||
struct vbo_context *vbo = vbo_context(ctx);
|
||||
struct vbo_exec_context *exec = &vbo->exec;
|
||||
|
|
@ -628,6 +685,7 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
|
|||
prim[0].count = count;
|
||||
prim[0].indexed = 1;
|
||||
prim[0].basevertex = basevertex;
|
||||
prim[0].num_instances = primcount;
|
||||
|
||||
/* Need to give special consideration to rendering a range of
|
||||
* indices starting somewhere above zero. Typically the
|
||||
|
|
@ -769,7 +827,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
|
|||
#endif
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
|
||||
count, type, indices, basevertex);
|
||||
count, type, indices, basevertex, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -805,7 +863,7 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
|
|||
return;
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
|
||||
count, type, indices, 0);
|
||||
count, type, indices, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -825,7 +883,27 @@ vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
|
|||
return;
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
|
||||
count, type, indices, basevertex);
|
||||
count, type, indices, basevertex, 1);
|
||||
}
|
||||
|
||||
|
||||
static void GLAPIENTRY
|
||||
vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
|
||||
const GLvoid *indices, GLsizei primcount)
|
||||
{
|
||||
GET_CURRENT_CONTEXT(ctx);
|
||||
|
||||
if (MESA_VERBOSE & VERBOSE_DRAW)
|
||||
_mesa_debug(ctx, "glDrawElementsInstanced(%s, %d, %s, %p, %d)\n",
|
||||
_mesa_lookup_enum_by_nr(mode), count,
|
||||
_mesa_lookup_enum_by_nr(type), indices, primcount);
|
||||
|
||||
if (!_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, indices,
|
||||
primcount))
|
||||
return;
|
||||
|
||||
vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
|
||||
count, type, indices, 0, primcount);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -926,6 +1004,7 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
|
|||
prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
|
||||
prim[i].count = count[i];
|
||||
prim[i].indexed = 1;
|
||||
prim[i].num_instances = 1;
|
||||
if (basevertex != NULL)
|
||||
prim[i].basevertex = basevertex[i];
|
||||
else
|
||||
|
|
@ -950,6 +1029,7 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
|
|||
prim[0].start = 0;
|
||||
prim[0].count = count[i];
|
||||
prim[0].indexed = 1;
|
||||
prim[0].num_instances = 1;
|
||||
if (basevertex != NULL)
|
||||
prim[0].basevertex = basevertex[i];
|
||||
else
|
||||
|
|
@ -1024,6 +1104,8 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
|
|||
exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
|
||||
exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
|
||||
exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
|
||||
exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
|
||||
exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
|
||||
#else
|
||||
exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
|
||||
exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
|
||||
|
|
|
|||
|
|
@ -418,6 +418,7 @@ static void _save_wrap_buffers( GLcontext *ctx )
|
|||
save->prim[0].pad = 0;
|
||||
save->prim[0].start = 0;
|
||||
save->prim[0].count = 0;
|
||||
save->prim[0].num_instances = 1;
|
||||
save->prim_count = 1;
|
||||
}
|
||||
|
||||
|
|
@ -773,6 +774,7 @@ GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode )
|
|||
save->prim[i].pad = 0;
|
||||
save->prim[i].start = save->vert_count;
|
||||
save->prim[i].count = 0;
|
||||
save->prim[i].num_instances = 1;
|
||||
|
||||
_mesa_install_save_vtxfmt( ctx, &save->vtxfmt );
|
||||
ctx->Driver.SaveNeedFlush = 1;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue