?/TD>
Microsoft DirectX 9.0

Vertex Declaration


Conceptually, the vertex declaration is a way of programming the vertex direct memory access (DMA) and the tessellator engine of the graphics pipe. It expresses the data layout and the tessellator operations concisely. To address the complexity and extensibility of declarations in Microsoft?DirectX?8.x, a new format for expressing vertex streams has been introduced.

Vertex shaders and vertex declarations are no longer bound together at CreateVertexShader time. The shader validation has been divided into two parts. One runs at the vertex shader creation time and the other runs at the DrawPrimitive time. Vertex shaders and vertex declarations are represented by objects.

Decls are no longer expressed as streams of DWORDs. They are expressed as an array of D3DVERTEXELEMENT9 structures. Each element of the array describes one vertex element.

Additionally, to address application programming interface (API) usability issues, there will be a separate SetFVF call that is equivalent to the SetVertexDeclaration call. This is a convenience function; when this call is made, it will clobber the currently set declaration and vice versa. If the driver is pre-DirectX 8.0 (NumStreams is set to 0), SetVertexDeclaration might fail for declarations that cannot be converted to flexible vertex format (FVF) with an error. SetFVF can be used with both the fixed function, as well as the programmable vertex pipeline. Internally, FVF is converted to a vertex shader declaration using the Mapping FVF to DirectX 9.0 Decl. DCL commands in vertex shader functions should be written with this in mind. Because of this conversion, all further discussion will be about vertex declarations only.

D3DVERTEXELEMENT9 Structure

The following are the fields in the D3DVERTEXELEMENT9 structure and their explanations.

A special value for the vertex element is considered the end of vertex shader declaration. This value is #define D3DDECL_END() {0xFF,0,0,0,0,0}.

UsageIndex is used in conjunction with Usage to specify the semantic of a vertex element. Instead of using D3DVSDE_POSITION2 as in DirectX 8.x, now user can specify D3DDECLUSAGE_POSITION as Usage and UsageIndex = 1.

A Decl specifies the input to the tessellator engine (or directly the vertex processing engine in case the tessellator is not used) as well as its output. The type field in the vertex element specifies the type of the input data to the decl. The output type is implied by the method.

There is a preamble in the vertex shader that has the form of {semantic, semantic index, register number}. The runtime matches up the declaration's semantic with the shader's semantic information, thus pairing up an input register with byte offset into a stream.

Mapping FVF to DirectX 9.0 Decl

FVFData typeUsageUsage index
D3DFVF_XYZD3DDECLTYPE_FLOAT3D3DDECLUSAGE_POSITION0
D3DFVF_XYZRHWD3DDECLTYPE_FLOAT4D3DDECLUSAGE_POSITIONT0
D3DFVF_XYZWD3DDECLTYPE_FLOAT4D3DDECLUSAGE_POSITION0
D3DFVF_XYZB5 and D3DFVF_LASTBETA_UBYTE4D3DVSDT_FLOAT3

D3DVSDT_FLOAT4

D3DVSDT_UBYTE4

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES
0
D3DFVF_XYZB5 and D3DFVF_LASTBETA_D3DCOLORD3DVSDT_FLOAT3

D3DVSDT_FLOAT4

D3DVSDT_D3DCOLOR

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES
0
D3DFVF_XYZB5D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT4

D3DDECLTYPE_FLOAT1

D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES
0
D3DFVF_XYZBn (n=1..4)D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOATn
D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT
0
D3DFVF_XYZBn (n=1..4) and D3DFVF_LASTBETA_UBYTE4D3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT(n-1)

D3DDECLTYPE_UBYTE4
D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES
0
D3DFVF_XYZBn (n=1..4) and D3DFVF_LASTBETA_D3DCOLORD3DDECLTYPE_FLOAT3

D3DDECLTYPE_FLOAT(n-1)

D3DDECLTYPE_D3DCOLOR
D3DDECLUSAGE_POSITION

D3DDECLUSAGE_BLENDWEIGHT

D3DDECLUSAGE_BLENDINDICES
0
D3DFVF_NORMALD3DDECLTYPE_FLOAT3D3DDECLUSAGE_NORMAL0
D3DFVF_PSIZED3DDECLTYPE_FLOAT1D3DDECLUSAGE_PSIZE0
D3DFVF_DIFFUSED3DDECLTYPE_D3DCOLORD3DDECLUSAGE_COLOR0
D3DFVF_SPECULARD3DDECLTYPE_D3DCOLORD3DDECLUSAGE_COLOR1
D3DFVF_TEXCOORDSIZEm(n)D3DDECLTYPE_FLOATmD3DDECLUSAGE_TEXCOORDn

Vertex Declarations with D3DDECLUSAGE_POSITIONT

Presence of a vertex element with (D3DUSAGE_POSITIONT, 0) is used to indicate to the device that the vertex data coming in has already been through vertex processing (like an FVF with D3DFVF_XYZRHW bit set). At Draw time, if the currently set declaration has an element with the (D3DUSAGE_POSITIONT, 0) semantic, the entire vertex processing is skipped (just as if an FVF with D3DFVF_XYZRHW bit has been set).

There are some restrictions on vertex declarations with (D3DDECLUSAGE_POSITIONT, 0):

In addition, there are some restrictions on such declaration, related to the device driver version. These restrictions are in effect because Direct3D sends such declarations directly to the driver without doing any conversion.

Pre-DirectX 9.0 Drivers

DirectX 9.0 Drivers without Pixel Shader Version 3 Support

DirectX 9.0 Drivers with Pixel Shader Version 3 Support

More general declarations are allowed.

Vertex Declarations without D3DDECLUSAGE_POSITIONT

Runtime validates the creation of declarations. Following are the general rules for what declarations are legal.

Usage with the Programmable Vertex Pipeline

There are additional restrictions when using with hardware vertex processing on a DirectX 8.x driver :

The CreateVertexDeclaration might fail if the declaration provided cannot be converted to a DirectX 8.x-style decl. For mixed mode device this failure will happen at Draw* time because that is the only time it can be known whether this shader is being used with hardware or software vertex processing.

Usage with the Fixed Function Vertex Pipeline

Only declarations that adhere to the following rules can be used:

When a declaration is used with hardware vertex processing on a DirectX 8.x driver, the Direct3D runtime converts it to a DirectX 8.x-style declaration with the following rules.

Mapping DirectX 9.0 Declaration to DirectX 8.x

DirectX 9.0 UsageDirectX 9.0 Usage IndexDirectX 8.0
D3DDECLUSAGE_POSITION0D3DVSDE_POSITION
D3DDECLUSAGE_POSITION1D3DVSDE_POSITION2
D3DDECLUSAGE_NORMAL0D3DVSDE_NORMAL
D3DDECLUSAGE_NORMAL1D3DVSDE_NORMAL2
D3DDECLUSAGE_BLENDWEIGHT0D3DVSDE_BLENDWEIGHT
D3DDECLUSAGE_BLENDINDICES0D3DVSDE_BLENDINDICES
D3DDECLUSAGE_PSIZE0D3DVSDE_PSIZE
D3DDECLUSAGE_COLOR0D3DVSDE_DIFFUSE
D3DDECLUSAGE_COLOR1D3DVSDE_SPECULAR
D3DDECLUSAGE_TEXCOORDnD3DVSDE_TEXCOORDn

When a declaration is used with hardware vertex processing on a DirectX 7.0 driver, the Direct3D runtime converts it to an FVF with the following rules.

Mapping DirectX 9.0 Declaration to FVF Bits

Data typeUsageUsage indexFVF
D3DDECLTYPE_FLOAT3D3DDECLUSAGE_POSITION0D3DFVF_XYZ
D3DDECLTYPE_FLOAT4D3DDECLUSAGE_POSITIONT0D3DFVF_XYZRHW
D3DDECLTYPE_FLOATnD3DDECLUSAGE_BLENDWEIGHT0D3DFVF_XYZBn
D3DDECLTYPE_UBYTE4D3DDECLUSAGE_BLENDINDICES0D3DFVF_XYZB (nWeights+1)
D3DDECLTYPE_FLOAT3D3DDECLUSAGE_NORMAL0D3DFVF_NORMAL
D3DDECLTYPE_FLOAT1D3DDECLUSAGE_PSIZE0D3DFVF_PSIZE
D3DDECLTYPE_D3DCOLORD3DDECLUSAGE_COLOR0D3DFVF_DIFFUSE
D3DDECLTYPE_D3DCOLORD3DDECLUSAGE_COLOR1D3DFVF_SPECULAR
D3DDECLTYPE_FLOATmD3DDECLUSAGE_TEXCOORDnD3DFVF_TEXCOORDSIZEm(n)
D3DDECLTYPE_FLOAT3D3DDECLUSAGE_POSITION1N/A
D3DDECLTYPE_FLOAT3D3DDECLUSAGE_NORMAL1N/A

Using Vertex Declarations with ProcessVertices

A vertex declaration could be used to describe the output of ProcessVertices. Such declaration should adhere to the following rules.



© 2002 Microsoft Corporation. All rights reserved.