[Mesa-dev] [PATCH 1/2] mesa: move glMultiDrawArray to vbo and fix error handling
Brian Paul
brianp at vmware.com
Fri Apr 7 17:05:04 UTC 2017
On 04/07/2017 10:30 AM, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> When any count[i] is negative, we must skip all draws.
>
> Moving to vbo makes the subsequent change easier.
> ---
> src/mapi/glapi/gen/gl_API.xml | 2 +-
> src/mesa/main/api_validate.c | 38 ++++++++++++++++++++++++++++++++++++++
> src/mesa/main/api_validate.h | 4 ++++
> src/mesa/main/varray.c | 18 ------------------
> src/mesa/vbo/vbo_exec_array.c | 33 +++++++++++++++++++++++++++++++++
> src/mesa/vbo/vbo_save_api.c | 35 +++++++++++++++++++++++++++++++++++
> 6 files changed, 111 insertions(+), 19 deletions(-)
>
> diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
> index c0ee2f2..522d2e5 100644
> --- a/src/mapi/glapi/gen/gl_API.xml
> +++ b/src/mapi/glapi/gen/gl_API.xml
> @@ -10212,21 +10212,21 @@
> </function>
> </category>
>
> <category name="GL_EXT_texture_perturb_normal" number="147">
> <function name="TextureNormalEXT" exec="skip">
> <param name="mode" type="GLenum"/>
> </function>
> </category>
>
> <category name="GL_EXT_multi_draw_arrays" number="148">
> - <function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" alias="MultiDrawArrays">
> + <function name="MultiDrawArraysEXT" es1="1.0" es2="2.0" exec="dynamic" alias="MultiDrawArrays">
> <param name="mode" type="GLenum"/>
> <param name="first" type="const GLint *"/>
> <param name="count" type="const GLsizei *"/>
> <param name="primcount" type="GLsizei"/>
> </function>
>
> <function name="MultiDrawElementsEXT" es1="1.0" es2="2.0" exec="dynamic" marshal="draw"
> marshal_fail="_mesa_glthread_is_non_vbo_draw_elements(ctx)">
> <param name="mode" type="GLenum"/>
> <param name="count" type="const GLsizei *"/>
Does the xml change have anything to do with the code movement? If not,
split the patch?
-Brian
> diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
> index af4f7cb..2f0e159 100644
> --- a/src/mesa/main/api_validate.c
> +++ b/src/mesa/main/api_validate.c
> @@ -906,20 +906,58 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi
> if (numInstances < 0)
> _mesa_error(ctx, GL_INVALID_VALUE,
> "glDrawArraysInstanced(numInstances=%d)", numInstances);
> return GL_FALSE;
> }
>
> return validate_draw_arrays(ctx, "glDrawArraysInstanced", mode, count, 1);
> }
>
>
> +/**
> + * Called to error check the function parameters.
> + *
> + * Note that glMultiDrawArrays is not part of GLES, so there's limited scope
> + * for sharing code with the validation of glDrawArrays.
> + */
> +bool
> +_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
> + const GLsizei *count, GLsizei primcount)
> +{
> + int i;
> +
> + FLUSH_CURRENT(ctx, 0);
> +
> + if (primcount < 0) {
> + _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(primcount=%d)",
> + primcount);
> + return false;
> + }
> +
> + if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawArrays"))
> + return false;
> +
> + if (!check_valid_to_render(ctx, "glMultiDrawArrays"))
> + return false;
> +
> + for (i = 0; i < primcount; ++i) {
> + if (count[i] < 0) {
> + _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawArrays(count[%d]=%d)",
> + i, count[i]);
> + return false;
> + }
> + }
> +
> + return true;
> +}
> +
> +
> GLboolean
> _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
> GLenum mode, GLsizei count, GLenum type,
> const GLvoid *indices, GLsizei numInstances)
> {
> FLUSH_CURRENT(ctx, 0);
>
> if (numInstances < 0) {
> _mesa_error(ctx, GL_INVALID_VALUE,
> "glDrawElementsInstanced(numInstances=%d)", numInstances);
> diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
> index de520c9..93ec93d 100644
> --- a/src/mesa/main/api_validate.h
> +++ b/src/mesa/main/api_validate.h
> @@ -41,20 +41,24 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where);
> extern bool
> _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode);
>
> extern GLboolean
> _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name);
>
>
> extern GLboolean
> _mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count);
>
> +extern bool
> +_mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode,
> + const GLsizei *count, GLsizei primcount);
> +
> extern GLboolean
> _mesa_validate_DrawElements(struct gl_context *ctx,
> GLenum mode, GLsizei count, GLenum type,
> const GLvoid *indices);
>
> extern GLboolean
> _mesa_validate_MultiDrawElements(struct gl_context *ctx,
> GLenum mode, const GLsizei *count,
> GLenum type, const GLvoid * const *indices,
> GLsizei primcount);
> diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c
> index af5abc8..07959a2 100644
> --- a/src/mesa/main/varray.c
> +++ b/src/mesa/main/varray.c
> @@ -1534,38 +1534,20 @@ _mesa_UnlockArraysEXT( void )
> _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
> return;
> }
>
> ctx->Array.LockFirst = 0;
> ctx->Array.LockCount = 0;
> ctx->NewState |= _NEW_ARRAY;
> }
>
>
> -/* GL_EXT_multi_draw_arrays */
> -void GLAPIENTRY
> -_mesa_MultiDrawArrays( GLenum mode, const GLint *first,
> - const GLsizei *count, GLsizei primcount )
> -{
> - GET_CURRENT_CONTEXT(ctx);
> - GLint i;
> -
> - FLUSH_VERTICES(ctx, 0);
> -
> - for (i = 0; i < primcount; i++) {
> - if (count[i] > 0) {
> - CALL_DrawArrays(ctx->CurrentClientDispatch, (mode, first[i], count[i]));
> - }
> - }
> -}
> -
> -
> /* GL_IBM_multimode_draw_arrays */
> void GLAPIENTRY
> _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
> const GLsizei * count,
> GLsizei primcount, GLint modestride )
> {
> GET_CURRENT_CONTEXT(ctx);
> GLint i;
>
> FLUSH_VERTICES(ctx, 0);
> diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
> index 30c52d5..bc4a18f 100644
> --- a/src/mesa/vbo/vbo_exec_array.c
> +++ b/src/mesa/vbo/vbo_exec_array.c
> @@ -630,20 +630,52 @@ vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first,
> 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);
> }
>
>
> +/**
> + * Called from glMultiDrawArrays when in immediate mode.
> + */
> +static void GLAPIENTRY
> +vbo_exec_MultiDrawArrays(GLenum mode, const GLint *first,
> + const GLsizei *count, GLsizei primcount)
> +{
> + GET_CURRENT_CONTEXT(ctx);
> + GLint i;
> +
> + if (MESA_VERBOSE & VERBOSE_DRAW)
> + _mesa_debug(ctx,
> + "glMultiDrawArrays(%s, %p, %p, %d)\n",
> + _mesa_enum_to_string(mode), first, count, primcount);
> +
> + if (!_mesa_validate_MultiDrawArrays(ctx, mode, count, primcount))
> + return;
> +
> + for (i = 0; i < primcount; i++) {
> + if (count[i] > 0) {
> + if (0)
> + check_draw_arrays_data(ctx, first[i], count[i]);
> +
> + vbo_draw_arrays(ctx, mode, first[i], count[i], 1, 0);
> +
> + if (0)
> + print_draw_arrays(ctx, mode, first[i], count[i]);
> + }
> + }
> +}
> +
> +
>
> /**
> * Map GL_ELEMENT_ARRAY_BUFFER and print contents.
> * For debugging.
> */
> #if 0
> static void
> dump_element_buffer(struct gl_context *ctx, GLenum type)
> {
> const GLvoid *map =
> @@ -1685,20 +1717,21 @@ vbo_initialize_exec_dispatch(const struct gl_context *ctx,
> SET_MultiDrawElementsIndirectCountARB(exec,
> vbo_exec_MultiDrawElementsIndirectCount);
> }
>
> if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
> SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced);
> SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced);
> }
>
> if (_mesa_is_desktop_gl(ctx)) {
> + SET_MultiDrawArrays(exec, vbo_exec_MultiDrawArrays);
> SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback);
> SET_DrawTransformFeedbackStream(exec,
> vbo_exec_DrawTransformFeedbackStream);
> SET_DrawTransformFeedbackInstanced(exec,
> vbo_exec_DrawTransformFeedbackInstanced);
> SET_DrawTransformFeedbackStreamInstanced(exec,
> vbo_exec_DrawTransformFeedbackStreamInstanced);
> }
> }
>
> diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
> index f8dab0c..ad54c3b 100644
> --- a/src/mesa/vbo/vbo_save_api.c
> +++ b/src/mesa/vbo/vbo_save_api.c
> @@ -1169,20 +1169,54 @@ _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
> | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
>
> for (i = 0; i < count; i++)
> CALL_ArrayElement(GET_DISPATCH(), (start + i));
> CALL_End(GET_DISPATCH(), ());
>
> _ae_unmap_vbos(ctx);
> }
>
>
> +static void GLAPIENTRY
> +_save_OBE_MultiDrawArrays(GLenum mode, const GLint *first,
> + const GLsizei *count, GLsizei primcount)
> +{
> + GET_CURRENT_CONTEXT(ctx);
> + GLint i;
> +
> + if (!_mesa_is_valid_prim_mode(ctx, mode)) {
> + _mesa_compile_error(ctx, GL_INVALID_ENUM, "glMultiDrawArrays(mode)");
> + return;
> + }
> +
> + if (primcount < 0) {
> + _mesa_compile_error(ctx, GL_INVALID_VALUE,
> + "glMultiDrawArrays(primcount<0)");
> + return;
> + }
> +
> + for (i = 0; i < primcount; i++) {
> + if (count[i] < 0) {
> + _mesa_compile_error(ctx, GL_INVALID_VALUE,
> + "glMultiDrawArrays(count[i]<0)");
> + return;
> + }
> + }
> +
> + for (i = 0; i < primcount; i++) {
> + if (count[i] > 0) {
> + _save_OBE_DrawArrays(mode, first[i], count[i]);
> + }
> + }
> +}
> +
> +
> /* Could do better by copying the arrays and element list intact and
> * then emitting an indexed prim at runtime.
> */
> static void GLAPIENTRY
> _save_OBE_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
> const GLvoid * indices, GLint basevertex)
> {
> GET_CURRENT_CONTEXT(ctx);
> struct vbo_save_context *save = &vbo_context(ctx)->save;
> struct gl_buffer_object *indexbuf = ctx->Array.VAO->IndexBufferObj;
> @@ -1477,20 +1511,21 @@ _save_vtxfmt_init(struct gl_context *ctx)
>
> /**
> * Initialize the dispatch table with the VBO functions for display
> * list compilation.
> */
> void
> vbo_initialize_save_dispatch(const struct gl_context *ctx,
> struct _glapi_table *exec)
> {
> SET_DrawArrays(exec, _save_OBE_DrawArrays);
> + SET_MultiDrawArrays(exec, _save_OBE_MultiDrawArrays);
> SET_DrawElements(exec, _save_OBE_DrawElements);
> SET_DrawElementsBaseVertex(exec, _save_OBE_DrawElementsBaseVertex);
> SET_DrawRangeElements(exec, _save_OBE_DrawRangeElements);
> SET_MultiDrawElementsEXT(exec, _save_OBE_MultiDrawElements);
> SET_MultiDrawElementsBaseVertex(exec, _save_OBE_MultiDrawElementsBaseVertex);
> SET_Rectf(exec, _save_OBE_Rectf);
> /* Note: other glDraw functins aren't compiled into display lists */
> }
>
>
>
More information about the mesa-dev
mailing list