Limitation on number of If statements

I’ve been running into some trouble using if statements in GLSL. I am using GLEW version to interface with GLSL and I have a Nvidia GeForce 7600 GT.

The problem I’m having is that I have about 8 if’s in a row but when I try to run it, it gives me compile errors. However if I only include each of the if statements by themselves it runs fine.

I’m wondering if this is a limitation on the number of if statements that can occur within a function or maybe a limitation on the shader size? This is the second time I’ve run into this problem.

I’ve also noticed that the Vertex and Fragment shader are compiled properly (and have empty compilation logs), but when it actually gets to linking the program, I receive this in the program log:

Fragment info
-------------
Internal error: assembly compile error for fragment shader at offset 3903:
-- error message --
line 120, column 20:  error: invalid operand variable
...

… and a bunch of other errors and a dump of the assembly text. Unfortunately the assembly makes no sense to me so I’m at a loss.

If anyone can help me, it would be greatly appreciated.

show your code

No idea what is going on, for geforce 6800:

• Function calls can be nested at most 4 calls deep.
• If-then-else decision making can be nested at most 47 branches deep.
• Loops cannot be nested more than 4 loops deep.
• Each loop can have at most 255 iterations.

see
http://download.nvidia.com/developer/Papers/2005/OpenGL_2.0/NVIDIA_OpenGL_2.0_Support.pdf

Hi here’s the code for the part that seems to be broken (It’s basically deciding what blendFactor and which light positions to use depending on the angle). Note that I’ve tried blocking off code using comments, but it hasn’t produced anything useful, because so long as I block off 5 of my if statements with comments, it works (and it doesn’t matter which five). Furthermore if I remove the light1 and light2 assignments from all of the if statements, it also runs. I’ve tried getting the value of GL_MAX_PROGRAM_IF_DEPTH_NV but it just gives me 0

if ( angle >= 0.0 && angle <= 45.0)
{
	blendFactor = angle / 45.0;
	light1 = vec2(-1.0, 0.0);
	light2 = vec2(-1.0, 1.0);
}
else
{

	if ( angle > 45.0 && angle <= 90.0 )
	{
		blendFactor = (90.0 - angle) / 45.0;
		light1 = vec2(-1.0, 1.0);
		light2 = vec2(0.0, 1.0);
	}
	else
	{
		if ( angle > 90.0 && angle <= 135.0 )
		{
			blendFactor = (135.0 - angle) / 45.0;
			light1 = vec2(0.0, 1.0);
			light2 = vec2(1.0, 1.0);
		}
	}
}

if ( angle > 135.0 && angle <= 180.0 )
{
	blendFactor = (180.0 - angle) / 45.0;
	light1 = vec2(1.0, 1.0);
	light2 = vec2(1.0, 0.0);
}
else
{
	if ( angle > 180.0 && angle <= 225.0 )
	{
		blendFactor = (225.0 - angle) / 45.0;
		light1 = vec2(1.0, 0.0);
		light2 = vec2(1.0, -1.0);
	}
	else
	{
		if ( angle > 225.0 && angle <= 270.0 )
		{
			blendFactor = (270.0 - angle) / 45.0;
			light1 = vec2(1.0, -1.0);
			light2 = vec2(0.0, -1.0);
		}
	}
}

if ( angle > 270.0 && angle <= 315.0 )
{
	blendFactor = (315.0 - angle) / 45.0;
	light1 = vec2(0.0, -1.0);
	light2 = vec2(-1.0, -1.0);
}
else
{
	if ( angle > 315.0 && angle <= 360.0 )
	{
		blendFactor = (360.0 - angle) / 45.0;
		light1 = vec2(-1.0, -1.0);
		light2 = vec2(0.0, -1.0);
	}
}

I tried a looping method, with the following code:

vec2 lightPositions[8];
vec2 light1, light2;
float blendFactor;

lightPositions[0] = vec2(-1.0, 0.0);
lightPositions[1] = vec2(-1.0, 1.0);
lightPositions[2] = vec2(0.0, 1.0);
lightPositions[3] = vec2(1.0, 1.0);
lightPositions[4] = vec2(1.0, 0.0);
lightPositions[5] = vec2(1.0, -1.0);
lightPositions[6] = vec2(0.0, -1.0);
lightPositions[7] = vec2(-1.0, -1.0);

// Use the light angle to figure out the two light positions
// and how much to blend between them.

// NOTE: Undefined behavior will result if angle is not within range [0, 360]

// Blend between the west and north west light.
light1 = light2 = vec2(0.0, 0.0);
blendFactor = 0.0;

float j = 0.0;
int l1 = 0, l2 = 0;
for (int i = 0; i < 8; i++)
{

	if ( swgl_lightAngle >= j && swgl_lightAngle < j + 45.0 )
	{
		blendFactor = (swgl_lightAngle - j) / 45.0;
		l1 = i;
		l2 = i + 1;
	}
	
	j += 45.0;
}

if (l2 > 7 )
	l2 = l2 - 8;

light1 = lightPositions[l1]; // Line(252)
light2 = lightPositions[l2]; // Line(253)

This also didn’t work and gave me two errors:

(252) : error C5043: profile requires index expression to be compile-time constant
(253) : error C5043: profile requires index expression to be compile-time constant

The word “profile” reminds me of something that would be mentioned for the CG language used by NVIDIA…

Have you considered a clever way of expressing what you’re doing? Like encoding it in a texture of some sort and using a texture lookup based on angle?

Well, what I did for now was to perform this code inside the main program and pass the results as uniform variables. This worked, so technically the problem is solved. Unfortunately, it doesn’t help me understand why it didn’t work in the first place. Thank you all for the help though.

From your first post, I think this means the compiler messed up somewhere. Send them a bug report, test code, your OS, RAM, CPU, GPU and which drivers.
Make sure you are using the latest drivers before sending bug reports.

=========================
Internal error: assembly compile error for fragment shader at offset 3903:

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