title: Looping vs unrolling in fragment shader in iOS
body: <p>One of my fragment shaders emulates some of the basic OpenGL ES 1.1 multi-texturing features.</p>
  
  <p>As part of that, I have the following GLSL function declared:</p>
  
  <pre><code>void applyTexture(int tuIdx) {
      lowp vec4 texColor = texture2D(s_cc3Textures[tuIdx], v_texCoord[tuIdx]);
      int tuMode = u_cc3TextureUnitMode[tuIdx];
  
      if (tuMode == k_GL_COMBINE)
          combineTexture(texColor, tuIdx);
      else if (tuMode == k_GL_MODULATE)
          fragColor *= texColor;
      else if (tuMode == k_GL_DECAL)
          fragColor.rgb = (texColor.rgb * texColor.a) + (fragColor.rgb * (1.0 - texColor.a));
      else if (tuMode == k_GL_REPLACE)
          fragColor = texColor;
      else if (tuMode == k_GL_ADD) {
          fragColor.rgb += texColor.rgb;
          fragColor.a *= texColor.a;
      }
      else if (tuMode == k_GL_BLEND) {
          fragColor.rgb =  (fragColor.rgb * (1.0 - texColor.rgb)) + (u_cc3TextureUnitColor[tuIdx].rgb * texColor.rgb);
          fragColor.a *= texColor.a;
      }
  }
  </code></pre>
  
  <p>The <code>k_GL_XXX</code> constants are <code>#defined</code> at the top of the shader. </p>
  
  <p>To perform multi-texturing, this function is called multiple times. For the SGX GPU's under iOS, this is successfully accomplished using a for loop:</p>
  
  <pre><code>for (int tuIdx = 0; tuIdx &lt; MAX_TEXTURES; tuIdx++) {
      if (tuIdx == u_cc3TextureCount) return;     // Break out once we've applied all the textures
      applyTexture(tuIdx);
  }
  </code></pre>
  
  <p>where <code>u_cc3TextureCount</code> is an int uniform and <code>MAX_TEXTURES</code> is <code>#defined</code> to be <code>2</code>.</p>
  
  <p>Strangely, attempting to manually unroll this loop does not work, and results in nothing being drawn:</p>
  
  <pre><code>if (u_cc3TextureCount &gt; 0) {
      applyTexture(0);
  }
  if (u_cc3TextureCount &gt; 1) {
      applyTexture(1);
  }
  </code></pre>
  
  <p>Even more strangely, neither does the even more basic:</p>
  
  <pre><code>applyTexture(0);
  applyTexture(1);
  </code></pre>
  
  <p>which is completely unexpected behaviour, to say the least !</p>
  
  <p>I have confirmed that the value of <code>u_cc3TextureCount</code> is <code>2</code>, so all three of these approaches should yield the same results.</p>
  
  <p>The reason I am attempting to unroll the loop is that several GPUs, including some Android GPUs, and the new Apple A7 GPU in the iPad Air do not work correctly with the loop. I'm trying to find a way of calling the <code>applyTexture()</code> function multiple times that will work for all GPUs.</p>
  
  <p>Is anyone able to explain to me why such basic loop unrolling is not working?</p>