available number of texture instructions exceeded

Well here is my lovely little fragment shader. And it all works great. Except for one little thing. When the loop count goes from 6 to 7 I get “The GLSL fragment shader will run in software - available number of texture instructions exceeded.” Hmmm… That will not do at all. I am pretty sure that “texture instructions” refers to “texture3D.” And I think that the loop is being parallized. And I think that because singleCoord is calculated in the loop that the texture3D command is being parallized along with the loop resulting in more than one call to texture3D. Of course I’m gussing, but it seems to make sense. The thing is, there really needs to be only one call to texture3D. The loop only finds one valid value for singleCoord so I can’t think of any reason for texture3D to be parallized. So my question is, how can I insure that only one call to texture3D is made after the loop is finished?

uniform sampler3D textures;
uniform mat4 surveySpace;
uniform vec4 textureInfo[500];

varying vec4 vertex;  // come straight from gl_Vertex in the vertex shader

void main(void){   
  vec4 singleCoord=vec4(2.0, 2.0, 0.0, 0.0);
  vec4 fragColor = vec4(1.0, 1.0, 1.0, 1.0); 
  mat4 tileSpace=surveySpace;
  vec4 coord;
     
  for(int textureIndex=0;textureIndex<6;textureIndex++){
    tileSpace[0][0] =surveySpace[0][0]/textureInfo[textureIndex].z;
    tileSpace[1][0] =surveySpace[1][0]/textureInfo[textureIndex].z;
    tileSpace[2][0] =surveySpace[2][0]/textureInfo[textureIndex].z;
    tileSpace[3][0] =(surveySpace[3][0]-textureInfo[textureIndex].x)/textureInfo[textureIndex].z;
    
    tileSpace[0][1] =surveySpace[0][1]/textureInfo[textureIndex].w;
    tileSpace[1][1] =surveySpace[1][1]/textureInfo[textureIndex].w;
    tileSpace[2][1] =surveySpace[2][1]/textureInfo[textureIndex].w;
    tileSpace[3][1] =(surveySpace[3][1]-textureInfo[textureIndex].y)/textureInfo[textureIndex].w;
        
    coord =tileSpace * vertex;
        
    if( coord.x >= 0.0 && coord.y >= 0.0 && coord.x <= 1.0 && coord.y <= 1.0 ){
      singleCoord = coord;
      singleCoord.z = float(textureIndex)/10.0;
    } 
  }

  if( singleCoord.x >= 0.0 && singleCoord.y >= 0.0 && singleCoord.x <= 1.0 && singleCoord.y <= 1.0 ){
    fragColor = texture3D(textures,singleCoord.xyz);
  }

  gl_FragColor = fragColor;
}

I don’t think this is actually about texture instructions, more like total instructions. What graphics card are you using?

By the way, you can use a 1x1 luminance texture with a single white pixel and black as border color to do a 2D range check. This may be faster on some cards.

I thought that might be it to for a while. However if I simply add a large number of instructions I don’t get the message. Also, I don’t get the message if there is no linkage between the loop and the texture3D command, that is if I set singleCoord2 instead of singleCoord I don’t get the message. Though I suppose both of these results could be explained by some sort of code optimization.

I am using an ATI Radeon 9800:

GL_VENDOR: ATI Technologies Inc.
GL_RENDERER: RADEON 9800 Pro x86/SSE2
GL_VERSION: 2.0.6012 WinXP Release
GL_MAX_LIGHTS 8
GL_MAX_CLIP_PLANES 6
GL_MAX_TEXTURE_UNITS 8
GL_MAX_TEXTURE_COORDS 8
GL_MAX_VERTEX_ATTRIBS 32
GL_MAX_VERTEX_UNIFORM_COMPONENTS 4096
GL_MAX_VARYING_FLOATS 44
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 16
GL_MAX_TEXTURE_IMAGE_UNITS 16
GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 4096
GL_MAX_DRAW_BUFFERS 4

I did some test I changed the code to look like this:

        tileSpace[0][0]=surveySpace[0][0]/textureInfo[0].z;
	tileSpace[1][0]=surveySpace[1][0]/textureInfo[0].z;
	tileSpace[2][0]=surveySpace[2][0]/textureInfo[0].z;
	tileSpace[3][0]=(surveySpace[3][0]-textureInfo[0].x)/textureInfo[0].z;
       
	tileSpace[0][1]=surveySpace[0][1]/textureInfo[0].w;
	tileSpace[1][1]=surveySpace[1][1]/textureInfo[0].w;
	tileSpace[2][1]=surveySpace[2][1]/textureInfo[0].w;
	tileSpace[3][1]=(surveySpace[3][1]-textureInfo[0].y)/textureInfo[0].w;
     
	for(int textureIndex=0;textureIndex<23;textureIndex++){ 
        coord=tileSpace * vertex;
        
        if( coord.x >= 0.0 && coord.y >= 0.0 && coord.x <= 1.0 && coord.y <= 1.0 ){
            singleCoord=coord;
            singleCoord.z=float(textureIndex)/10.0;
        } 
    }

It doesn’t do what I want it to do, but it does let me get the loop to 23. So I guess it is a total instruction count limit. I need the count to be around 500 for what I want to do so I guess fragment shading isn’t going to work for me.

For 500 iterations you need a card with dynamic branching in the fragment shader (GeForce 6 and later, Radeon X1k). With loop unrolling the shader will just become too big.

Ok thanks for the info. I guess I’ll have to tighten my card definition.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.