diff options
Diffstat (limited to 'mesalib/src/mesa/vbo/vbo_exec_array.c')
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_exec_array.c | 193 |
1 files changed, 150 insertions, 43 deletions
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 90474da7c..1759e5788 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -30,7 +30,6 @@ #include "main/context.h" #include "main/state.h" #include "main/api_validate.h" -#include "main/api_noop.h" #include "main/varray.h" #include "main/bufferobj.h" #include "main/enums.h" @@ -40,7 +39,8 @@ /** - * Compute min and max elements for glDraw[Range]Elements() calls. + * Compute min and max elements by scanning the index buffer for + * glDraw[Range]Elements() calls. */ void vbo_get_minmax_index(GLcontext *ctx, @@ -112,6 +112,7 @@ vbo_get_minmax_index(GLcontext *ctx, /** * Check that element 'j' of the array has reasonable data. * Map VBO if needed. + * For debugging purposes; not normally used. */ static void check_array_data(GLcontext *ctx, struct gl_client_array *array, @@ -172,6 +173,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array) /** * Examine the array's data for NaNs, etc. + * For debug purposes; not normally used. */ static void check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType, @@ -249,7 +251,7 @@ check_draw_arrays_data(GLcontext *ctx, GLint start, GLsizei count) /** - * Print info/data for glDrawArrays(). + * Print info/data for glDrawArrays(), for debugging. */ static void print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec, @@ -295,6 +297,9 @@ print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec, /** + * Bind the VBO executor to the current vertex array object prior + * to drawing. + * * Just translate the arrayobj into a sane layout. */ static void @@ -334,6 +339,14 @@ bind_array_obj(GLcontext *ctx) } +/** + * Set the vbo->exec->inputs[] pointers to point to the enabled + * vertex arrays. This depends on the current vertex program/shader + * being executed because of whether or not generic vertex arrays + * alias the conventional vertex arrays. + * For arrays that aren't enabled, we set the input[attrib] pointer + * to point at a zero-stride current value "array". + */ static void recalculate_input_bindings(GLcontext *ctx) { @@ -453,27 +466,15 @@ recalculate_input_bindings(GLcontext *ctx) static void bind_arrays(GLcontext *ctx) { -#if 0 - if (ctx->Array.ArrayObj.Name != exec->array.array_obj) { - bind_array_obj(ctx); - recalculate_input_bindings(ctx); - } - else if (exec->array.program_mode != get_program_mode(ctx) || - exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) { - recalculate_input_bindings(ctx); - } -#else bind_array_obj(ctx); recalculate_input_bindings(ctx); -#endif } -/*********************************************************************** - * API functions. +/** + * Called from glDrawArrays when in immediate mode (not display list mode). */ - static void GLAPIENTRY vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) { @@ -520,6 +521,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 ); @@ -533,7 +535,68 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) /** + * Called from glDrawArraysInstanced when in immediate mode (not + * display list mode). + */ +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. + * For debugging. */ static void dump_element_buffer(GLcontext *ctx, GLenum type) @@ -588,14 +651,18 @@ dump_element_buffer(GLcontext *ctx, GLenum type) } -/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */ +/** + * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. + * Do the rendering for a glDrawElements or glDrawRangeElements call after + * we've validated buffer bounds, etc. + */ static void vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode, GLboolean index_bounds_valid, 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 +695,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 @@ -664,6 +732,10 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode, index_bounds_valid, start, end ); } + +/** + * Called by glDrawRangeElementsBaseVertex() in immediate mode. + */ static void GLAPIENTRY vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, @@ -713,7 +785,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, start, end, count, type, indices, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, - ctx->Array.ElementArrayBufferObj->Size); + (int) ctx->Array.ElementArrayBufferObj->Size); } if (0) @@ -739,7 +811,7 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, start, end, count, type, indices, max, ctx->Array.ArrayObj->_MaxElement - 1, ctx->Array.ElementArrayBufferObj->Name, - ctx->Array.ElementArrayBufferObj->Size); + (int) ctx->Array.ElementArrayBufferObj->Size); } } /* XXX we could also find the min index and compare to 'start' @@ -769,10 +841,13 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode, #endif vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end, - count, type, indices, basevertex); + count, type, indices, basevertex, 1); } +/** + * Called by glDrawRangeElements() in immediate mode. + */ static void GLAPIENTRY vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) @@ -790,6 +865,9 @@ vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end, } +/** + * Called by glDrawElements() in immediate mode. + */ static void GLAPIENTRY vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) @@ -805,10 +883,13 @@ 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); } +/** + * Called by glDrawElementsBaseVertex() in immediate mode. + */ static void GLAPIENTRY vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) @@ -825,11 +906,38 @@ 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); +} + + +/** + * Called by glDrawElementsInstanced() in immediate mode. + */ +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); } -/** Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */ +/** + * Inner support for both _mesa_MultiDrawElements() and + * _mesa_MultiDrawRangeElements(). + * This does the actual rendering after we've checked array indexes, etc. + */ static void vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, const GLsizei *count, GLenum type, @@ -861,7 +969,8 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, } /* Decide if we can do this all as one set of primitives sharing the - * same index buffer, or if we have to reset the index pointer per primitive. + * same index buffer, or if we have to reset the index pointer per + * primitive. */ bind_arrays( ctx ); @@ -926,6 +1035,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 +1060,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 @@ -1009,14 +1120,13 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode, } -/*********************************************************************** - * Initialization +/** + * Plug in the immediate-mode vertex array drawing commands into the + * givven vbo_exec_context object. */ - void vbo_exec_array_init( struct vbo_exec_context *exec ) { -#if 1 exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays; exec->vtxfmt.DrawElements = vbo_exec_DrawElements; exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements; @@ -1024,15 +1134,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; -#else - exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays; - exec->vtxfmt.DrawElements = _mesa_noop_DrawElements; - exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements; - exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements; - exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex; - exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex; - exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex; -#endif + exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced; + exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced; } @@ -1043,7 +1146,13 @@ vbo_exec_array_destroy( struct vbo_exec_context *exec ) } -/* This API entrypoint is not ordinarily used */ + +/** + * The following functions are only used for OpenGL ES 1/2 support. + * And some aren't even supported (yet) in ES 1/2. + */ + + void GLAPIENTRY _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) { @@ -1051,7 +1160,6 @@ _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count) } -/* This API entrypoint is not ordinarily used */ void GLAPIENTRY _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) @@ -1059,6 +1167,7 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, vbo_exec_DrawElements(mode, count, type, indices); } + void GLAPIENTRY _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) @@ -1067,7 +1176,6 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, } -/* This API entrypoint is not ordinarily used */ void GLAPIENTRY _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) @@ -1086,7 +1194,6 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, } -/* GL_EXT_multi_draw_arrays */ void GLAPIENTRY _mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount) |