GLSL crash in ATI 9550

I’m implementing a per-pixel lighting shading program.
Here is part of my fragment shader source code:

vec3 R = normalize( reflect(-L, n) );
vec3 V = normalize( eye - hitPoint );
float RV = max(dot(R,V), 0.0);
specular = pow( RV, NsRf.r);
color = Ka + Kd * diffuse; // + Ks * specular;

Everything is ok at first,
but the program will crash if I remove the comment in the last line.
I’ve checked the values of both variables $Ks and $specular, and it seems correct.
Does anyone have ideas about where the problem is?

Running on ATI9550 and X300 has the same problem.

There are no obvious errors there. Could you post the entire shader so we can debug it (preferably the corresponding vertex shader too)?

Here is the vertex shader.

void main()
	gl_TexCoord[0] = gl_MultiTexCoord0;
	gl_Position = ftransform();

and fragment shader is:

 #define INTEGER(x) (x-fract(x))

uniform sampler2D hit;
uniform sampler2D triangles;
uniform sampler2D vertices;
uniform sampler2D normals;
uniform sampler2D normalID;
uniform sampler2D materials;
uniform vec3 eye;
uniform vec3 lightPos;

vec2 mapTo2D(float idx)
	float n = INTEGER(idx);
	float s = mod(n, 512.0);
	float t = floor(n / 512.0);
	return vec2(s+0.5, t+0.5) / 512.0;

vec2 mapTo2D_32x32(float idx)
	float n = INTEGER(idx);
	float s = mod(n, 32.0);
	float t = floor(n / 32.0);
	return vec2(s+0.5, t+0.5) / 32.0;

void main()
	vec4 z_buffer = texture2D(hit, gl_TexCoord[0].st);
	vec4 color;
	// z_buffer(r,g,b) = (triangle index, u, v)
	if(z_buffer.r > 0.0)
		vec4 tri = texture2D(triangles, mapTo2D(z_buffer.r-1.0) );
		// fetch materials
		float matID = tri.w;
		vec4 Ka = texture2D(materials, mapTo2D_32x32(matID * 4.0) );
		vec4 Kd = texture2D(materials, mapTo2D_32x32(matID * 4.0 + 1.0) );
		vec4 Ks = texture2D(materials, mapTo2D_32x32(matID * 4.0 + 2.0) );
		vec2 NsRf = texture2D(materials, mapTo2D_32x32(matID * 4.0 + 3.0) ).rg;
		// fetch vertices
		vec3 v0 = texture2D(vertices, mapTo2D( tri.x )).xyz;
		vec3 v1 = texture2D(vertices, mapTo2D( tri.y )).xyz;
		vec3 v2 = texture2D(vertices, mapTo2D( tri.z )).xyz;
		vec3 hitPoint = (1.0 - z_buffer.g - z_buffer.b) * v0 + z_buffer.g * v1 + z_buffer.b * v2;
		vec3 L = normalize( lightPos - hitPoint );
		// fetch normals
		vec3 nID = texture2D(normalID, mapTo2D(z_buffer.r-1.0)).xyz;
		vec3 n1 = texture2D(normals, mapTo2D( nID.x )).xyz;
		vec3 n2 = texture2D(normals, mapTo2D( nID.y )).xyz;
		vec3 n3 = texture2D(normals, mapTo2D( nID.z )).xyz;
		vec3 n = (1.0 - z_buffer.g - z_buffer.b) * n1 + z_buffer.g * n2 + z_buffer.b * n3;
		n = normalize(n);
		color = Ka;
		float diffuse = max(dot(n,L), 0.0);
		if(diffuse > 0.0) {
			color += Kd * diffuse;
			float specular = 0.0;
			vec3 R = normalize( reflect(-L, n) );
			vec3 V = normalize( eye - hitPoint );
			float RV = max(dot(R,V), 0.0);
			color += pow( RV, NsRf.r) * Ks;
		color = vec4(0.0);

	gl_FragColor = color;

actually I’m writing a shading phase of ray tracer.
‘hit’ texture stores the triangle index which is hit
‘triangles’ stores vertices ID of triangle
‘vertices’ stores vertex position
‘normals’ and ‘normalID’ are just like vertex and vertexID

The result seems OK before I sum the specular term,
however when I sum it, the program crash :frowning:

I also tried on a nvidia 6600, the program did not crash but the result is a little different :confused:

It seems that the program exceeds the maximal instruction counts?
I remove a few texture fetch and it works.

Yes. Without the specular it optimizes away a lot of stuff, so it compiles down to 58 instructions. With specular included it is 143 instructions. Do you really need to provide the coordinates as 1D and converts to 2D? This consumes a lot of instructions. If so, you may want to try to vectorize it a bit. You’ll probably still have a hard time squeezing that into 64 instructions though.

Thanks for your answer.
I currently divide this program into two pass.
May I ask you how to get the number of instructions used?
Is 64 the limitation of radeon9550?

Yes, 64 is the maximum number of ALU instructions on 9550 and all other R300 based. R420 and up supports 512 ALU instructions. Texture instructions are not counted against this limit, and in practice you can often have more instructions since we can issue a vec3 and a scalar instruction in parallel. There are no public tools for viewing the numbers of instructions at this point.

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