NVidia's new NV_fragment_program extension

Ostsol

Veteran
I was just looking at the OpenGL extension registry and found a bunch of new extensions. One of them was NV_fragment_program. It appears to allow one to have a great deal of control with regard to the level of precision one has for the values in each register. Here's a snippet:

Section 3.11.4.2: Fragment Program Operation Precision

Fragment program instructions frequently perform mathematical operations.
Such operations may be performed at one of three different precisions.
Fragment programs can specify the precision of each instruction by using
the precision suffix. If an instruction has a suffix of "R", calculations
are carried out with 32-bit floating point operands and results. If an
instruction has a suffix of "H", calculations are carried out using 16-bit
floating point operands and results. If an instruction has a suffix of
"X", calculations are carried out using 12-bit fixed point operands and
results. For example, the instruction "MULR" performs a 32-bit
floating-point multiply, "MULH" performs a 16-bit floating-point multiply,
and "MULX" performs a 12-bit fixed-point multiply. If no precision suffix
is specified, calculations are carried out using the precision of the
temporary register receiving the result.

Fragment program instructions may source registers or constants whose
precisions differ from the precision specified with the instruction.
Instructions may also generate intermediate results with a different
precision than that of the destination register. In these cases, the
values sourced are converted to the precision specified by the
instruction.

When converting to fx12 format, -INF and any values less than -2048/1024
become -2048/1024. +INF, and any values greater than +2047/1024 become
+2047/1024. NaN becomes 0.

When converting to fp16 format, any values less than or equal to -2^16 are
converted to -INF. Any values greater than or equal to +2^16 are
converted to +INF. -INF, +INF, NaN, -0.0, and +0.0 are unchanged. Any
other values that are not exactly representable in fp16 format are
converted to one of the two nearest representable values.

When converting to fp32 format, any values less than or equal to -2^128
are converted to -INF. Any values greater than or equal to +2^128 are
converted to +INF. -INF, +INF, NaN, -0.0, and +0.0 are unchanged. Any
other values that are not exactly representable in fp32 format are
converted to one of the two nearest representable values.

Fragment program instructions using the fragment attribute registers
f[FOGC] or f[TEX0] through f[TEX7] will be carried out at full fp32
precision, regardless of the precision specified by the instruction.

In addition to the extra options for precision, there is also the ability to pack multiple small registers into a 32 bit register. Two 16 bit registers, for example, can be packed to be stored in a 32 bit register.

I'm guessing that this new functionality is how Cg will greatly benefit new NVidia cards (namely the GeforceFX) over others, in OpenGL. The HLSL will be compiled down to NV_fragment_program code, rather than ARB_fragment_program code. Similarily, though, Cg -- if used wisely by developers -- could easily make supporting cards that don't support certain shader extensions easy.

Here's a link to the full extension specs:

http://oss.sgi.com/projects/ogl-sample/registry/NV/fragment_program.txt
 
The coolest thing is being able to pack 16 bytes into one pixel. Very nice if you need to store alot of small scalars.

You could probably do it under DX9 with a bunch extra instructions, but it's nice to have HW support.
 
Back
Top