<div dir="ltr">On 10 January 2014 11:41, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">On 01/09/2014 06:19 PM, Paul Berry wrote:<br>
> This is possible now that ctx->Shader.CurrentProgram is an array.<br>
> ---<br>
>  src/mesa/main/texstate.c | 75 +++++++++++++++++++-----------------------------<br>
>  1 file changed, 29 insertions(+), 46 deletions(-)<br>
><br>
> diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c<br>
> index b9c76da..905a9d5 100644<br>
> --- a/src/mesa/main/texstate.c<br>
> +++ b/src/mesa/main/texstate.c<br>
> @@ -526,27 +526,20 @@ static void<br>
>  update_texture_state( struct gl_context *ctx )<br>
>  {<br>
>     GLuint unit;<br>
> -   struct gl_program *fprog = NULL;<br>
> -   struct gl_program *vprog = NULL;<br>
> -   struct gl_program *gprog = NULL;<br>
> +   struct gl_program *prog[MESA_SHADER_STAGES];<br>
>     GLbitfield enabledFragUnits = 0x0;<br>
> -<br>
> -   if (ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX] &&<br>
> -       ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->LinkStatus) {<br>
> -      vprog = ctx->Shader.CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]->Program;<br>
> -   }<br>
> -<br>
> -   if (ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY] &&<br>
> -       ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->LinkStatus) {<br>
> -      gprog = ctx->Shader.CurrentProgram[MESA_SHADER_GEOMETRY]->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;<br>
> -   }<br>
> -<br>
> -   if (ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT] &&<br>
> -       ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->LinkStatus) {<br>
> -      fprog = ctx->Shader.CurrentProgram[MESA_SHADER_FRAGMENT]->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;<br>
> -   }<br>
> -   else if (ctx->FragmentProgram._Enabled) {<br>
> -      fprog = &ctx->FragmentProgram.Current->Base;<br>
> +   int i;<br>
> +<br>
> +   for (i = 0; i < MESA_SHADER_STAGES; i++) {<br>
> +      if (ctx->Shader.CurrentProgram[i] &&<br>
> +          ctx->Shader.CurrentProgram[i]->LinkStatus) {<br>
> +         prog[i] = ctx->Shader.CurrentProgram[i]->_LinkedShaders[i]->Program;<br>
> +      } else {<br>
> +         if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)<br>
> +            prog[i] = &ctx->FragmentProgram.Current->Base;<br>
> +         else<br>
> +            prog[i] = NULL;<br>
> +      }<br>
>     }<br>
><br>
>     /* TODO: only set this if there are actual changes */<br>
> @@ -562,9 +555,7 @@ update_texture_state( struct gl_context *ctx )<br>
>      */<br>
>     for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {<br>
>        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];<br>
> -      GLbitfield enabledVertTargets = 0x0;<br>
> -      GLbitfield enabledFragTargets = 0x0;<br>
> -      GLbitfield enabledGeomTargets = 0x0;<br>
> +      GLbitfield enabledTargetsByStage[MESA_SHADER_STAGES];<br>
>        GLbitfield enabledTargets = 0x0;<br>
>        GLuint texIndex;<br>
><br>
> @@ -574,25 +565,16 @@ update_texture_state( struct gl_context *ctx )<br>
>         * by a fragment program/program.  When multiple flags are set, we'll<br>
>         * settle on the one with highest priority (see below).<br>
>         */<br>
> -      if (vprog) {<br>
> -         enabledVertTargets |= vprog->TexturesUsed[unit];<br>
> +      for (i = 0; i < MESA_SHADER_STAGES; i++) {<br>
> +         if (prog[i])<br>
> +            enabledTargetsByStage[i] = prog[i]->TexturesUsed[unit];<br>
> +         else if (i == MESA_SHADER_FRAGMENT)<br>
> +            enabledTargetsByStage[i] = texUnit->Enabled;<br>
> +         else<br>
> +            enabledTargetsByStage[i] = 0;<br>
> +         enabledTargets |= enabledTargetsByStage[i];<br>
<br>
</div></div>This doesn't look equivalent.  Previously,<br>
enabled{Vert,Frag,Geom}Targets would accumulate bits over every<br>
iteration through units.  Now, enabledTargetsByStage only reflects the<br>
most recent unit.<br>
<br>
enabledTargets still accumulates properly, but you use<br>
enabledTargetsByStage below, so I think it needs to as well.<br>
<br>
You just need to use |= in both places, like the old code.<br></blockquote><div><br></div><div>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.<br>
<br>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:<br><br>   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {<br>
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];<br>      GLbitfield enabledVertTargets = 0x0;<br>      GLbitfield enabledFragTargets = 0x0;<br>      GLbitfield enabledGeomTargets = 0x0;<br>      GLbitfield enabledTargets = 0x0;<br>
      GLuint texIndex;<br><br>      /* Get the bitmask of texture target enables.<br>       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating<br>       * which texture targets are enabled (fixed function) or referenced<br>
       * by a fragment program/program.  When multiple flags are set, we'll<br>       * settle on the one with highest priority (see below).<br>       */<br>      if (vprog) {<br>         enabledVertTargets |= vprog->TexturesUsed[unit];<br>
      }<br><br>      if (gprog) {<br>         enabledGeomTargets |= gprog->TexturesUsed[unit];<br>      }<br><br>      if (fprog) {<br>         enabledFragTargets |= fprog->TexturesUsed[unit];<br>      }<br>      else {<br>
         /* fixed-function fragment program */<br>         enabledFragTargets |= texUnit->Enabled;<br>      }<br><br>      enabledTargets = enabledVertTargets | enabledFragTargets |<br>                       enabledGeomTargets;<br>
<br>      ...<br>   }<br><br></div><div>I don't know if that was intentional or a bug, but I'm pretty sure my patch preserves the behaviour.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

<br>
Also, I just want to say - this code is absurdly confusing.  Always has<br>
been.  I don't envy you having to touch it. :)<br></blockquote><div><br></div><div>You can say that again :)  Hopefully my patch doesn't make the situation any worse.<br></div></div></div></div>