arb_vertex_program problem on 9700

I’ve been having some trouble getting the correct behavior from ARB_vertex_program on my 9700 pro. The problem that I’m about to describe doesn’t occur on Geforce4 hardware when using the same vertex programs.

Basically all of my vertex programs are using the option ARB_position_invariant. Having this option enabled on my 9700 when using generic attribute binding causes an error like this: “illegal attribute pair”. So, ok, I changed all of my vertex.attrib[x] to vertex.position, vertex.color, etc. This compiles fine, but the attributes that I give via glDrawElements and glVertexAttribArrayARB do not show up correctly…for instance, texture coordinates all seem to be the same, colors don’t show up, etc. I have double checked that I’m doing the translation correctly.

This error on program compilation only started showing up after I installed Catalyst 3.2 drivers. Using catalyst 3.1, the programs would compile and work (with some bugs that I hadn’t finished chasing down) when binding ATTRIBS with vertex.attrib[x], but would give the same behaviour as above when using the traditional attribute bindings.

Anyway, maybe there’s something I don’t understand in the spec. I’d be grateful if someone could shed some light on this problem.

Thanks,
Zeno

On NVIDIA cards the generic attributes and conventional attributes are the same so you can f.e. set vertex.attrib[8] with glTexCoord. This is not true for other vendors so you need to do the following:

When using vertex.attrib[n], you must send the data to the vertex program using glVertexAttrib or glVertexAttribPointer.

When using vertex.color, vertex.position, etc… you must use glColor, glColorPointer, glVertex, glVertexPointer, etc…

Ahh, I am sending all my data via drawElements and vertexAttribPointer, so that might explain why the named attributes don’t work.

So now the other half of the question…how can I get the generic attributes to work with ARB_position_invariant? Or am I out of luck with that?

Thanks for the tip

– Zeno

From that error message it sounds like you are using a generic attribute and a conventional attribute that are bound the the same register. So if you are accessing vertex.texcoord[0] and vertex.attrib[8] at the same time, the program will fail to load.

Originally posted by jra101:
From that error message it sounds like you are using a generic attribute and a conventional attribute that are bound the the same register. So if you are accessing vertex.texcoord[0] and vertex.attrib[8] at the same time, the program will fail to load.

I know, that’s what I thought too when I first saw the error. I checked and that’s not the problem…all my vertex.attribs are generic. I only found through trial and error that the position invariant option is causing it.

Does the program work as is without the position invariant option?

Are you still writing to result.position when the pos invariant option is used?

Ok, I’m back at work now. Here’s the exact error I’m getting when using position invariant with generic vertex attributes:

“Error on line 0: Invalid attribute pair (hint: ‘]’) at position 0”. Position 0 is the ‘!’ in the “!!ARBvp1.0”, so the error message isn’t too useful.

Anyway, yes, the programs work mostly as intended if I transform the vertex myself and output to result.position. I say mostly because there is a fog bug in there too, but I think it’s unrelated. The texture coordinates and whatnot seem to be correct.

I double checked that I wasn’t writing to result.position when position_invariant was enabled.

Any help for this would be greatly appreciated. I need the position invariant for when the engine must fall back to more than one pass.

– Zeno

Out of curiosity, are you binding to “vertex.attrib[0]”? If so, you might want to try changing this to “vertex.position” and see what happens.

I’m purely guessing here, but it’s possible that the position invariant option is implemented by appending instructions to your vertex program behind your back. If their added instructions use “vertex.position” and you’ve already bound to “vertex.attrib[0]”, the compiler flags this as an error.

It’s something to try at least…

– sec

Thanks for the hints, secnuop. I am binding the vertex position for use in a fog calculation. I suspect you’re right about the driver adding some instructions behind the scenes. To summarize, here are my results for various permutations:

case 1) position invariant & vertex.position
ATI result) fog (based on vertex.position) is incorrect. It fogs very close objects instead of very distant objects
NVIDIA result) works fine

case 2) position_invariant & vertex.attrib[0]
ATI result) glProgramString returns error described above.
NVIDIA result) works fine

case 3) position_invariant & no bound position therefore no fog calc
ATI result) glProgramString returns error described above (I didn’t believe this, but I tried it twice with the same result).
NVIDIA result) works fine

case 4) no position_invariant & manual vertex transform using vertex.position
ATI result) same as case 1)
NVIDIA result) works fine

case 5) no position_invariant & manual vertex transform using vertex.attrib[0]
ATI result) same as case 1)
NVIDIA result) works fine

Just to be complete, here is my fog calculation:

"DP4 oFog, iVertex, mvp[2];"

where oFog is result.fogcoord, iVertex is as described above, and mvp[2] is the second row of the modelview projection matrix.

So, it looks like I need to use vertex.position when using ARB_position_invariant on ATI hardware. And even then, I may not be getting the correct vertex.position. sigh

I just tried that, and it works just as it should.

Using 3.2 version drivers.

Tried what, the fog?

Hmm, here’s a thought (probably wrong). I have one program.env constant…are any of the constant registers shared? I.e. if I do this:

“PARAM fogInfo = program.env[0];”
“PARAM mvp[4] = { state.matrix.mvp };”

Do I have to worry about the fogInfo stomping on the mvp parameter? If so, how can I find out what numerical values mvp is using so that I can avoid them?

No, you don’t have to worry about that. It’s the driver’s responsibility to allocate actual hardware registers to all parameters, be they environment, local, or state tracking parameters.

Originally posted by Zeno:
Tried what, the fog?

Yeah. Worked fine with and with out position invariant enabled.