[Mesa-dev] [PATCH 1/2] mesa: move glMultiDrawArray to vbo and fix error handling

Nicolai Hähnle nhaehnle at gmail.com
Thu Apr 13 19:27:27 UTC 2017


On 07.04.2017 19:05, Brian Paul wrote:
> 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?

It removes setting the dispatch pointer from the auto-generated 
api_exec.c; so it logically belongs to the change that adds the dispatch 
function in vbo_exec_array.c and vbo_save_api.c.

Nicolai

>
> -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 */
>>   }
>>
>>
>>
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list