understanding ftransform

ive decided to go the whole gl2.0 route, which means ive gotta go from

void main(void)
{
gl_Position = ftransform();
}


to this

attribute vec4 vert;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vert;
}


or else theres depth fighting (if i do two passes one with methodA + one with methodB), my question is why? (yes i know in the spec it saiz its not guaranted to be the same) but surely at the end of the day they would implement the above the same way thus the results should be the same!

Originally posted by zed:
but surely at the end of the day they would implement the above the same way thus the results should be the same!
That assumption is incorrect.

The calculation done in the fixed function mode might be done in slightly different way (e.g. different precision, different rounding behaviour) especially if the gpu contains specialized hw support for fixed function (this was case for nVidia cards up to and including GeForce FX).

Even if the gpu does not have specialized circuits for that, it is possible that the optimalizations done by the compiler when you use the matrix multiplications might result in slightly different results from the custom code that is run when the fixed function mode is emulated.

Even if the gpu does not have specialized circuits for that, it is possible that the optimalizations done by the compiler when you use the matrix multiplications might result in slightly different results from the custom code that is run when the fixed function mode is emulated.
thanks komat, i dont know how this could be possible, i assume the minimum precision with fixed + glsl is the same thus if theyre giving different results then its an error.

ok i have a gffx, now i get different results if one shader uses ftransform + one uses glsl, now which one should i be using (yes i know the answer is use ftransform if u want the fixed function result)
i mean is it good to use ftransform in the midst of a shader, ie i can imagine it going, (a day in the life of a shader)

la de da, yeah normalize this vector here
hang on he wants a ftransform, go wake up fixed func fred + see what he saiz
ok jim here just got back from the other building anyways fred saiz the answer is …

ie is it a good idea mixing the two as in is it suboptimal

then again if i dump the fixed pipeline, ill lose all the nice global uniform things
vec4 camera_pos = gl_ModelViewMatrixInverse[3];
lightpositions etc

glsl needs global uniforms … badly

Originally posted by zed:
thanks komat, i dont know how this could be possible, i assume the minimum precision with fixed + glsl is the same thus if theyre giving different results then its an error.

The GL standard does define the precision only to some degree.

It is possible that the precision in which the vertex shader calculations are done might vary between various types of instructions (e.g. some calculations might be internally done in higher/lower precision than the one that is stored in registers) so the result might depend on type and order of instructions used to calculate it. This is true even for float calculations you do on the CPU.

Because of this, even if the fixed function is always emulated by shaders, there might be difference in the result between the code generated by the compiler and the code hand optimalized by the card vendor.

When there is special ff unit on the GPU, that unit might have different precision and behaviour from the sequence of shader instructions that does “the same” calculation, for example because it uses specialized multiplier+adder units. Additionaly the special unit might be designed to take advantage of knowledge of rest of the chip to increase performance of the calculation. For example: the rasterizer unit that converts triangle to the fragments does have only limited subpixel precision because there is no need to handle pixel x coordinates 5.0000001 and 5.0000002 differently (no one will notice that) so it will round positions to nearest subpixel (for purpose of this example say 0.01, altrough it will likely be some numer with good float representation) . With this knowledge the specialized unit does not need to generate result that has higher precision than this.

Now the problem happens: Say that the ff unit calculates (using the lower precision) that the position is 0.035 so the rasterizer will round it to the 0.04 subpixel. The shader unit with higher precision calculates that the result really is 0.0344 so the rasterizer will round it to the 0.03 subpixel and now the interpolation is different from the ff case.

[b]
ok i have a gffx, now i get different results if one shader uses ftransform + one uses glsl, now which one should i be using (yes i know the answer is use ftransform if u want the fixed function result)
i mean is it good to use ftransform in the midst of a shader, ie i can imagine it going, (a day in the life of a shader)

la de da, yeah normalize this vector here
hang on he wants a ftransform, go wake up fixed func fred + see what he saiz
ok jim here just got back from the other building anyways fred saiz the answer is …
[/b]
While it might be theoretically possible for the gpu to have special shader instruction “calculate position using the ff unit”, it is unlikely. What most likely happens is that the ftransform function is replaced with hand made shader code that is designed in such way that the result will be, after various rounding and clamping, the same as result of the ff unit.

If ff unit is not present, the code will probably be the same as code that is used during the ff emulation.

So, with the exception of more instructions and possible additional constants, there should be no special cost for using ftransform() function.

[b]
ie is it a good idea mixing the two as in is it suboptimal

then again if i dump the fixed pipeline, ill lose all the nice global uniform things
vec4 camera_pos = gl_ModelViewMatrixInverse[3];
lightpositions etc
[/b]
Use of such uniforms should not interact with the ff unit (if available) in any way. They are only for convenience and they basically are “masked” uniforms whose value is managed by the OGL driver. There might be some cpu/gpu cost associated with update of such uniforms because that path is probably not optimized that much as ordinary uniforms.


glsl needs global uniforms … badly

I agree.