GL_VERTEX_STATE_PROGRAM_NV

HI!
According to the Nvidia spec, when ExecuteProgramNV(enum target, uint id, const float *params); is called, the 4 float array defined by “params” is passed over into vertex attribute register 0. I believe I am right in thinking this is v[OPOS]… if not tell me.

I wrote a state program which just passes over some constants into the C registers, however, on moving c[i] to c[J] works fine, but moving V[OPOS] to c[J] does not. It seems as if ExecuteProgramNV is not moving the values over into v[OPOS]. Anyone else had any problems like this?

I’m using Detonator 10.80, with a geforce 256 under win2k.

Matt or Cass, any ideas?

Cheers,

  • Nutty

Pheeewww… Took me 45mn to figure out this one !

First, I always got an error with glGetError because I was trying to bind the vertex state program… Don’t try it guys, it’s useless (actually, you specify which one to use in glExecuteProgramNV).

Then I forgot that Vertex State Programs start with “!!VSP1.0” instead of “!!VP1.0”…

In the end, I manage to reproduce what you describe i.e. it does not work to do the following:

char Mover=
{
“!!VSP1.0
MOV c[0],v[OPOS];
END”
};

I don’t know if the behaviour is by design or if it is a bug in the aliasing but doing the following works:

char Mover=
{
“!!VSP1.0
MOV c[0],v[0];
END”
};

I agree that v[0] and V[OPOS] should be the same (page 441 of the nVidia OpenGL specs) but it seems that you have to use v[0] and not v[OPOS] if you don’t want to be thrown out by glLoadProgramNV…

Bug or design ??? As Richard, said: Matt, Cass ?

Best regards.

Eric

I’ve read the vertex shaders specification last week, and if i remember well, there are basic differences between vertex programs and vertex state programs. One of them are ( to be confirmed ) that you can read from the v0 register ( only v0 ?! ), but can’t write at all to any v register… look at the register access restrictions chapter in the specif.

Y.

Lo…
Well I tried MOV c[19],v[0];

and I got a crash… using 10.80… using v[OPOS] worked. in the spec it says that OPOS is index 0. So it should work…

Apart from this thingy, my vertex state programs work fine.

You know that cube map/specular/point light thingy you tried in Heathrow? Well I now use a state program to convert the light source into local space removing the need to convert vertices and normals into world space, saving 7 instructions in the vertex program.

I’m not really bothered about the arguments passed into v[0], but I just happened to find it not working when I was experimenting.

Theres a limit to the number of C constants you can access in a single instruction. I was doing.

DP4 c[19],c[8],c[20]
etc etc…

but that didn’t work… had to move c[8] into R0, and use that… works fine now…

Fun day at work today… spend the entire day doing no work cos of network problems… finally sorted it out… by changing domains… and everyones user settings are shafted… YAY!!!

I have no email either… HURRAH!!! :stuck_out_tongue:

  • Nutty

P.S. The new program with vertex state is on my website…
www.nutty.org

oooops!!

actually I’ve just tried it… and with v[OPOS] it dont crash, but it aint executed… with v[0] it works.

it seems to be actually passing the args over to v[0] now too… so actually forget this thread all works fine… DOH!!

must’ve been somat else screwing up!!!

ah well…

  • Nutty

Check the grammar for VSPs, and you’ll find that it is explicitly stated that only v[0] is allowed.

So design, not bug.

  • Matt

Originally posted by mcraighead:
Check the grammar for VSPs, and you’ll find that it is explicitly stated that only v[0] is allowed.

Actually it makes perfect sense: there is no such thing as a vertex position (OPOS) in a vertex state program !

Just a question though…The “binding” system for vertex programs is supposed to be “inspired” by the textures one.

So why don’t we do something like:

glBindProgramNV(GL_VERTEX_PROGRAM_NV,1);
glLoadProgramNV(GL_VERTEX_PROGRAM_NV,strlen((char * ) Shader), Shader); // Notice that I removed the id of the program in the call to glLoadProgramNV… DON’T DO IT !

which is more similar to glBindTexture/glTexImage… ???

OK, that is not important… I just thought people were trying to keep some kind of consistency in the API calls !

Best regards.

Eric

P.S.: Richard, I’ll have a look at your demo today !!!

Originally posted by Nutty:
[b]I’m not really bothered about the arguments passed into v[0], but I just happened to find it not working when I was experimenting.

Theres a limit to the number of C constants you can access in a single instruction. I was doing.
[/b]

Actually, now that we know that v[0] works, you can save 1 instruction in your vertex state program !!!

Here is what I did:

I created a Vector 4 class:

typedef struct
{
float x, y, z, w;

}Vector4;

This class is used for your light_pos variable:

// This is the position of the light.
Vector4 light_pos={0.0f, 2.0f, 4.0f, 1.0f};

Change your vertex state program to:

const unsigned char State1 =
{
“!!VSP1.0”
//Convert light in v[0] to local space in c[19]
“DP4 c[19].x,v[0],c[20];
DP4 c[19].y,v[0],c[21];
DP4 c[19].z,v[0],c[22];
DP4 c[19].w,v[0],c[23];”
“END”
};

Now, change your call to glExecuteProgramNV by:

//Execute state program. This converts the light position into local space!
glExecuteProgramNV(GL_VERTEX_STATE_PROGRAM_NV, 2, &light_pos.x);

You can delete the declaration of state_args as well as this piece of code:

//Reload the light position into register 8 for the vertex program to use.
glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 8, light_pos.x, light_pos.y, light_pos.z, 1); // Light position.

Instead of passing the light position in c[8], you pass it as an argument to the vertex state programs via v[0]. And you can access v[0] in your DP4 without using a Rx register… Saved one instruction !

Regards.

Eric

P.S.: I e-mailed the modified source to you !

Here’s a peice of code i wrote up really quick…
was getting tired of using source files for vertex_program stuff…

http://www.angelfire.com/ab3/nobody/nv_programbuild.c

btw, if you make code changes to support c style comments/make it more robust, please send me the code so i can post it for others to use…

laterz,
-akbar A.

Thanks eric… 1 instruction per object aint that much though… Think I will convert it to that…

we still have no email here though… ah the joys of networks!

Nutty

Originally posted by Nutty:
1 instruction per object aint that much though…

Tsss, tsss…

After Richard Huddy’s “Batch, batch, batch, batch”, you should know that every single instruction counts !

Regards.

Eric

Nice work!
My trained assembler eye shows me at least three obviously unnecessary instructions.
(In case it’s not working, I haven’t tested it )

//Calculate cube mapping section.
ADD o[TEX0].xyz,R2,-R3; // Removed R6

//Store these in x and Y component of 2nd texture unit.
MUL o[TEX1].xy,R4.x,c[9].x; // Removed two MOVs

Cheers Relic, yes they do work…

it’s been quite a while since I’ve done assembler… must catch up on this kind of stuff…

P.S. Just removed another 2, from substituting muls and adds for MAD.

[This message has been edited by Nutty (edited 03-16-2001).]

Yup, I have seen there was a formula with R2 - (R5 * 2 * R3) which could be done with a MAD.
I love this instruction set

Originally posted by Relic:
I love this instruction set

So do I !

It reminds me of the Motorola DSP 56001 that was on my Atari Falcon 030, along with the Motorola 68030…

nVIDIA’s GeForce3 looks a lot like a DSP to me ! Actually, on this DSP you could do the MAD thing (called mac) but you could, in the same clock cycle, round the result and do two memory transfers in parallel… OK, that will be GeForce4 (I hate this numbering system ! )

Regards.

Eric

Off topic:
>>It reminds me of the Motorola DSP 56001 that was on my Atari Falcon 030, along with the Motorola 68030…

I skipped that one, but still own an Atari 260ST with 8 MHz 68000 and RAM maxed to 1MB of memory. Woohoo…