Incorrect data on NV with more than 8 attributes

Hi there

When i try to use more than 8 vertex attributes on an nVidia card all shaders compile and link fine, it runs without errors, but the results are completely wrong. All first 8 vertex attributes contain correct data, but from the 9th on the data contained is just random (usually something from one of the other arrays).

However, ARB_vertex_program promises me 16 vertex attributes, so i guess this is no different in glsl. As already said, OpenGL mentions no errors.

This happens on a Geforce 9600 with latest drivers, but i first encountered it on a Geforce 7xxx about 1.5 years ago. Both times the only way to “fix” it, is to use fewer vertex attributes (by computing bitangents inside the shaders, etc.).

Anyone encountered the same issues?

Jan.

I encountered something like these. To fix it, I used vertex attribs for up yo 7-th attrib, and then I used texcoords 0…7 (instead of attrib 8…15). Don’t know why, but it helped. I think, it’s nothing but some little driver bug.

Could it be something to do with vertex attribute aliasing?

http://developer.download.nvidia.com/opengl/glsl/glsl_release_notes.pdf

Quite a old document (November 2006) so not sure whether it’s still true.

Are you using built-in vertex attributes (gl_Vertex, gl_Normal, gl_MultiTexCoord0, gl_MultiTexCoord1 etc.) as well as your 8 generic attributes?

If so it may start to overwrite the built-in attributes with your generic ones. (just at a guess at what the driver does in this situation)

I use generic vertex attributes exclusively. That’s why i was surprised that such a bug should exist after such a long time. I assume most people don’t need so many attributes, personally i only need it in a radiosity-tool, which needs a lot of per-vertex data, but not in an actual engine.

I have double-checked my code, but i can’t find anything that should make problems. Even if it is only a “little” driver bug, it does prevent me from being able to use 9 attributes.

Jan.

>> I use generic vertex attributes exclusively
doesnt matter same rules apply

IIRC the reason behind that on nvidia hardware was cause thats how the hardware was designed, thus impossible to change (I dont know if this is still true with the new hardware).

#define VERTEXATTRIB_INDEX_VERTEX 0
#define VERTEXATTRIB_INDEX_NORMAL 2
#define VERTEXATTRIB_INDEX_COLOR 3
#define VERTEXATTRIB_INDEX_SECONDARYCOLOR 4
#define VERTEXATTRIB_INDEX_FOGCOORD 5
#define VERTEXATTRIB_INDEX_TEXCOORD0 8
#define VERTEXATTRIB_INDEX_TEXCOORD1 9
#define VERTEXATTRIB_INDEX_TEXCOORD2 10
#define VERTEXATTRIB_INDEX_TEXCOORD3 11
#define VERTEXATTRIB_INDEX_TEXCOORD4 12
#define VERTEXATTRIB_INDEX_TEXCOORD5 13
#define VERTEXATTRIB_INDEX_TEXCOORD6 14
#define VERTEXATTRIB_INDEX_TEXCOORD7 15

perhaps (though unlikely I think) is it only vertex attrib stuff cause 8*(4 floats) sounds suspiciously like the limit that on (a lot of) hardware u can only pass Xfloats from the VS to the FS

Ive just checked on my gf9500 max varying floats=60 though on previously hardware this was only like 32

>> doesnt matter same rules apply
How can same rules apply to generic attributes? Driver has no knowledge what does generic attributes represent - is it normal? color? or texcoord?

Are you passing in matrices as vertex attributes? (or passing matrix around as varying would quickly eat into the max varying floats limit)

From GL spec:
The VertexAttrib* entry points may also be used to load shader attributes declared as a floating-point matrix. Each column of a matrix takes up one generic 4-component attribute slot out of the MAX VERTEX ATTRIBS available slots.

So 2 (4x4) matrices would take up 8 attribute slots.

Also, If you’re passing in single float values, and running out of attributes, you could always combine 4 of them as one attribute:

eg. could turn the float attributes “myColor”, “myTemperature”, “myShininess”, “myRoughness” into one float4 attribute “myMaterialProperties” therefore using 3 less attributes, or if you’re passing in a float3, instead could pass in a float4 with an extra value in the w position, and use 1 less attribute.

Section 4.4 of http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf has tips like this.

No, i don’t pass matrices as attributes, only float3 and float4. Also i do not select the slot myself, but query the shader for the attribute bind point. I already combine some data, otherwise i would have long surpassed that limit.

Jan.

>> How can same rules apply to generic attributes? Driver has no knowledge what does generic attributes represent - is it normal? color? or texcoord?

yes you’re right, what Ive written doesnt seem logical.

perhaps try looking at the cg output from this shader + seeing if it always gets placed in index0

gl_Position = attributeA;

or

gl_Position = attributeA * atrributeB;

Jan,

Can you include your vertex shader?

  • Mark Kilgard, NVIDIA