NV2A/Pixel Combiner
Data types
NV_texture_shader suggests that: "The 8-bit and 16-bit signed fixed-point types are used for signed internal texture formats, while the 9-bit signed fixed-point type is used for register combiners computations." Here is a table from the GL extension:
floating-point | 8-bit fixed-point | 9-bit fixed-point | 16-bit fixed-point |
---|---|---|---|
1.0 | n/a | 255 | n/a |
0.99996... | n/a | n/a | 32767 |
0.99218... | 127 | n/a | n/a |
0.0 | 0 | 0 | 0 |
-1.0 | -128 | -255 | -32768 |
-1.00392... | n/a | -256 | n/a |
This means:
- 8-bit fixed-point: [-128, 127] → [-128/128, 127/128] → [-1.0, 0.99218...]
- 9-bit fixed-point: [-256, 255] → [-256/255, 255/255] → [-1.00392..., 1.0]
- 16-bit fixed-point: [-32768, 32767] → [-32768/32768, 32767/32768] → [-1.0, 0.99996...]
It is not known if the NV2A really implements these 3 datatypes. It is also not yet known how exactly conversion or negation of these types would work.
Texture Shaders
The NV2A implements at least parts of the following OpenGL extensions:
Texturing modes
ID | Name | D3D name | GL Name | Stage 1 | Stage 2 | Stage 3 | Stage 4 | Notes |
---|---|---|---|---|---|---|---|---|
0x00 | PS_TEXTUREMODES_NONE | NONE | ✔ | ✔ | ✔ | ✔ | ||
0x01 | PS_TEXTUREMODES_PROJECT2D | tex | TEXTURE_2D | ✔ | ✔ | ✔ | ✔ | |
0x02 | PS_TEXTUREMODES_PROJECT3D | tex | TEXTURE_3D | ✔ | ✔ | ✔ | ✔ | |
0x03 | PS_TEXTUREMODES_CUBEMAP | tex | TEXTURE_CUBE_MAP_ARB | ✔ | ✔ | ✔ | ✔ | |
0x04 | PS_TEXTUREMODES_PASSTHRU | texcoord | PASS_THROUGH_NV | ✔ | ✔ | ✔ | ✔ | |
0x05 | PS_TEXTUREMODES_CLIPPLANE | texkill | CULL_FRAGMENT_NV | ✔ | ✔ | ✔ | ✔ | |
0x06 | PS_TEXTUREMODES_BUMPENVMAP | texbem | OFFSET_TEXTURE_2D_NV | ✗ | ✔ | ✔ | ✔ | |
0x07 | PS_TEXTUREMODES_BUMPENVMAP_LUM | texbeml | OFFSET_TEXTURE_2D_SCALE_NV | ✗ | ✔ | ✔ | ✔ | |
0x08 | PS_TEXTUREMODES_BRDF | texbrdf | ✗ | ✗ | ✔ | ✔ | ||
0x09 | PS_TEXTUREMODES_DOT_ST | texm3x2tex | DOT_PRODUCT_TEXTURE_2D_NV | ✗ | ✗ | ✔ | ✔ | |
0x0A | PS_TEXTUREMODES_DOT_ZW | texm3x2depth | DOT_PRODUCT_DEPTH_REPLACE_NV | ✗ | ✗ | ✔ | ✔ | |
0x0B | PS_TEXTUREMODES_DOT_RFLCT_DIFF | texm3x3diff | DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV[citation needed] | ✗ | ✗ | ✔ | ✗ | |
0x0C | PS_TEXTUREMODES_DOT_RFLCT_SPEC | texm3x3vspec | DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV | ✗ | ✗ | ✗ | ✔ | |
0x0D | PS_TEXTUREMODES_DOT_STR_3D | texm3x3tex | DOT_PRODUCT_TEXTURE_3D_NV | ✗ | ✗ | ✗ | ✔ | |
0x0E | PS_TEXTUREMODES_DOT_STR_CUBE | texm3x3vspec | DOT_PRODUCT_REFLECT_CUBE_MAP_NV | ✗ | ✗ | ✗ | ✔ | |
0x0F | PS_TEXTUREMODES_DPNDNT_AR | texreg2ar | DEPENDENT_AR_TEXTURE_2D_NV | ✗ | ✔ | ✔ | ✔ | |
0x10 | PS_TEXTUREMODES_DPNDNT_GB | texreg2gb | DEPENDENT_GB_TEXTURE_2D_NV | ✗ | ✔ | ✔ | ✔ | |
0x11 | PS_TEXTUREMODES_DOTPRODUCT | texm3x3pad texm3x2pad |
DOT_PRODUCT_NV | ✗ | ✔ | ✔ | ✗ | |
0x12 | PS_TEXTUREMODES_DOT_RFLCT_SPEC_CONST | texm3x3spec | DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV | ✗ | ✗ | ✗ | ✔ |
0x08: PS_TEXTUREMODES_BRDF / texbrdf
The BRDF texture shader is probably only exposed on original Xbox, but not in standard OpenGL or D3D drivers.
These are some generic resources about BRDFs:
- Walt Disney BRDF Explorer
- Walt Disney BRDF Paper
- Collection of BRDF information
- BRDF viewer[FIXME]
- BRDF Database by Mitsubishi
- nvidia resources (The code and technique is probably not using the texture shader that is described here):
[FIXME]
Register combiners
The NV2A implements at least parts of the following OpenGL extensions:
There's some additional features and oddities.
DISCARD and ZERO are the same register
On NV2A the DISCARD and ZERO register are the same index: writes are discarded / reads return zero.
This is different from NV_register_combiners where 2 different constants are used.
Encoding of input swizzle
NV2A uses a single ALPHA flag to specify the swizzle of inputs:
- 0 for
.rgb
(RGB portion only) and.b
(ALPHA portion only). - 1 for
.aaa
(RGB portion only) and.a
(ALPHA portion only).
This is different from NV_register_combiners where each swizzle has its own constant.
Per stage constant-colors
The combiner setup switches between using the same const0
and const1
for all stages (FACTOR#_SAME_FACTOR_ALL
), or using different constant-colors per stage (FACTOR#_EACH_STAGE
).
On NV2A, the final-combiner does always have unique constants (even using FACTOR#_SAME_FACTOR_ALL
) from all other stages.
If FACTOR#_SAME_FACTOR_ALL
is used, the constant-colors for all other stages are taken from the very first stage.
This setting can be controlled independently for const0
and const1
.
This is different from NV_register_combiners2. If that GL extension isn't available / enabled, then the constants are shared between general combiner stages and the final combiner (which doesn't have unique colors then). Additionally, the GL extension can only control this for both constant-colors at the same time.
Encoding of constant-colors
On NV2A, the constant-colors are encoded as 8-bit unsigned int values, packed into a 32-bit ARGB value ((a<<24 | r<<16 | g<<8 | b)
).
This is different from NV_register_combiners where constant-colors are specified as floats in RGBA format.
BLUETOALPHA in RGB portion
NV2A has a special flag to write the blue result (RGB portion) of the A/B and C/D computations to the alpha channel of the RGB portion output register. There's no such option for the AB/CD result. [FIXME]
This feature isn't available in GL, probably.
This is different from NV_register_combiners where the RGB portion always writes to .rgb
of the output.
Special "or" operation (MUX) modifier
NV2A has a special flag to switch between MSB and LSB[FIXME] for the special "or" operation (MUX). [FIXME]
This feature isn't available in GL, probably.
This is different from NV_register_combiners where the special "or" operation (MUX) is always doing: spare0_alpha >= 0.5 ? C*D : A*B
.
Debugging
PIX from the Microsoft XDK provides great debugging capabilities.