diff --git a/Xbox-D3D-drawing-via-NV2A-Kelvin.md b/Xbox-D3D-drawing-via-NV2A-Kelvin.md new file mode 100644 index 0000000..1c59300 --- /dev/null +++ b/Xbox-D3D-drawing-via-NV2A-Kelvin.md @@ -0,0 +1,83 @@ +Xbox D3D Drawing is performed via 4 Draw*Vertices* API's (and a few other cases, described below); + +All 4 Draw*Vertices* API's 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 specified StartVertex offset into the vertex buffer), +* or according to the specified IndexData (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 API's, these API's "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 API's 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 API's.) + + +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 send +* NV097_SET_VERTEX[_DATA_][2|3|4][F|F_M|S|S_M|UB] : Updates current attribute data (by the various SetVertexData API's) +* NV097_SET_VERTEX_DATA_ARRAY_FORMAT : Sets the format of attribute data stored in vertex buffer memory +* NV097_SET_VERTEX_DATA_ARRAY_OFFSET : Sets the starting memory address (and stride) for each attribute in the vertex buffer +* NV097_DRAW_ARRAYS : Supplies count and starting vertex index in the active vertex buffers +* NV097_INLINE_ARRAY : Supplies attribute data of the vertices to be drawn +* NV097_ARRAY_ELEMENT[16|32] + +D3DDevice_DrawVertices +* NV097_SET_BEGIN_END +* NV097_SET_VERTEX_DATA_ARRAY_FORMAT (via SetStateVB) +* NV097_SET_VERTEX_DATA_ARRAY_OFFSET (via SetStateVB) +* NV097_DRAW_ARRAYS + +D3DDevice_DrawVerticesUP +* NV097_SET_BEGIN_END +* NV097_SET_VERTEX_DATA_ARRAY_FORMAT (via SetStateUP) +* NV097_INLINE_ARRAY + +D3DDevice_DrawIndexedVertices +* NV097_SET_BEGIN_END +* NV097_SET_VERTEX_DATA_ARRAY_FORMAT (via SetStateVB) +* NV097_SET_VERTEX_DATA_ARRAY_OFFSET (via SetStateVB) +* NV097_ARRAY_ELEMENT16 +* NV097_INLINE_ARRAY + +D3DDevice_DrawIndexedVerticesUP +* NV097_SET_BEGIN_END +* NV097_SET_VERTEX_DATA_ARRAY_FORMAT (via SetStateUP) +* NV097_ARRAY_ELEMENT16 +* NV097_INLINE_ARRAY + + +Xbox also supports two derived Draw API's : +1. D3DDevice_DrawTriPatch +2. D3DDevice_DrawRectPatch +Which get converted into push buffer commands, comparable to the Draw*Vertices* API's. + + +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 calls. (These macro's forward to the vertex-based Xbox Draw API's.) +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 \ No newline at end of file