<div dir="ltr">These comments have been addressed.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 30, 2014 at 3:46 PM, Anuj Phogat <span dir="ltr"><<a href="mailto:anuj.phogat@gmail.com" target="_blank">anuj.phogat@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Tue, Dec 16, 2014 at 7:46 AM, Brian Paul <<a href="mailto:brianp@vmware.com">brianp@vmware.com</a>> wrote:<br>
> On 12/15/2014 06:22 PM, Laura Ekstrand wrote:<br>
>><br>
>> The following preparations were made in texstate.c and texstate.h to<br>
>> better facilitate the BindTextureUnit function:<br>
>><br>
>> Dylan Noblesmith:<br>
>> mesa: add _mesa_get_tex_unit()<br>
>> mesa: factor out _mesa_max_tex_unit()<br>
>> This is about to appear in a lot more places, so<br>
>> reduce boilerplate copy paste.<br>
>> add _mesa_get_tex_unit_err() checking getter function<br>
>> Reduce boilerplate across files.<br>
>><br>
>> Laura Ekstrand:<br>
>> Made note of why BindTextureUnit should throw GL_INVALID_OPERATION if the<br>
>> unit is out of range.<br>
>> Added assert(unit > 0) to _mesa_get_tex_unit.<br>
>> ---<br>
>>   src/mapi/glapi/gen/ARB_direct_state_access.xml |   5 ++<br>
>>   src/mesa/main/texobj.c                         | 108<br>
>> ++++++++++++++++++++++++-<br>
>>   src/mesa/main/texobj.h                         |  15 +++-<br>
>>   src/mesa/main/texstate.c                       |   4 +-<br>
>>   src/mesa/main/texstate.h                       |  39 ++++++++-<br>
>>   5 files changed, 160 insertions(+), 11 deletions(-)<br>
>><br>
>> diff --git a/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
>> b/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
>> index 4c5005f..f54c3f8 100644<br>
>> --- a/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
>> +++ b/src/mapi/glapi/gen/ARB_direct_state_access.xml<br>
>> @@ -75,5 +75,10 @@<br>
>>         <param name="pixels" type="const GLvoid *" /><br>
>>      </function><br>
>><br>
>> +   <function name="BindTextureUnit" offset="assign"><br>
>> +      <param name="unit" type="GLuint" /><br>
>> +      <param name="texture" type="GLuint" /><br>
>> +   </function><br>
>> +<br>
>>   </category><br>
>>   </OpenGLAPI><br>
>> diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c<br>
>> index 26d07ee..eb16f47 100644<br>
>> --- a/src/mesa/main/texobj.c<br>
>> +++ b/src/mesa/main/texobj.c<br>
>> @@ -482,8 +482,8 @@ valid_texture_object(const struct gl_texture_object<br>
>> *tex)<br>
>>    * when there's a real pointer change.<br>
>>    */<br>
>>   void<br>
>> -_mesa_reference_texobj_(struct gl_texture_object **ptr,<br>
>> -                        struct gl_texture_object *tex)<br>
>> +_mesa_reference_texobj_( struct gl_texture_object **ptr,<br>
>> +                         struct gl_texture_object *tex )<br>
><br>
><br>
> I prefer the lack of whitespace as it was.<br>
</div></div>This extra space is used at many other places in this patch.<br>
<div><div class="h5"><br>
><br>
><br>
>>   {<br>
>>      assert(ptr);<br>
>><br>
>> @@ -503,6 +503,8 @@ _mesa_reference_texobj_(struct gl_texture_object<br>
>> **ptr,<br>
>>         mtx_unlock(&oldTex->Mutex);<br>
>><br>
>>         if (deleteFlag) {<br>
>> +         /* Passing in the context drastically changes the driver code<br>
>> for<br>
>> +          * framebuffer deletion. */<br>
><br>
><br>
> Closing */ on next line.<br>
><br>
><br>
>>            GET_CURRENT_CONTEXT(ctx);<br>
>>            if (ctx)<br>
>>               ctx->Driver.DeleteTexture(ctx, oldTex);<br>
>> @@ -1571,6 +1573,108 @@ _mesa_BindTexture( GLenum target, GLuint texName )<br>
>>         ctx->Driver.BindTexture(ctx, ctx->Texture.CurrentUnit, target,<br>
>> newTexObj);<br>
>>   }<br>
>><br>
>> +/** Do the actual binding to a numbered texture unit.<br>
><br>
><br>
> /**<br>
>  * Do the ...<br>
><br>
><br>
>> + * The refcount on the previously bound<br>
>> + * texture object will be decremented.  It'll be deleted if the<br>
>> + * count hits zero.<br>
>> + */<br>
>> +void<br>
>> +_mesa_bind_texture_unit( struct gl_context *ctx,<br>
>> +                         GLuint unit,<br>
>> +                         struct gl_texture_object *texObj )<br>
>> +{<br>
>> +   struct gl_texture_unit *texUnit;<br>
>> +<br>
>> +   /* Get the texture unit (this is an array look-up) */<br>
>> +   texUnit = _mesa_get_tex_unit_err(ctx, unit, "glBindTextureUnit");<br>
>> +   if (!texUnit)<br>
>> +      return;<br>
>> +<br>
>> +   /* Check if this texture is only used by this context and is already<br>
>> bound.<br>
>> +    * If so, just return.<br>
>> +    */<br>
>> +   {<br>
>> +      GLboolean early_out;<br>
><br>
><br>
> bool<br>
><br>
><br>
>> +      mtx_lock(&ctx->Shared->Mutex);<br>
>> +      early_out = ((ctx->Shared->RefCount == 1)<br>
>> +                   && (texObj ==<br>
>> texUnit->CurrentTex[texObj->TargetIndex]));<br>
>> +      mtx_unlock(&ctx->Shared->Mutex);<br>
>> +      if (early_out) {<br>
>> +         return;<br>
>> +      }<br>
>> +   }<br>
>> +<br>
>> +   /* flush before changing binding */<br>
>> +   FLUSH_VERTICES(ctx, _NEW_TEXTURE);<br>
>> +<br>
>> +   _mesa_reference_texobj(&texUnit->CurrentTex[texObj->TargetIndex],<br>
>> +                          texObj);<br>
>> +   ASSERT(texUnit->CurrentTex[texObj->TargetIndex]);<br>
>> +   ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed,<br>
>> +                                         unit + 1);<br>
>> +   texUnit->_BoundTextures |= (1 << texObj->TargetIndex);<br>
>> +<br>
>> +<br>
>> +   /* Pass BindTexture call to device driver */<br>
>> +   if (ctx->Driver.BindTexture)<br>
>> +   {<br>
><br>
><br>
> Opening { on the if line.<br>
><br>
><br>
><br>
>> +      ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj);<br>
>> +   }<br>
>> +}<br>
>> +<br>
>> +/**<br>
>> + * Bind a named texture to the specified texture unit.<br>
>> + *<br>
>> + * \param unit texture unit.<br>
>> + * \param texture texture name.<br>
>> + *<br>
>> + * \sa glBindTexture().<br>
>> + *<br>
>> + * If the named texture is 0, this will reset each target for the<br>
>> specified<br>
>> + * texture unit to its default texture.<br>
>> + * If the named texture is not 0 or a recognized texture name, this<br>
>> throws<br>
>> + * GL_INVALID_OPERATION.<br>
>> + */<br>
>> +void GLAPIENTRY<br>
>> +_mesa_BindTextureUnit( GLuint unit, GLuint texture )<br>
>> +{<br>
>> +   GET_CURRENT_CONTEXT(ctx);<br>
>> +   struct gl_texture_object *texObj;<br>
>> +<br>
>> +   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))<br>
>> +      _mesa_debug(ctx, "glBindTextureUnit %s %d\n",<br>
>> +                  _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit), (GLint)<br>
>> texture);<br>
>> +<br>
>> +   /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec<br>
>> +    * (20141030) says:<br>
>> +    *    "When texture is zero, each of the targets enumerated at the<br>
>> +    *    beginning of this section is reset to its default texture for<br>
>> the<br>
>> +    *    corresponding texture image unit."<br>
>> +    */<br>
>> +   if (texture == 0) {<br>
>> +      unbind_textures_from_unit(ctx, unit);<br>
>> +      return;<br>
>> +   }<br>
>> +<br>
>> +   /* Get the non-default texture object */<br>
>> +   texObj = _mesa_lookup_texture(ctx, texture);<br>
>> +<br>
>> +   /* Error checking */<br>
>> +   if (!texObj) {<br>
>> +      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
>> +         "glBindTextureUnit(non-gen name)");<br>
>> +      return;<br>
>> +   }<br>
>> +   if (texObj->Target == 0) {<br>
>> +      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTextureUnit(target)");<br>
>> +      return;<br>
>> +   }<br>
>> +   assert(valid_texture_object(texObj));<br>
>> +<br>
>> +   _mesa_bind_texture_unit(ctx, unit, texObj);<br>
>> +}<br>
>> +<br>
>> +<br>
>>   void GLAPIENTRY<br>
>>   _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures)<br>
>>   {<br>
>> diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h<br>
>> index b957ac5..34daebb 100644<br>
>> --- a/src/mesa/main/texobj.h<br>
>> +++ b/src/mesa/main/texobj.h<br>
>> @@ -85,12 +85,12 @@ _mesa_clear_texture_object(struct gl_context *ctx,<br>
>>                              struct gl_texture_object *obj);<br>
>><br>
>>   extern void<br>
>> -_mesa_reference_texobj_(struct gl_texture_object **ptr,<br>
>> -                        struct gl_texture_object *tex);<br>
>> +_mesa_reference_texobj_( struct gl_texture_object **ptr,<br>
>> +                         struct gl_texture_object *tex );<br>
>><br>
>>   static inline void<br>
>> -_mesa_reference_texobj(struct gl_texture_object **ptr,<br>
>> -                       struct gl_texture_object *tex)<br>
>> +_mesa_reference_texobj( struct gl_texture_object **ptr,<br>
>> +                        struct gl_texture_object *tex )<br>
>>   {<br>
>>      if (*ptr != tex)<br>
>>         _mesa_reference_texobj_(ptr, tex);<br>
>> @@ -190,6 +190,11 @@ _mesa_unlock_context_textures( struct gl_context *ctx<br>
>> );<br>
>>   extern void<br>
>>   _mesa_lock_context_textures( struct gl_context *ctx );<br>
>><br>
>> +extern void<br>
>> +_mesa_bind_texture_unit( struct gl_context *ctx,<br>
>> +                         GLuint unit,<br>
>> +                         struct gl_texture_object *texObj );<br>
>> +<br>
>>   /*@}*/<br>
>><br>
>>   /**<br>
>> @@ -210,6 +215,8 @@ _mesa_DeleteTextures( GLsizei n, const GLuint<br>
>> *textures );<br>
>>   extern void GLAPIENTRY<br>
>>   _mesa_BindTexture( GLenum target, GLuint texture );<br>
>><br>
>> +extern void GLAPIENTRY<br>
>> +_mesa_BindTextureUnit( GLuint unit, GLuint texture );<br>
>><br>
>>   extern void GLAPIENTRY<br>
>>   _mesa_BindTextures( GLuint first, GLsizei count, const GLuint *textures<br>
>> );<br>
>> diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c<br>
>> index 36eefa6..66fd718 100644<br>
>> --- a/src/mesa/main/texstate.c<br>
>> +++ b/src/mesa/main/texstate.c<br>
>> @@ -290,9 +290,7 @@ _mesa_ActiveTexture(GLenum texture)<br>
>>      GLuint k;<br>
>>      GET_CURRENT_CONTEXT(ctx);<br>
>><br>
>> -   /* See OpenGL spec for glActiveTexture: */<br>
>> -   k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,<br>
>> -            ctx->Const.MaxTextureCoordUnits);<br>
>> +   k = _mesa_max_tex_unit(ctx);<br>
>><br>
>>      ASSERT(k <= Elements(ctx->Texture.Unit));<br>
>><br>
>> diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h<br>
>> index 5cd1684..2514d10 100644<br>
>> --- a/src/mesa/main/texstate.h<br>
>> +++ b/src/mesa/main/texstate.h<br>
>> @@ -33,9 +33,19 @@<br>
>><br>
>><br>
>>   #include "compiler.h"<br>
>> +#include "enums.h"<br>
>> +#include "macros.h"<br>
>>   #include "mtypes.h"<br>
>><br>
>><br>
>> +static inline struct gl_texture_unit *<br>
>> +_mesa_get_tex_unit(struct gl_context *ctx, GLuint unit)<br>
>> +{<br>
>> +   ASSERT(unit >= 0);<br>
>> +   ASSERT(unit < Elements(ctx->Texture.Unit));<br>
>> +   return &(ctx->Texture.Unit[unit]);<br>
>> +}<br>
>> +<br>
>>   /**<br>
>>    * Return pointer to current texture unit.<br>
>>    * This the texture unit set by glActiveTexture(), not<br>
>> glClientActiveTexture().<br>
>> @@ -43,8 +53,33 @@<br>
>>   static inline struct gl_texture_unit *<br>
>>   _mesa_get_current_tex_unit(struct gl_context *ctx)<br>
>>   {<br>
>> -   ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));<br>
>> -   return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);<br>
>> +   return _mesa_get_tex_unit(ctx, ctx->Texture.CurrentUnit);<br>
>> +}<br>
>> +<br>
>> +static inline GLuint<br>
>> +_mesa_max_tex_unit(struct gl_context *ctx)<br>
>> +{<br>
>> +   /* See OpenGL spec for glActiveTexture: */<br>
>> +   return MAX2(ctx->Const.MaxCombinedTextureImageUnits,<br>
>> +               ctx->Const.MaxTextureCoordUnits);<br>
>> +}<br>
>> +<br>
>> +static inline struct gl_texture_unit *<br>
>> +_mesa_get_tex_unit_err(struct gl_context *ctx, GLuint unit, const char<br>
>> *func)<br>
>> +{<br>
>> +   if (unit < _mesa_max_tex_unit(ctx))<br>
>> +      return _mesa_get_tex_unit(ctx, unit);<br>
>> +<br>
>> +   /* Note: This error is a precedent set by glBindTextures. From the GL<br>
>> 4.5<br>
>> +    * specification (30.10.2014) Section 8.1 ("Texture Objects"):<br>
>> +    *<br>
>> +    *    "An INVALID_OPERATION error is generated if first + count is<br>
>> greater<br>
>> +    *     than the number of texture image units supported by the<br>
>> +    *     implementation."<br>
>> +    */<br>
>> +   _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unit=%s)", func,<br>
>> +               _mesa_lookup_enum_by_nr(GL_TEXTURE0+unit));<br>
>> +   return NULL;<br>
>>   }<br>
>><br>
>><br>
>><br>
><br>
</div></div>> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div><br></div>