[Mesa-dev] [PATCH 14/14] mesa: Rewrite shader-based texture image state updates.

Eric Anholt eric at anholt.net
Fri Apr 25 17:34:35 PDT 2014


Ilia Mirkin <imirkin at alum.mit.edu> writes:

> On Thu, Apr 24, 2014 at 8:50 PM, Eric Anholt <eric at anholt.net> wrote:
>> Instead of walking 6 shader stages for each of the 96 combined texture
>> image units, now we just walk the samplers used in each shader stage.
>>
>> With cairo-perf-trace on Xephyr with glamor, I'm seeing a -6.50518% +/-
>> 2.55601% effect on runtime (n=22) since the "drop _EnabledUnits" change.
>> No significant performance difference on an apitrace of minecraft (n=442).
>> ---
>>  src/mesa/main/texstate.c | 122 ++++++++++++++++++++++++++++-------------------
>>  1 file changed, 73 insertions(+), 49 deletions(-)
>>
>> diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
>> index 0082caf..3a7e227 100644
>> --- a/src/mesa/main/texstate.c
>> +++ b/src/mesa/main/texstate.c
>> @@ -515,68 +515,92 @@ update_texgen(struct gl_context *ctx)
>>     }
>>  }
>>
>> +static struct gl_texture_object *
>> +update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
>> +                              int s)
>> +{
>> +   gl_texture_index target_index;
>> +   struct gl_texture_unit *texUnit;
>> +   struct gl_texture_object *texObj;
>> +   int unit;
>> +
>> +   if (!(prog->SamplersUsed & (1 << s)))
>> +      return NULL;
>> +
>> +   unit = prog->SamplerUnits[s];
>> +   texUnit = &ctx->Texture.Unit[unit];
>> +
>> +   /* Note: If more than one bit was set in TexturesUsed[unit], then we should
>> +    * have had the draw call rejected already.  From the GL 4.4 specification,
>> +    * section 7.10 ("Samplers"):
>> +    *
>> +    *     "It is not allowed to have variables of different sampler types
>> +    *      pointing to the same texture image unit within a program
>> +    *      object. This situation can only be detected at the next rendering
>> +    *      command issued which triggers shader invocations, and an
>> +    *      INVALID_OPERATION error will then be generated."
>> +    */
>> +   target_index = ffs(prog->TexturesUsed[unit]) - 1;
>> +   texObj = texUnit->CurrentTex[target_index];
>> +
>> +   struct gl_sampler_object *sampler = texUnit->Sampler ?
>> +      texUnit->Sampler : &texObj->Sampler;
>> +
>> +   if (likely(texObj)) {
>> +      if (_mesa_is_texture_complete(texObj, sampler))
>> +         return texObj;
>> +
>> +      _mesa_test_texobj_completeness(ctx, texObj);
>> +      if (_mesa_is_texture_complete(texObj, sampler))
>> +         return texObj;
>> +   }
>> +
>> +   /* If we've reached this point, we didn't find a complete texture of the
>> +    * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
>> +    * ("Texture Access"):
>> +    *
>> +    *     "If a sampler is used in a shader and the sampler’s associated
>> +    *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
>> +    *      will be returned for a non-shadow sampler and 0 for a shadow
>> +    *      sampler."
>> +    *
>> +    * Mesa implements this by creating a hidden texture object with a pixel of
>> +    * that value.
>> +    */
>> +   texObj = _mesa_get_fallback_texture(ctx, target_index);
>> +   assert(texObj);
>> +
>> +   return texObj;
>> +}
>> +
>>  static void
>>  update_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
>>                               BITSET_WORD *enabled_texture_units)
>>  {
>> -   GLuint unit;
>>     int i;
>>
>> -   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
>> -      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
>> -      GLbitfield enabledTargets = 0x0;
>> -      GLuint texIndex;
>> -
>> -      for (i = 0; i < MESA_SHADER_STAGES; i++) {
>> -         if (prog[i])
>> -            enabledTargets |= prog[i]->TexturesUsed[unit];
>> -      }
>> +   for (i = 0; i < MESA_SHADER_STAGES; i++) {
>> +      int s;
>>
>> -      if (enabledTargets == 0x0) {
>> -         /* neither vertex nor fragment processing uses this unit */
>> +      if (!prog[i])
>>           continue;
>> -      }
>> -
>> -      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
>> -         if (enabledTargets & (1 << texIndex)) {
>> -            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
>> -            struct gl_sampler_object *sampler = texUnit->Sampler ?
>> -               texUnit->Sampler : &texObj->Sampler;
>> -
>> -            if (!_mesa_is_texture_complete(texObj, sampler)) {
>> -               _mesa_test_texobj_completeness(ctx, texObj);
>> -            }
>> -            if (_mesa_is_texture_complete(texObj, sampler)) {
>> -               _mesa_reference_texobj(&texUnit->_Current, texObj);
>> -               break;
>> -            }
>> -         }
>> -      }
>>
>> -      if (texIndex == NUM_TEXTURE_TARGETS) {
>> -         /* If we get here it means the shader is expecting a texture
>> -          * object, but there isn't one (or it's incomplete).  Use the
>> -          * fallback texture.
>> -          */
>> +      /* We can't only do the shifting trick as the loop condition because if
>> +       * sampler 31 is active, the next iteration tries to shift by 32, which is
>> +       * undefined.
>> +       */
>> +      for (s = 0; s < MAX_SAMPLERS && (1 << s) <= prog[i]->SamplersUsed; s++) {
>
> I could be confused, but are you trying to walk over all set bits of
> SamplersUsed? You can do this with something like u_bit_scan() which
> basically does
>
> tmp = prog[i]->SamplersUsed;
> while (tmp) {
>   s = ffs(tmp) - 1;
>   tmp &= ~(1 << s);
>   ...
> }
>
> This should avoid pointless iteration when there are just a few bits
> set. If the expectation is that 1..n bits are all going to be set,
> then this provides little advantage.

Samplers are actually used from 1..n, with the exception of being able
to do silly things with assembly programs.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140425/15a02dea/attachment-0001.sig>


More information about the mesa-dev mailing list