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_DRAWPRIMITIVES2DATA dwCommandOffset 成員中的位元元組數目新增至D3DHAL_DRAWPRIMITIVES2DATA點之 lpDDCommands 成員所在的命令緩衝區,以判斷第一個D3DHAL_DP2COMMAND結構的位置。
  • 判斷頂點緩衝區中第一個頂點的位置。 只有在頂點緩衝區中有數據時,才應該這麼做;也就是說, (收到D3DDP2OP_Xxx 命令令牌時,除非令牌是D3DDP2OP_LINELIST_IMM或D3DDP2OP_TRIANGLEFAN_IMM) 。 這兩個 opcode 表示頂點數據會立即在命令數據流中傳遞,而不是在頂點緩衝區中傳遞。 因此,假設頂點緩衝區中有數據,如果頂點緩衝區位於用戶記憶體中,則第一個頂點是 dwVertexOffset 位元組到 lpVertices 指向的緩衝區。 否則,驅動程式應該將 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_D3DParseUnknownCommandCallback GUID,將此回呼提供給驅動程式的 DdGetDriverInfo 回呼。
驅動程式不需要探查命令和頂點緩衝區儲存所在記憶體的可讀性。 不過,驅動程式必須保留在 dwCommandLengthdwVertexLength 成員所指定的界限內D3DHAL_DRAWPRIMITIVES2DATA。

如果驅動程式必須失敗 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_SWAPVERTEXBUFFER) 时,驅動程式才會在轉譯用戶記憶體基本類型 (D3DHALDP2_USERMEMVERTICES) 和从隐含目前顶点缓冲区转译时停止。

    下列範例顯示 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