[Mesa-dev] [PATCH 12/30] mesa: Change redundant code into loops in texstate.c.

Paul Berry stereotype441 at gmail.com
Fri Jan 10 13:50:53 PST 2014


On 10 January 2014 11:41, Kenneth Graunke <kenneth at whitecape.org> wrote:

> On 01/09/2014 06:19 PM, Paul Berry wrote:
> > This is possible now that ctx->Shader.CurrentProgram is an array.
> > ---
> >  src/mesa/main/texstate.c | 75
> +++++++++++++++++++-----------------------------
> >  1 file changed, 29 insertions(+), 46 deletions(-)
> >
> > diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
> > index b9c76da..905a9d5 100644
> > --- a/src/mesa/main/texstate.c
> > +++ b/src/mesa/main/texstate.c
> > @@ -526,27 +526,20 @@ static void
> >  update_texture_state( struct gl_context *ctx )
> >  {
> >     GLuint unit;
> > -   struct gl_program *fprog = NULL;
> > -   struct gl_program *vprog = NULL;
> > -   struct gl_program *gprog = NULL;
> > +   struct gl_program *prog[MESA_SHADER_STAGES];
> >     GLbitfield enabledFragUnits = 0x0;
> > -
> > -   if (ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX] &&
> > -       ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->LinkStatus) {
> > -      vprog =
> ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
> > -   }
> > -
> > -   if (ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY] &&
> > -       ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->LinkStatus) {
> > -      gprog =
> ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
> > -   }
> > -
> > -   if (ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT] &&
> > -       ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->LinkStatus) {
> > -      fprog =
> ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
> > -   }
> > -   else if (ctx->FragmentProgram._Enabled) {
> > -      fprog = &ctx->FragmentProgram.Current->Base;
> > +   int i;
> > +
> > +   for (i = 0; i < MESA_SHADER_STAGES; i++) {
> > +      if (ctx->Shader.CurrentProgram[i] &&
> > +          ctx->Shader.CurrentProgram[i]->LinkStatus) {
> > +         prog[i] =
> ctx->Shader.CurrentProgram[i]->_LinkedShaders[i]->Program;
> > +      } else {
> > +         if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)
> > +            prog[i] = &ctx->FragmentProgram.Current->Base;
> > +         else
> > +            prog[i] = NULL;
> > +      }
> >     }
> >
> >     /* TODO: only set this if there are actual changes */
> > @@ -562,9 +555,7 @@ update_texture_state( struct gl_context *ctx )
> >      */
> >     for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits;
> unit++) {
> >        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
> > -      GLbitfield enabledVertTargets = 0x0;
> > -      GLbitfield enabledFragTargets = 0x0;
> > -      GLbitfield enabledGeomTargets = 0x0;
> > +      GLbitfield enabledTargetsByStage[MESA_SHADER_STAGES];
> >        GLbitfield enabledTargets = 0x0;
> >        GLuint texIndex;
> >
> > @@ -574,25 +565,16 @@ update_texture_state( struct gl_context *ctx )
> >         * by a fragment program/program.  When multiple flags are set,
> we'll
> >         * settle on the one with highest priority (see below).
> >         */
> > -      if (vprog) {
> > -         enabledVertTargets |= vprog->TexturesUsed[unit];
> > +      for (i = 0; i < MESA_SHADER_STAGES; i++) {
> > +         if (prog[i])
> > +            enabledTargetsByStage[i] = prog[i]->TexturesUsed[unit];
> > +         else if (i == MESA_SHADER_FRAGMENT)
> > +            enabledTargetsByStage[i] = texUnit->Enabled;
> > +         else
> > +            enabledTargetsByStage[i] = 0;
> > +         enabledTargets |= enabledTargetsByStage[i];
>
> This doesn't look equivalent.  Previously,
> enabled{Vert,Frag,Geom}Targets would accumulate bits over every
> iteration through units.  Now, enabledTargetsByStage only reflects the
> most recent unit.
>
> enabledTargets still accumulates properly, but you use
> enabledTargetsByStage below, so I think it needs to as well.
>
> You just need to use |= in both places, like the old code.
>

It's definitely possible that I got something wrong in this patch--I didn't
completely grok what the code was doing and instead strived to just
preserve the existing semantics.

But I'm pretty sure I got the enabledTargetsByStage part right.  Here's
what the code used to look like--the enabled{Vert,Frag,Geom}Targets
variables were all reset to 0 every time through the loop:

   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      GLbitfield enabledVertTargets = 0x0;
      GLbitfield enabledFragTargets = 0x0;
      GLbitfield enabledGeomTargets = 0x0;
      GLbitfield enabledTargets = 0x0;
      GLuint texIndex;

      /* Get the bitmask of texture target enables.
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
       * which texture targets are enabled (fixed function) or referenced
       * by a fragment program/program.  When multiple flags are set, we'll
       * settle on the one with highest priority (see below).
       */
      if (vprog) {
         enabledVertTargets |= vprog->TexturesUsed[unit];
      }

      if (gprog) {
         enabledGeomTargets |= gprog->TexturesUsed[unit];
      }

      if (fprog) {
         enabledFragTargets |= fprog->TexturesUsed[unit];
      }
      else {
         /* fixed-function fragment program */
         enabledFragTargets |= texUnit->Enabled;
      }

      enabledTargets = enabledVertTargets | enabledFragTargets |
                       enabledGeomTargets;

      ...
   }

I don't know if that was intentional or a bug, but I'm pretty sure my patch
preserves the behaviour.


>
> Also, I just want to say - this code is absurdly confusing.  Always has
> been.  I don't envy you having to touch it. :)
>

You can say that again :)  Hopefully my patch doesn't make the situation
any worse.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140110/eb85ccfe/attachment-0001.html>


More information about the mesa-dev mailing list