New NV driver breaks my app (190.38)

I just installed the latest nVidia driver (190.38) and now one of my shaders is not working anymore (and i don’t see how to fix this).

The error is:

Fragment info

0(330) : error C5208: Sampler needs to be a uniform (global or parameter to main), need to inline function or resolve conditional expression
(0) : fatal error C9999: unable to generate code for texture function.

This is on a Geforce 9600 desktop GPU. The code has been working for 1.5 years flawlessly now, and all of a sudden it breaks.

What i do is, i do calculate parallax mapping (using conemaps, binary search, etc.), interior mapping and environmental mapping in one shader.
The parallax mapping determines the color and normal of the fragment, that is subsequently used to modify environmental mapping and interior mapping. So there is a data-dependency.

The parallax mapping uses a dynamic loop (number of steps calculated on the fly), but fixing it to a constant number (4) doesn’t make a difference.

Now, if i disable parallax mapping, the shader works again. If i disable env-mapping AND interior-mapping (both dependent on PM) it also works. There are no other things done, that sample textures after the parallax mapping. So i assume the dependence on the result of the parallax mapping, which itself uses a dynamic for loop, cannot be handled by the new GLSL compiler.

The shader is quite long (400 lines), so i won’t post it here. If needed i can show it, though.

Any ideas? Would be great if nVidia fixes this fast.

Jan.

“Sampler needs to be a uniform (global or parameter to main), need to inline function or resolve conditional expression”

Maybe you should make the sampler a uniform?

It is!

And how do you make a sampler NOT a uniform anyway??

“0(330)” this looks put quite late in the code. Maybe you can post the relevant excerpts of the shader, with removed parts replaced with “…” .
I have met this problem, but figured-out my error.

Well, ok, here is the entire shader, except for comments and some really basic stuff removed. The problem is, i don’t see what could possibly be wrong in the line the compiler complains about.



003: #version 120
049:
051: uniform float fDepthShift;
052: uniform float fDepthScale;
053: uniform float fRatio;
054:
059: uniform sampler2D Texture0;
060: uniform sampler2D TextureNormal0;
061: uniform sampler2D TextureConeMap;
062: uniform samplerCube TextureInterior;
063: uniform sampler2D TextureNoise;
064: uniform samplerCube Skybox;
066:
067: varying vec2 vTexCoord;
068: varying vec4 vAttrib0; //Diffuse, AO, Distance
069: varying vec3 vN;
070: varying vec3 vT;
071: varying vec3 vB;
072: varying vec3 vEye;
074:
075: vec3 SetupRay (vec3 eyeVec, out float fStretch)
076: {
077: vec3 p = vec3(vTexCoord, 0.0);
078: vec3 v = normalize (eyeVec);
079:
080: vec2 v2d2 = normalize (vec2(eyeVec.x, -eyeVec.y));
081: fStretch = mix(1.0/fRatio, 1.0, abs(v2d2.y));
082:
086: {
087: float db=1.0-v.z;
088: db*=db;
089: db*=db;
090: db=1.0-db*db;
091: v.xy*=db;
092: }
093:
095: float fDepthScale2 = (fDepthScale) / vAttrib0.a;
096: v.xy *= vec2(-fDepthScale2, -fDepthScale2);
097: v.y *= vAttrib0.a;
107:
108: return v;
109: }
110:
111: vec2 RayIntersectRelaxedcone (vec3 vRayPos, // Ray position
112: vec3 vRayDir, inout int iTextureFetches, in float fStretch) // Ray direction
113: {
114: int cone_steps = iTextureFetches;//15;
115: iTextureFetches = 0;
116: const int binary_steps = 7;
117:
118: vRayDir /= vRayDir.z; // Scale vRayDir
119: float fRayRatio = length (vRayDir.xy);
120: vec3 vPos = vRayPos;
121:
123: for ( int i=0; i < cone_steps; i++ )
124: {
125: vec4 vTex = texture2D (TextureConeMap, vPos.xy);
126: iTextureFetches++;
127: float vConeRatio = vTex.y * fStretch;
128: float fHeight = clamp (vTex.x - vPos.z, 0.0, 1.0);
129: float d = (vConeRatio * fHeight) / (fRayRatio + vConeRatio);
130:
132: vPos += vRayDir * (d+vRayDir.z/100.0);
136:
137: if (d <= 0.0)
138: break;
139: }
140:
144: vec3 vBSRange = 0.5 * vRayDir * vPos.z;
145: vec3 vBSPosition = vRayPos + vBSRange;
146: for ( int i=0; i < binary_steps; i++ )
147: {
148: vec4 vTex = texture2D (TextureConeMap, vBSPosition.xy);
149: iTextureFetches++;
150: vBSRange *= 0.5;
151: if (vBSPosition.z < vTex.x) // If outside
152: vBSPosition += vBSRange; // Move forward
153: else
154: vBSPosition -= vBSRange; // Move backward
155: }
156:
157: return vBSPosition.xy;
158: }
159:
160: vec2 GetCoord(vec2 vTexCoord, vec3 vEyeVec, inout int iTextureFetches)
161: {
164: const float fDepthScale = 0.06;
165: int iNumSteps = iTextureFetches;//15;
166:
167: int iStep = 0;
168: float fStep = (1.0 / float(iNumSteps));
169:
170: vec3 vDelta = vec3(vEyeVec.xy * fDepthScale / (float(iNumSteps) * vEyeVec.z), fStep);
171: vec3 vCoord = vec3(vTexCoord.xy, 1.0);
172:
173: vec4 vNormal = texture2D (TextureConeMap, vCoord.xy);
174: vNormal.x = 1.0 - vNormal.x;
175: vec4 vNormalOld = vec4(0.0);
176:
177: while(iStep < iNumSteps)
178: {
179: if(vNormal.r > vCoord.z)
180: {
181: iStep = (iNumSteps + 1);
182:
183:
184: vec3 vCoord1 = vCoord + vDelta;
185: vec3 vCoord2 = vCoord;
186:
187: for (int i = 0; i < 7; i++ )
188: {
190: vec3 vCurrCoord = (vCoord2 + vCoord1) * 0.5f;
191:
192: float fHeight = 1.0 - texture2D (TextureConeMap, vCurrCoord.xy).r;
193: float delta = vCurrCoord.z - fHeight;
194:
195: if ( vCurrCoord.z > fHeight )
196: {
197: vCoord1 = vCurrCoord;
198: }
199: else
200: {
201: vCoord2 = vCurrCoord;
202: }
203: }
204: vCoord = vCoord1;
206:
207: }
208: else
209: {
210: iStep++;
211: vNormalOld = vNormal;
212: vCoord -= vDelta;
213:
214: vNormal = (texture2D (TextureConeMap, vCoord.xy));
215: vNormal.x = 1.0 - vNormal.x;
216: }
217: }
218:
219: return vCoord.xy;
220: }
222:
223: void main(void)
224: {
225: vec3 vE = vEye;
226: vec2 vTexCoord2 = vTexCoord.xy;
227: vec4 vTex0 = vec4(1.0);
228: vec4 vNormal0;
229: vec4 vData2;
230: float fSpecularPower2 = fSpecularPower;
231: float fGlossFactor2 = fGlossFactor;
235:
236: vec2 dPdx = dFdx(vTexCoord.xy);
237: vec2 dPdy = dFdy(vTexCoord.xy);
238: vTex0 = texture2D (Texture0, vTexCoord2.xy);
239:
243: {
246: const float fParallaxDist = 40.0;
247: if (vAttrib0.y < fParallaxDist )
248: {
249:
250: mat3 tbn = mat3 ( vT, vB, vN );
251: vE *= tbn;
252: int iTextureFetches = int ( clamp ( 3.0 * (50.0 - vAttrib0.y)/10.0, 1.0, 15.0));
253:
254: float fStretch = 0.0;
255: vec3 vChEye = SetupRay (vE, fStretch);
256: vec3 vNormal = vec3(0.0, 0.0, 1.0);
257:
258: vChEye = mix (vNormal, vChEye, min(5.0 * (1.0 - (vAttrib0.y / fParallaxDist)), 1.0) );
260:
261: vec2 kCoord = vTexCoord.xy - vChEye.xy * fDepthShift / vChEye.z; //Shift the z null point of the height map
262: vTexCoord2 = RayIntersectRelaxedcone (vec3(kCoord.xy,0.0), vChEye, iTextureFetches, fStretch);
272:
273: vTex0 = texture2DGrad (Texture0, vTexCoord2.xy, dPdx, dPdy);
277: vNormal0 = texture2DGrad (TextureNormal0, vTexCoord2.xy, dPdx, dPdy);
280:
281: }
282: else
283: {
285: vNormal0 = texture2D (TextureNormal0, vTexCoord2.xy);
286: }
290:
291: vNormal0.a = 0.0;
292:
300: vNormal0.g = 1.0 - vNormal0.g;
301: vNormal0.rgb = vNormal0.rgb * 2.0 - 1.0;
302:
303: vNormal0.rgb = normalize (vNormal0.rgb);
304:
306: mat3 tbn = mat3 (normalize (vT), normalize (vB), normalize (vN));
307: vNormal0.rgb = tbn * vNormal0.rgb;
308:
311: vNormal0 = vNormal0;
312:
317:
318: vData2 = vec4((vNormal0.rgb+1.0)*0.5, vNormal0.a);
319:
320: }
325:
329: vec3 vReflect = reflect (normalize (vEye), vData2.xyz);
330: vec3 vReflection = textureCube (Skybox, vReflect).rgb;
331: vTex0.rgb += vReflection * fEnvMapFactor * vLightColor.rgb * vTex0.a;
337:
338: gl_FragData[0] = vec4 (vTex0.rgb, vTex0.a * fGlossFactor2);
339: gl_FragData[1] = vec4 (vData2.rgba);
340: gl_FragData[2] = vec4 (vAttrib0.rgb, fSpecularPower2 / 64.0);
341: }


The error is:


0(330) : error C5208: Sampler needs to be a uniform (global or parameter to main), need to inline function or resolve conditional expression 

The line that it complains about is thus:


330: vec3 vReflection = textureCube (Skybox, vReflect).rgb;

As you can see, “Skybox” is defined as


064: uniform samplerCube Skybox;

Sorry, i know the code is not pretty, but well, it works (worked…). (And in my defense, i didn’t write it :wink: )

I think it’s best to look at it from the end (line 330) instead of trying to work through it from the beginning.

As already explained above, it first does parallax mapping, where it searches for the texture coordinate, that gives the best parallax effect. This texture coordinate is then used to sample the diffuse and normal maps. The normal is then used to reflect the view ray and sample the environment map. And exactly that sample is line 330, which is broken.

Any hints or tips are greatly appreciated!

Jan.

It’s kinda funny… here’s the fix:


//vec3 vReflection = textureCube(Skybox, vReflect).rgb; 
	vec4 vReflection2 = textureCube(Skybox, vReflect);
	vec3 vReflection = vReflection2.rgb;

Obviously the compiler’s fault. Send a bug-report to nV.

NOWAI !!! WTF ??!

  1. It works!
    The given shader didn’t include the interior mapping, but it was the same problem there too, so all is fixed now.

  2. HOW did you know that??

Many many thanks for your help!

Jan.

I’m not a registered developer. Where can i send a bug report to ?

Email address is on the last page of this .pdf:
http://http.download.nvidia.com/developer/presentations/GDC_2004/gdc_2004_NV_GLSL.pdf

I think I had actually met that problem long ago with some drivers or version of Cgc. I have such luck :slight_smile: (imagine my paranoid coding style…)

“imagine my paranoid coding style…” - I honestly feel for you. You saved my day (or maybe even week), so maybe this is a little bit of compensation for your trouble in retrospect.

Thanks for pointing this out. We looked, and found the bug in the GLSL compiler. This should already be fixed in the GL 3.2 beta driver 190.56 which you can download here.

http://developer.nvidia.com/object/opengl_3_driver.html

The next Rel190 driver release will also have the fix.

Thanks!
Barthold
(with my NVIDIA hat on)

That’s very good to hear.

Could you put up Linux versions of this driver as well? I’ve got at least one unresolved NVidia 3.2 driver issue (see here). I’ll respond to your post yesterday there in just a minute.

Linux drivers are also downloadable from the same link

http://developer.nvidia.com/object/opengl_3_driver.html

Yes, but different versions. Windows: 190.56, Linux: 190.18.03. Just asking for updated 190.56 drivers for Linux to be posted. Thanks.

Yes, but different versions. Windows: 190.56, Linux: 190.18.03. Just asking for updated 190.56 drivers for Linux to be posted. Thanks.[/QUOTE]

Ah! Our Linux drivers use a somewhat different numbering scheme than our Windows drivers. Linux version 190.18.03 was built from the exact same OpenGL driver source as Windows 190.56.

Barthold
(with my NVIDIA hat on)

I can somewhat understand that IHVs WANT to confuse consumers with their weird GPU naming schemes, but is it really necessary to make the lives of developers more complicated than it already is?

I actually like ATI’s driver naming scheme very much. Year-dot-month. What could be more logical (and helpful!) than that?

Jan.

Ah! Our Linux drivers use a somewhat different numbering scheme than our Windows drivers. Linux version 190.18.03 was built from the exact same OpenGL driver source as Windows 190.56.[/QUOTE]
Ok, thanks for the clarification. I’d suspected it but had never heard that this was true.

Updated OpenGL 3.2 drivers are now available.

http://developer.nvidia.com/object/opengl_3_driver.html

Barthold
(with my NVIDIA hat on)