Xbox D3D drawing is performed via 4 Draw*Vertices*
APIs (and a few other cases, described below);
All 4 Draw*Vertices*
APIs have the two arguments (D3DPRIMITIVETYPE PrimitiveType, UINT VertexCount)
. Additionally:
- One API has a StartVertex argument
- Two draw using indices, and for that have an additional "index data" argument
- Two draw using a 'User Pointer', and for that have additional "stream zero" arguments
The vertex data required for drawing, is either read from up to 16 VertexBuffers (as set by the SetStreamSource
API),
or for the User Pointer (UP) draws, read directly from the supplied Stream Zero pointer (and stride).
Vertex data is composed of 1 up to 16 attributes, as defined in a vertex declaration. Each attribute declaration specifies the StreamSource index from which the attribute data is read. (User Pointer draws are only allowed to read from stream index zero, which will use the supplied pointer, not actually stream zero!)
The order vertices are drawn in, is either:
- sequential, for regular draws (starting at the first vertex, or for
DrawVertices
at the specifiedStartVertex
offset into the vertex buffer), - or according to the specified
pIndexData
(which allows re-using vertices and drawing subsets of available vertices in the given buffer)
Xbox D3D API Arguments (D3DPRIMITIVETYPE PrimitiveType, UINT VertexCount + ...)
--- ---
D3DDevice_DrawVertices (UINT StartVertex)
D3DDevice_DrawVerticesUP (void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
D3DDevice_DrawIndexedVertices (WORD *pIndexData)
D3DDevice_DrawIndexedVerticesUP (WORD *pIndexData, void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
(In the rest of this text, the "D3DDevice_" prefix is sometimes left out for terseness.)
Xbox also supports immediate drawing, using one D3DDevice_BeginPush call, a D3DDevice_SetVertexData* call per vertex and one D3DDevice_EndPush API call. Similar to the other Xbox D3D APIs, these APIs "push" commands and data towards the Xbox GPU (called NV2A) to perform drawing.
( As an optimization, most of these "push buffer commands" generated by Xbox D3D APIs can be recorded and replayed back to the NV2A. Even though playing back these pre-recorded push buffers may require "fixups", it's still faster than repeating the original D3D APIs.)
Most drawing-related commands on NV2A are part of the so-called Kelvin Primitive (or Object, as there's many objects on NV2A - Kelvin has code NV097).
Kelvin Commands that are used for drawing (with their data arguments) :
NV097_SET_BEGIN_END
: Initializes the PrimitiveType to draw, and triggers the draw once all data was sendNV097_SET_VERTEX[_DATA_][2|3|4][F|F_M|S|S_M|UB]
: Updates current attribute data (by the variousSetVertexData*
APIs)NV097_SET_VERTEX_DATA_ARRAY_FORMAT
: Sets the format of attribute data stored in vertex buffer memoryNV097_SET_VERTEX_DATA_ARRAY_OFFSET
: Sets the starting memory address (and stride) for each attribute in the vertex bufferNV097_DRAW_ARRAYS
: Supplies count and starting vertex index in the active vertex buffersNV097_INLINE_ARRAY
: Supplies attribute data of the vertices to be drawnNV097_ARRAY_ELEMENT[16|32]
D3DDevice_DrawVertices
NV097_SET_VERTEX_DATA_ARRAY_FORMAT
(viaSetStateVB
)NV097_SET_VERTEX_DATA_ARRAY_OFFSET
(viaSetStateVB
)NV097_SET_BEGIN_END
NV097_DRAW_ARRAYS
D3DDevice_DrawVerticesUP
NV097_SET_VERTEX_DATA_ARRAY_FORMAT
(viaSetStateUP
)NV097_SET_BEGIN_END
NV097_INLINE_ARRAY
D3DDevice_DrawIndexedVertices
NV097_SET_VERTEX_DATA_ARRAY_FORMAT
(viaSetStateVB
)NV097_SET_VERTEX_DATA_ARRAY_OFFSET
(viaSetStateVB
)NV097_SET_BEGIN_END
NV097_ARRAY_ELEMENT16
D3DDevice_DrawIndexedVerticesUP
NV097_SET_VERTEX_DATA_ARRAY_FORMAT
(viaSetStateUP
)NV097_SET_BEGIN_END
NV097_INLINE_ARRAY
Xbox also supports two derived Draw APIs :
D3DDevice_DrawTriPatch
D3DDevice_DrawRectPatch
Which get converted into push buffer commands, comparable to theDraw*Vertices*
APIs.
On Xbox, the D3DDevice_SetIndices
API is also available, mostly as compatibility with Windows Direct3D 8;
It writes the supplied index data to a global called D3D__IndexData
, which is used by macro's that mimick Windows' DrawPrimitive
APIs. (These macro's forward to the vertex-based Xbox Draw APIs.)
The second argument to D3DDevice_SetIndices
, IndexBase
is stored internally and only used for D3DDevice_DrawIndexedVertices
TODO : Describe how SetStreamSource
and SetVertexShaderInput[Direct]
tie into the above
Home
Usage:
Development:
- Cxbx Reloaded overview
- Developer notes
- Child Process Debugging
- Developing Homebrew and test programs
- HLE v2 Database Method
- Maintaining OOVPAs for HLE function detection
- OOVPA sorting
- Updating a sub moduled Git repository
- Rebase Line Ending Fix
- Xbox D3D drawing via NV2A Kelvin
Other links: