Difference between revisions of "NV2A/Pixel Combiner"

From xboxdevwiki
Jump to: navigation, search
(Attempted to add D3D names)
(Found another nvidia mirror for BRDFs.pdf; added to archive.org)
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
The NV2A implements [https://www.opengl.org/registry/specs/NV/register_combiners.txt NV_register_combiners] (and [https://www.opengl.org/registry/specs/NV/register_combiners2.txt NV_register_combiners2]?)
+
== Data types ==
  
== Texturing modes ==
+
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:
 +
 
 +
{| class="wikitable"
 +
! 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:
 +
 
 +
* [https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_shader.txt NV_texture_shader]
 +
* [https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_shader2.txt NV_texture_shader2]
 +
* [https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_shader3.txt NV_texture_shader3]{{citation needed}}
 +
 
 +
=== Texturing modes ===
  
 
{|class="wikitable"
 
{|class="wikitable"
 
!ID
 
!ID
 
!Name
 
!Name
 +
!D3D name
 +
!GL Name
 
!Stage 1
 
!Stage 1
 
!Stage 2
 
!Stage 2
Line 13: Line 51:
 
|-
 
|-
 
|0x00
 
|0x00
|PS_TEXTUREMODES_NONE<br>texcoord?{{citation needed}}
+
|PS_TEXTUREMODES_NONE
|*
+
|
|*
+
|NONE
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x01
 
|0x01
|PS_TEXTUREMODES_PROJECT2D<br>tex
+
|PS_TEXTUREMODES_PROJECT2D
|*
+
|tex
|*
+
|TEXTURE_2D
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x02
 
|0x02
 
|PS_TEXTUREMODES_PROJECT3D
 
|PS_TEXTUREMODES_PROJECT3D
|*
+
|tex
|*
+
|TEXTURE_3D
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x03
 
|0x03
 
|PS_TEXTUREMODES_CUBEMAP
 
|PS_TEXTUREMODES_CUBEMAP
|*
+
|tex
|*
+
|TEXTURE_CUBE_MAP_ARB
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x04
 
|0x04
|PS_TEXTUREMODES_PASSTHRU<br>texcoord?{{citation needed}}
+
|PS_TEXTUREMODES_PASSTHRU
|*
+
|texcoord
|*
+
|PASS_THROUGH_NV
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x05
 
|0x05
|PS_TEXTUREMODES_CLIPPLANE<br>texkill
+
|PS_TEXTUREMODES_CLIPPLANE
|*
+
|texkill
|*
+
|CULL_FRAGMENT_NV
|*
+
|{{yes}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x06
 
|0x06
|PS_TEXTUREMODES_BUMPENVMAP<br>texbem
+
|PS_TEXTUREMODES_BUMPENVMAP
|
+
|texbem
|*
+
|OFFSET_TEXTURE_2D_NV
|*
+
|{{no}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x07
 
|0x07
|PS_TEXTUREMODES_BUMPENVMAP_LUM<br>texbeml
+
|PS_TEXTUREMODES_BUMPENVMAP_LUM
|
+
|texbeml
|*
+
|OFFSET_TEXTURE_2D_SCALE_NV
|*
+
|{{no}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x08
 
|0x08
|PS_TEXTUREMODES_BRDF<br>texm3x2tex
+
|PS_TEXTUREMODES_BRDF
|
+
|texbrdf
 
|
 
|
|*
+
|{{no}}
|*
+
|{{no}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x09
 
|0x09
|PS_TEXTUREMODES_DOT_ST<br>texm3x2pad?{{citation needed}}
+
|PS_TEXTUREMODES_DOT_ST
|
+
|texm3x2tex
|
+
|DOT_PRODUCT_TEXTURE_2D_NV
|*
+
|{{no}}
|*
+
|{{no}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x0A
 
|0x0A
|PS_TEXTUREMODES_DOT_ZW<br>texm3x2tex?{{citation needed}}
+
|PS_TEXTUREMODES_DOT_ZW
|
+
|texm3x2depth
|
+
|DOT_PRODUCT_DEPTH_REPLACE_NV
|*
+
|{{no}}
|*
+
|{{no}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x0B
 
|0x0B
 
|PS_TEXTUREMODES_DOT_RFLCT_DIFF
 
|PS_TEXTUREMODES_DOT_RFLCT_DIFF
|
+
|texm3x3diff
|
+
|DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV{{citation needed}}
|*
+
|{{no}}
|
+
|{{no}}
 +
|{{yes}}
 +
|{{no}}
 
|
 
|
 
|-
 
|-
 
|0x0C
 
|0x0C
 
|PS_TEXTUREMODES_DOT_RFLCT_SPEC
 
|PS_TEXTUREMODES_DOT_RFLCT_SPEC
|
+
|texm3x3vspec
|
+
|DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV
|
+
|{{no}}
|*
+
|{{no}}
 +
|{{no}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x0D
 
|0x0D
 
|PS_TEXTUREMODES_DOT_STR_3D
 
|PS_TEXTUREMODES_DOT_STR_3D
|
+
|texm3x3tex
|
+
|DOT_PRODUCT_TEXTURE_3D_NV
|
+
|{{no}}
|*
+
|{{no}}
 +
|{{no}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x0E
 
|0x0E
 
|PS_TEXTUREMODES_DOT_STR_CUBE
 
|PS_TEXTUREMODES_DOT_STR_CUBE
|
+
|texm3x3vspec
|
+
|DOT_PRODUCT_REFLECT_CUBE_MAP_NV
|
+
|{{no}}
|*
+
|{{no}}
 +
|{{no}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x0F
 
|0x0F
|PS_TEXTUREMODES_DPNDNT_AR<br>texreg2ar
+
|PS_TEXTUREMODES_DPNDNT_AR
|
+
|texreg2ar
|*
+
|DEPENDENT_AR_TEXTURE_2D_NV
|*
+
|{{no}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x10
 
|0x10
|PS_TEXTUREMODES_DPNDNT_GB<br>texreg2gb
+
|PS_TEXTUREMODES_DPNDNT_GB
|
+
|texreg2gb
|*
+
|DEPENDENT_GB_TEXTURE_2D_NV
|*
+
|{{no}}
|*
+
|{{yes}}
 +
|{{yes}}
 +
|{{yes}}
 
|
 
|
 
|-
 
|-
 
|0x11
 
|0x11
 
|PS_TEXTUREMODES_DOTPRODUCT
 
|PS_TEXTUREMODES_DOTPRODUCT
|
+
|texm3x3pad<br>texm3x2pad
|*
+
|DOT_PRODUCT_NV
|*
+
|{{no}}
|
+
|{{yes}}
 +
|{{yes}}
 +
|{{no}}
 
|
 
|
 
|-
 
|-
 
|0x12
 
|0x12
 
|PS_TEXTUREMODES_DOT_RFLCT_SPEC_CONST
 
|PS_TEXTUREMODES_DOT_RFLCT_SPEC_CONST
|
+
|texm3x3spec
|
+
|DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV
|
+
|{{no}}
|*
+
|{{no}}
 +
|{{no}}
 +
|{{yes}}
 
|
 
|
 
|}
 
|}
  
Also known from nvidia docs:  
+
=== 0x08: PS_TEXTUREMODES_BRDF / texbrdf ===
* texm3x3pad [stage 1, stage 2]
+
 
* texm3x3spec [stage 3]
+
The BRDF texture shader is probably only exposed on original Xbox, but not in standard OpenGL or D3D drivers.
* texm3x3vspec [stage 3]
+
 
* texm3x3tex [stage 3]
+
These are some generic resources about BRDFs:
 +
 
 +
* [http://www.disneyanimation.com/technology/brdf.html Walt Disney BRDF Explorer]
 +
* [https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf Walt Disney BRDF Paper]
 +
* [https://math.nist.gov/~FHunt/appearance/brdf.html Collection of BRDF information]
 +
* [http://www-graphics.stanford.edu/~smr/brdf/bv/ BRDF viewer]{{FIXME|reason=Find alternative; this one is hard to compile}}
 +
* [https://www.merl.com/brdf/ BRDF Database by Mitsubishi]
 +
 
 +
* nvidia resources ''(The code and technique is probably not using the texture shader that is described here)'':
 +
 
 +
** [https://web.archive.org/web/20200506033455/http://developer.download.nvidia.com/assets/gamedev/docs/BRDFs.pdf BRDFs.pdf] / [http://www.nvidia.in/attach/6669 BRDFs.ppt]{{FIXME|reason=URL dead; not in archive.org!}}
 +
** [https://web.archive.org/web/20191214200801/https://www.nvidia.com/attach/6568 BRDFIntro.pdf] / [https://web.archive.org/web/20191214200809/https://www.nvidia.com/attach/6569 BRDFIntro.doc]
 +
** [https://web.archive.org/web/20191214200757/https://www.nvidia.com/attach/6567 BRDFSeparable.pdf] / [https://web.archive.org/web/20191214200753/https://www.nvidia.com/attach/6566 BRDFSeparable.doc]
 +
** [https://web.archive.org/web/20191214200813/https://www.nvidia.com/attach/6570 brdfseparate.zip]
 +
** [https://web.archive.org/web/20191214200819/https://www.nvidia.com/attach/6571 brdfview.zip]
 +
 
 +
{{FIXME|reason=Describe Xbox specific BRDF texture shader}}
 +
 
 +
== Register combiners ==
 +
 
 +
The NV2A implements at least parts of the following OpenGL extensions:
 +
 
 +
* [https://www.opengl.org/registry/specs/NV/register_combiners.txt NV_register_combiners]
 +
* [https://www.opengl.org/registry/specs/NV/register_combiners2.txt NV_register_combiners2]
 +
 
 +
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 <code>.rgb</code> (RGB portion only) and <code>.b</code> (ALPHA portion only).
 +
* 1 for <code>.aaa</code> (RGB portion only) and <code>.a</code> (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 <code>const0</code> and <code>const1</code> for all stages (<code>FACTOR#_SAME_FACTOR_ALL</code>), or using different constant-colors per stage (<code>FACTOR#_EACH_STAGE</code>).
 +
 
 +
On NV2A, the final-combiner does always have unique constants (even using <code>FACTOR#_SAME_FACTOR_ALL</code>) from all other stages.
 +
If <code>FACTOR#_SAME_FACTOR_ALL</code> is used, the constant-colors for all other stages are taken from the very first stage.
 +
This setting can be controlled independently for <code>const0</code> and <code>const1</code>.
 +
 
 +
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 (<code>(a<<24 | r<<16 | g<<8 | b)</code>).
 +
 
 +
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|reason=Document specifics, tests proposed on https://github.com/JayFoxRox/nxdk/pull/33}}
 +
 
 +
This feature isn't available in GL, probably.
 +
This is different from NV_register_combiners where the RGB portion always writes to <code>.rgb</code> of the output.
 +
 
 +
=== Special "or" operation (MUX) modifier ===
 +
 
 +
NV2A has a special flag to switch between MSB and LSB{{FIXME|reason=Unconfirmed / untested - doesn't make a lot of sense}} for the special "or" operation (MUX).
 +
{{FIXME|reason=Check the comparison type}}
 +
 
 +
This feature isn't available in GL, probably.
 +
This is different from NV_register_combiners where the special "or" operation (MUX) is always doing: <code>spare0_alpha >= 0.5 ? C*D : A*B</code>.
  
 
== Debugging ==
 
== Debugging ==
Line 175: Line 322:
 
PIX from the Microsoft XDK provides great debugging capabilities.
 
PIX from the Microsoft XDK provides great debugging capabilities.
  
== References and links ==
+
=== References and links ===
  
 +
* [http://developer.download.nvidia.com/assets/gamedev/docs/ProgrammableTextureBlending.pdf Overview about programmable texture blending] <!-- Mirror: https://www.nvidia.com/object/programmable_texture_blending.html -->
 +
* [http://developer.download.nvidia.com/assets/gamedev/docs/combiners.pdf Overview of register combiners]
 +
* [https://github.com/XboxDev/nxdk/blob/77b5de45f0c64e70f2ff68248873448d5edccc71/tools/fp20compiler/ps1.0_program.cpp#L227 Code from nvparse (NVIDIA SDK 9.52) in nxdk, which handles shader to OpenGL conversion]
 
* http://developer.download.nvidia.com/assets/gamedev/docs/GDC2K1_DX8_Pixel_Shaders.pdf
 
* http://developer.download.nvidia.com/assets/gamedev/docs/GDC2K1_DX8_Pixel_Shaders.pdf
* http://developer.download.nvidia.com/assets/gamedev/docs/ProgrammableTextureBlending.pdf
+
 
 +
[[Category:NV2A]]

Latest revision as of 03:37, 6 May 2020

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:

  • 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.

References and links