Input Registers

The input registers are how data gets passed to the pixel shader. All registers consist of a four-element vector, with at least 8 bits of precision per component in some of the earlier implementations, which may cause round off to be a problem in long complicated shaders.   In PS 1.4, if you need more precision, then you can use texture coordinate registers to pass in higher precision values. See the texture register section for more information.

 

Input to the pixel shader consists of the vertex color registers, the texture registers, and the constant registers. The vertex color registers are the direct output of the vertex shader – the values in oD0 and oD1 or, if no vertex shader was used, the diffuse and specular colors generated by the fixed function pipeline. The constant registers are constants that are set up prior to the shader being called or are set inside the shader code itself. The texture registers are either actual texture coordinate data or actual sampled texture data (for PS 1.0 through 1.3, 2.0 & 3.0) or are just texture coordinate data (PS 1.4).

 

v[n] – the Vertex Color Registers
Pixel shader vertex color registers consist of at least two read-only registers that are generated as output from the vertex shader or the fixed function pipeline. If the current render state is flat shading D3DSHADE_FLAT, then the vertex color registers only use the vertex shader color data from the first vertex in the triangle. If Gouraud shading is enabled i.e.D3DSHADE_GOURAUD, then the pixel values will be a linear interpolation of the three vertex color values used in the current triangle’s vertices. The vertex color registers (potentially) have the lowest precision of all the registers, but a minimum of eight unsigned bits of precision.

 

 

Vertex Color Register Properties

PS Version

1.0

1.1

1.2

1.3

1.4

2.0

Number

2

2

2

2

2 (See note)

2

Port limits

1

2

2

2

2

1

Read/Write?

RO

RO

RO

RO

RO

RO

Range

0,1

0,1

0,1

0,1

0,1

0,1

 

NOTE: In PS 1.4 you can only use the vertex color register in phase two.

c[n] – the Constant Registers

The pixel shader constant registers are similar to the ones we used for vertex shaders. Just like those vertex shader constant registers, the pixel shader constant registers are

read-only. There are at least eight constant registers, but generally only two can be used at once in a single pixel shader instruction.

 

Due to the limited precision of pixel shader math (the registers values might possibly be represented internally by a fixed point representation) pixel shader constant registers can only have a range of [-1,1].

 

Constant Register Properties

PS Version

1.0

1.1

1.2

1.3

1.4

2.0

Number

8

8

8

8

8

32

Port limits

2

2

2

2

2

2

Read/Write?

RO

RO

RO

RO

RO

RO

Range

-1,1

-1,1

-1,1

-1,1

-1,1

float

 

 

You set pixel shader constant registers either by using the def instruction in the shader or by using SetPixelShaderConstant(). Unlike vertex shaders, the def instruction requires no other effort on the part of the programmer, the constant value are set when the shader is loaded. You can override values set in the shader using the def instruction after the shader is loaded by a subsequent call to SetPixelShaderConstant().

 

You generally cannot use constant register with the texture instructions – the exception being the texm3x3spec instruction.

 

t[n] – the Texture Registers
A significant difference between vertex shaders (which have texture-coordinate registers), pixel shaders have texture color registers. The number of texture registers is the same as the number of simultaneous textures that are supported by the current interface.

 

There is a significant difference between the way that the texture registers are used between pixel shaders 1.0 though 1.3 and pixel shaders 1.4.

 

Texture Register Properties

PS Version

1.0

1.1

1.2

1.3

1.4

Number

4

4

4

4

6

Port limits

1

2

3

3

1

Read/Write?

See note

RW

RW

RW

RO

Range

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxTexture-Repeat

 

NOTE: For PS 1.0 the texture registers are read-write for texture addressing instructions, but read-only for arithmetic instructions.

 

For pixel shaders 1.1 though 1.3

The value in the texture register is a sample of the texture at the interpolated point – that is, it’s a color value. The interpolated value consists of (u, v, w, q) data, as interpolated from the current texture stage attributes. There is a one-to-one association between the texture stage and the texture coordinate declaration order. This means that the texture selected in stage n will provide the color values passed into the pixel shader in the texture registers. Texture coordinates are read-write, which means that you can use them as temporary register if you need to.

 

For pixel shaders 1.4

The texture registers for 1.4 pixel shaders should be thought of as texture coordinate registers since they can only contain read-only texture coordinates. This means that the data in the texture register is not color data as in previous pixel shader versions.  The texcrd instruction is used to pass texture coordinates, and the texld instruction is used to sample a texture. Texture samples will end up in temporary registers.

 

The texture stage that is used to sample from is no longer associated with the texture coordinate declaration order, but is determined by the destination register number. Thus when you actually load a texture value using texld, the texture register used as the source register will contain the texture coordinate information, while the destination register number will correspond to the texture to sample.

 

Initialized texture registers contain the output from the texture-sampling units after any filtering modes set for that texture stage. Unused/uninitialized texture registers have a setting of opaque-black (0,0,0,1). [Verify..???]

 

It also means that you can no longer use them as temporary registers.

 

Loading a texture coordinate will only place three components into the register, even though a texture coordinate starts out as a four element register. Thus you have to use a destination register write mask when using the texld, or texcrd instructions.

 

If you want to perform a perspective divide in a PS 1.4, the D3DTTFF_PROJECTED flag is ignored. You can perform a perspective divide on the .x and .y texture coordinates using the _dw modifier and the results require a .xy write mask.

 

For pixel shaders 2.0

In order to end confusion about texture coordinates vs. texture sampling using the texture registers, the PS 2.0 model breaks these into two separate sets of registers.

Temporary Registers

r[n] – the Temporary Registers

The temporary registers can be used to hold anything you want in a pixel shader.

 

                                                     Temporary Register Properties

PS Version

1.0

1.1

1.2

1.3

1.4

2.0

Number

2

2

2

2

6

24

Port limits

2

2

3

3

3

3

Read/Write?

RW

RW

RW

RW

RW

RW

Range

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

±MaxPixel-ShaderValue

float

 

Temporary registers are considered uninitialized when a vertex shader is first loaded, and an attempt to assemble a shader that fails to initialize a temporary register before using it will fail validation.

 

The r0 register is a special case and all pixel shaders must write r0 as the final color of the pixel that is being rendered.

 

The r5.r register element is used as output if you used the texdepth instruction.

 

Note: Since texture registers are read-write (except in PS 1.4 and PS 2.0) you are free to use an unused (or no longer needed) texture coordinate registers as extra temporary registers.

 

s[n] – the Texture Sampling Stage Registers

The DirectX 9 pixel shader 2.0 model separated the texture registers into texture coordinate registers and texture sample stage registers.A sampling stage register identifies a sampling unit that can be used in texture load statements. A sampling unit corresponds to a texture sampling stage, encapsulating the sampling-specific state provided in the TextureStageState construct (called SamplerState in DirectX 9). Each sampler uniquely identifies a single texture surface which is set to the corresponding sampler using SetTexture() method. The same texture surface can be set at multiple samplers. A texture cannot be simultaneously set as a render target and a texture. A sampler register may only appear as an argument in texture load statements

Two new render states were added that effect texture sampling stage registers:

D3DSAMP_SRGBTEXTURE which indicates that this sampler should assume gamma of 2.2 on the content and convert it to gamma 1.0 (linear gamma) before sending it to the pixel shader.

D3DSAMP_ELEMENTINDEX describes which element index to use when a MET surface is set to the sampler. The MET surface must be supported or this render state is ignored.

Declaring Register Usage

 DirectX 9’s PS 2.0 model requires that all registers (except temp and constant) used in a shader be declared via the dcl statement down to the component (rgba) level. This is to simplify things for optimization and verification.