LPD3DHAL_DRAWPRIMITIVES2CB callback function (d3dhal.h)
The D3dDrawPrimitives2 function renders primitives and returns the updated render state.
Syntax
LPD3DHAL_DRAWPRIMITIVES2CB Lpd3dhalDrawprimitives2cb;
DWORD Lpd3dhalDrawprimitives2cb(
LPD3DHAL_DRAWPRIMITIVES2DATA unnamedParam1
)
{...}
Parameters
unnamedParam1
pdp [in]
Points to a D3DHAL_DRAWPRIMITIVES2DATA structure that contains the information required for the driver to render one or more primitives.
Return value
D3dDrawPrimitives2 returns one of the following callback codes:
Remarks
D3dDrawPrimitives2 must be implemented in Microsoft Direct3D drivers.
The driver must do the following:
- Ensure that the context handle specified by the dwhContext member of the D3DHAL_DRAWPRIMITIVES2DATA structure at pdp is valid.
- Check that a flip to the drawing surface associated with the context is not in progress. If the drawing surface is involved in a flip, the driver should set the ddrval member of D3DHAL_DRAWPRIMITIVES2DATA to DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED.
- Determine the location of the first D3DHAL_DP2COMMAND structure by adding the number of bytes in the dwCommandOffset member of D3DHAL_DRAWPRIMITIVES2DATA to the command buffer to which the lpDDCommands member of D3DHAL_DRAWPRIMITIVES2DATA points.
- Determine the location of the first vertex in the vertex buffer. This should only be done if there is data in the vertex buffer; that is, when a D3DDP2OP_Xxx command token is received (except when the token is D3DDP2OP_LINELIST_IMM or D3DDP2OP_TRIANGLEFAN_IMM). These two opcodes indicate that the vertex data is passed immediately in the command stream, rather than in a vertex buffer. So, assuming there is data in the vertex buffer, if the vertex buffer is in user memory, the first vertex is dwVertexOffset bytes into the buffer that lpVertices points to. Otherwise, the driver should apply dwVertexOffset to the memory associated with the DD_SURFACE_LOCAL structure to which lpDDVertex points. dwVertexOffset, lpVertices, and lpDDVertex are members of D3DHAL_DRAWPRIMITIVES2DATA.
- Check the dwVertexType member of D3DHAL_DRAWPRIMITIVES2DATA to ensure that the driver supports the requested FVF. The driver should fail the call if any of the following conditions exist:
- Vertex coordinates are not specified; that is, if D3DFVF_XYZRHW is not set.
- Normals are specified; that is, if D3DFVF_NORMAL is set.
- Any of the reserved D3DFVF_RESERVED x bits are set.
- Process all of the commands in the command buffer sequentially. For each D3DHAL_DP2COMMAND structure, the driver should do the following:
- If the command is D3DDP2OP_RENDERSTATE, process the wStateCount D3DHAL_DP2RENDERSTATE structures that follow in the command buffer, updating the driver state for each render state structure. When the D3DHALDP2_EXECUTEBUFFER flag is set, the driver should also reflect the state change in the array that lpdwRStates points to. wStateCount and lpdwRStates are members of D3DHAL_DRAWPRIMITIVES2DATA.
- If the command is D3DDP2OP_TEXTURESTAGESTATE, process the wStateCount D3DHAL_DP2TEXTURESTAGESTATE structures that follow in the command buffer, updating the driver's texture state associated with the specified texture stage for each texture state structure.
- If the command is D3DDP2OP_VIEWPORTINFO, process the D3DHAL_DP2VIEWPORTINFO structure that follows in the command buffer, updating the viewport information stored in the driver's internal rendering context.
- If the command is D3DDP2OP_WINFO, process the D3DHAL_DP2WINFO structure that follows in the command buffer, updating the w-buffering information stored in the driver's internal rendering context.
- Otherwise, process the D3DHAL_DP2Xxx primitive structures that follow the D3DDP2OP_Xxx primitive rendering command in the command buffer.
- If the command is unknown, call the runtime's D3dParseUnknownCommand callback. The runtime provides this callback to the driver's DdGetDriverInfo callback with the GUID_D3DParseUnknownCommandCallback GUID.
If the driver must fail D3dDrawPrimitives2, it should fill in the dwErrorOffset member of D3DHAL_DRAWPRIMITIVES2DATA with the offset into the command buffer where the first unhandled D3DHAL_DP2COMMAND can be found.
The following comments are not valid for applications that are written using DirectX 8.0 and later interfaces because such applications no longer use the concept of a current vertex buffer (that is, vertex data is no longer passed in via the lpDDVertex member of D3DHAL_DRAWPRIMITIVES2DATA). Therefore, with these applications, the driver's D3dDrawPrimitives2 function should never cause rendering from a vertex buffer to stall even if the buffer is implicit or explicit and there is an outstanding lock on it.
If the driver is used with a DirectX 8.0 runtime, the driver should sometimes stall when rendering from an implicit current vertex buffer to prevent synchronization issues and resulting corruption. In addition, the DirectX 8.0 runtime calls the driver's D3dDrawPrimitives2 function to render from a locked explicit current vertex buffer more often then really necessary so performance is degraded. The following are stalling workarounds for a driver that is used with a DirectX 8.0 runtime:
-
The driver should stall when it transitions between rendering user-memory primitives (identified by D3DHALDP2_USERMEMVERTICES) and rendering from an implicit current vertex buffer only if it does not rename the buffer (does not set D3DHALDP2_SWAPVERTEXBUFFER).
The following example shows when D3dDrawPrimitives2 should stall on an implicit current vertex buffer:
DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Do not stall DrawPrimitives2(Implicit VB, 0); // Stall
The following example shows when D3dDrawPrimitives2 should not stall on an implicit current vertex buffer:
DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Do not stall DrawPrimitives2(Explicit VB, 0); // Do not stall if not locked DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Do not stall whether locked DrawPrimitives2(Implicit VB, 0); // Do not stall whether locked DrawPrimitives2(Implicit VB, 0); // Do not stall whether locked DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Do not stall DrawPrimitives2(Implicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Do not stall because D3DHALDP2_SWAPVERTEXBUFFER is set
If the runtime sets the D3DHALDP2_REQCOMMANDBUFSIZE flag, then the driver is not required to stall. By coincidence, the DirectX 8.0 runtime also sets D3DHALDP2_REQCOMMANDBUFSIZE when it most commonly renders from a locked explicit current vertex buffer. The driver can therefore improve performance by not stalling when it detects D3DHALDP2_REQCOMMANDBUFSIZE while rendering from a locked explicit current vertex buffer.
The following example shows when D3dDrawPrimitives2 should stall on an explicit current vertex buffer:
DrawPrimitives2(Explicit VB, 0); // Stall when locked (happens rarely)
The following example shows when D3dDrawPrimitives2 should not stall on an explicit current vertex buffer:
DrawPrimitives2(Explicit VB, D3DHALDP2_REQCOMMANDBUFSIZE); // Do not stall whether locked DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER); // Do not stall whether locked DrawPrimitives2(Explicit VB, D3DHALDP2_SWAPVERTEXBUFFER | D3DHALDP2_REQCOMMANDBUFSIZE); // Do not stall
Requirements
Requirement Value Target Platform Desktop Header d3dhal.h (include D3dhal.h) See also