LPD3DHAL_DRAWPRIMITIVES2CB回调函数 (d3dhal.h)

D3dDrawPrimitives2 函数呈现基元并返回更新的呈现状态。

语法

LPD3DHAL_DRAWPRIMITIVES2CB Lpd3dhalDrawprimitives2cb;

DWORD Lpd3dhalDrawprimitives2cb(
  LPD3DHAL_DRAWPRIMITIVES2DATA unnamedParam1
)
{...}

参数

unnamedParam1

pdp [in]

指向 D3DHAL_DRAWPRIMITIVES2DATA 结构,该结构包含驱动程序呈现一个或多个基元所需的信息。

返回值

D3dDrawPrimitives2 返回以下回调代码之一:

注解

D3dDrawPrimitives2 必须在 Microsoft Direct3D 驱动程序中实现。

驱动程序必须执行以下操作:

  • 确保 pdp D3DHAL_DRAWPRIMITIVES2DATA 结构的 dwhContext 成员指定的上下文句柄有效。
  • 检查是否正在翻转到与上下文关联的绘图图面。 如果翻转涉及绘图图面,驱动程序应将 D3DHAL_DRAWPRIMITIVES2DATA 的 ddrval 成员设置为DDERR_WASSTILLDRAWING并返回DDHAL_DRIVER_HANDLED。
  • 通过将 D3DHAL_DRAWPRIMITIVES2DATAdwCommandOffset 成员中的字节数添加到D3DHAL_DRAWPRIMITIVES2DATA点的 lpDDCommands 成员的命令缓冲区,确定第一个D3DHAL_DP2COMMAND结构的位置。
  • 确定顶点缓冲区中第一个顶点的位置。 仅当顶点缓冲区中存在数据时,才应执行此操作;也就是说, (收到 D3DDP2OP_Xxx 命令令牌时,D3DDP2OP_LINELIST_IMM或D3DDP2OP_TRIANGLEFAN_IMM) 令牌时除外。 这两个操作码指示顶点数据立即在命令流中传递,而不是在顶点缓冲区中传递。 因此,假设顶点缓冲区中有数据,如果顶点缓冲区位于用户内存中,则第一个顶点是 lpVertices 指向的缓冲区中的 dwVertexOffset 字节。 否则,驱动程序应将 dwVertexOffset 应用于与 lpDDVertex 指向的 DD_SURFACE_LOCAL 结构关联的内存。 dwVertexOffsetlpVerticeslpDDVertex 是 D3DHAL_DRAWPRIMITIVES2DATA 的成员。
  • 检查 D3DHAL_DRAWPRIMITIVES2DATA 的 dwVertexType 成员,确保驱动程序支持请求的 FVF。 如果存在以下任一情况,驱动程序应使调用失败:
    • 未指定顶点坐标;即,如果未设置D3DFVF_XYZRHW。
    • 指定了法线;即,如果设置了D3DFVF_NORMAL。
    • 设置任何保留D3DFVF_RESERVED x 位。
  • 按顺序处理命令缓冲区中的所有命令。 对于每个D3DHAL_DP2COMMAND结构,驱动程序应执行以下操作:
    • 如果命令D3DDP2OP_RENDERSTATE,请在命令缓冲区中处理 wStateCount D3DHAL_DP2RENDERSTATE 结构,更新每个呈现状态结构的驱动程序状态。 设置D3DHALDP2_EXECUTEBUFFER标志时,驱动程序还应反映 lpdwRStates 指向的数组中的状态更改。 wStateCount lpdwRStates 是 D3DHAL_DRAWPRIMITIVES2DATA 的成员。
    • 如果命令D3DDP2OP_TEXTURESTAGESTATE,请在命令缓冲区中处理 wStateCount D3DHAL_DP2TEXTURESTAGESTATE 结构,更新与每个纹理状态结构的指定纹理阶段关联的驱动程序的纹理状态。
    • 如果命令D3DDP2OP_VIEWPORTINFO,则处理命令缓冲区中遵循的 D3DHAL_DP2VIEWPORTINFO 结构,更新存储在驱动程序内部呈现上下文中的视区信息。
    • 如果命令D3DDP2OP_WINFO,则处理命令缓冲区中遵循 的D3DHAL_DP2WINFO 结构,更新存储在驱动程序的内部呈现上下文中的 w 缓冲信息。
    • 否则,请在命令缓冲区中处理遵循 D3DDP2OP_Xxx 基元呈现命令的 D3DHAL_DP2 Xxx 基元结构。
    • 如果命令未知,请调用运行时的 D3dParseUnknownCommand 回调。 运行时通过 GUID 向驱动程序的 DdGetDriverInfo 回调提供此回调GUID_D3DParseUnknownCommandCallback。
驱动程序不需要探测存储命令和顶点缓冲区的内存的可读性。 但是,驱动程序必须保持在D3DHAL_DRAWPRIMITIVES2DATA 的 dwCommandLengthdwVertexLength 成员指定的边界内。

如果驱动程序必须失败 D3dDrawPrimitives2,它应使用偏移量填充 D3DHAL_DRAWPRIMITIVES2DATA 的 dwErrorOffset 成员,在该缓冲区中可以找到第一个未处理的D3DHAL_DP2COMMAND。

注意 以下注释仅适用于使用 Microsoft DirectX 7.0 接口编写的并通过 DirectX 8.0 和 DirectX 8.1 运行时与驱动程序通信的应用程序。

以下注释对于使用 DirectX 8.0 及更高版本接口编写的应用程序无效,因为此类应用程序不再使用当前顶点缓冲区的概念 (即不再通过 D3DHAL_DRAWPRIMITIVES2DATA) 的 lpDDVertex 成员传入顶点数据。 因此,对于这些应用程序,驱动程序的 D3dDrawPrimitives2 函数不应导致顶点缓冲区的呈现停止,即使缓冲区是隐式或显式的,并且存在未完成的锁定。

 
如果驱动程序与 DirectX 8.1 或更高版本的运行时一起使用,则驱动程序的 D3dDrawPrimitives2 函数不应导致当前顶点缓冲区的呈现 (通过 lpDDVertex 传递) 停止(如果缓冲区是隐式的)。 如果缓冲区是显式的,并且存在未完成的锁,则驱动程序应停止在其 D3dDrawPrimitives2 函数末尾,如果它不重命名缓冲区 (未设置D3DHALDP2_SWAPVERTEXBUFFER) 。 如果驱动程序重命名缓冲区,则驱动程序不会停止。 DirectX 8.1 及更高版本的运行时调用驱动程序的 D3dDrawPrimitives2 函数,以便仅在必要时从锁定的显式顶点缓冲区呈现,因此性能很少受到影响。 隐式顶点缓冲区由驱动程序的 CreateD3DBuffer 回调创建,仅设置了DDSCAPS_EXECUTEBUFFER标志。 显式顶点缓冲区由驱动程序的 CreateD3DBuffer 回调创建,并设置了DDSCAPS_EXECUTEBUFFER和DDSCAPS2_VERTEXBUFFER标志。 显式顶点缓冲区由驱动程序的 LockD3DBuffer 回调锁定。

如果驱动程序与 DirectX 8.0 运行时一起使用,则从隐式当前顶点缓冲区呈现时,驱动程序有时会停止,以防止同步问题和导致损坏。 此外,DirectX 8.0 运行时调用驱动程序的 D3dDrawPrimitives2 函数,以更频繁地从锁定的显式当前顶点缓冲区呈现,这样性能就会降低。 以下是与 DirectX 8.0 运行时一起使用的驱动程序的停止解决方法:

  • 驱动程序在呈现 (D3DHALDP2_USERMEMVERTICES) 标识的用户内存基元与从隐式当前顶点缓冲区呈现之间转换时应停止,仅当它不重命名缓冲区 (未设置D3DHALDP2_SWAPVERTEXBUFFER) 。

    以下示例显示 D3dDrawPrimitives2 何时应在隐式当前顶点缓冲区上停止:

    DrawPrimitives2(p*, D3DHALDP2_USERMEMVERTICES); // Do not stall
    DrawPrimitives2(Implicit VB, 0); // Stall 
    

    以下示例显示 D3dDrawPrimitives2 何时不应在隐式当前顶点缓冲区上停止:

    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
    

    如果运行时设置D3DHALDP2_REQCOMMANDBUFSIZE标志,则驱动程序不需要停止。 巧合的是,当 DirectX 8.0 运行时最常从锁定的显式当前顶点缓冲区呈现时,还设置D3DHALDP2_REQCOMMANDBUFSIZE。 因此,驱动程序可以通过在从锁定的显式当前顶点缓冲区进行呈现时检测到D3DHALDP2_REQCOMMANDBUFSIZE时不停止来提高性能。

    以下示例显示 D3dDrawPrimitives2 何时应在显式当前顶点缓冲区上停止:

    DrawPrimitives2(Explicit VB, 0); // Stall when locked (happens rarely)
    

    以下示例显示 D3dDrawPrimitives2 何时不应在显式当前顶点缓冲区上停止:

    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
    

    要求

    要求
    目标平台 桌面
    标头 d3dhal.h (包括 D3dhal.h)

    另请参阅

    D3DHAL_DP2INDEXEDLINELIST

    D3DHAL_DP2INDEXEDLINESTRIP

    D3DHAL_DP2INDEXEDTRIANGLEFAN

    D3DHAL_DP2INDEXEDTRIANGLELIST

    D3DHAL_DP2INDEXEDTRIANGLESTRIP

    D3DHAL_DP2LINELIST

    D3DHAL_DP2LINESTRIP

    D3DHAL_DP2POINTS

    D3DHAL_DP2TRIANGLEFAN

    D3DHAL_DP2TRIANGLELIST

    D3DHAL_DP2TRIANGLESTRIP

    FVF