共用方式為


Direct3D 10 的變更

本節僅適用于 Windows 7 和更新版本,以及 Windows Server 2008 R2 和更新版本的 Windows 作業系統。

下列各節說明 Direct3D 11 如何從 Direct3D 10 變更。

Kernel-Mode服務的驅動程式回呼函式

當執行時間呼叫使用者模式顯示驅動程式的CreateDevice (D3D10) 時,Direct3D 第 11 版執行時間在D3DDDI_DEVICECALLBACKS結構中提供的裝置特定回呼函式會將驅動程式與核心控制碼和核心函式簽章隔離。 Direct3D 第 11 版執行時間會變更回呼語意,因此,回呼函式的實作可支援自由執行緒模式的作業,而先前的 Direct3D 版本執行時間則不支援自由執行緒模式的作業。 在驅動程式指出它支援自由執行緒模式 (D3D11DDICAPS_FREETHREADED) 之後,就會套用免費執行緒模式作業的規則;否則,會套用先前高度限制的規則。 如需驅動程式如何指出支援自由執行緒模式的資訊,請參閱 執行緒和命令清單。 Direct3D 第 11 版仍然有下列限制:

  • 一次只能對 HCONTEXT 使用單一線程。 目前使用 HCONTEXT 的現有回呼函式為 pfnPresentCbpfnRenderCbpfnEscapeCbpfnDestroyCoNtextCbpfnWaitForSynchronizationObjectCbpfnSignalSynchronizationObjectCb。 因此,如果多個執行緒呼叫這些回呼函式並使用相同的 HCONTEXT,驅動程式必須同步處理回呼函式的呼叫。 滿足這項需求相當自然,因為這些回呼函式可能只從操作立即內容的執行緒呼叫。

  • 驅動程式只有在呼叫下列驅動程式函式時,才能使用呼叫這些驅動程式函式的相同執行緒來呼叫下列回呼函式:

  • pfnDeallocateCb回呼函式值得特別提及,因為驅動程式在驅動程式從其 DestroyResource (D3D10) 函式傳回之前,不需要呼叫pfnDeallocateCb。 因為 DestroyResource (D3D10) 是一個自由執行緒函式,所以驅動程式必須延遲物件的解構,直到驅動程式有效率地確保沒有任何現有的立即內容參考維持 (亦即,驅動程式必須在pfnDeallocateCb) 之前呼叫pfnRenderCb。 此限制甚至適用于共用資源或任何其他使用 HRESOURCE 的回呼函式,以使用 pfnAllocateCb補充 HRESOURCE 使用量。 不過,這項限制不適用於主要複本。 如需主要例外狀況的詳細資訊,請參閱 主要例外狀況。 由於某些應用程式可能需要同步解構的外觀,因此驅動程式必須在呼叫 Flush (D3D10) 函式期間,針對先前終結的任何共用資源呼叫pfnDeallocateCb。 驅動程式也必須清除任何先前終結的物件, (在呼叫其 Flush (D3D10) 函式時,不會停止管線) 的物件;驅動程式必須這樣做,以確保執行時間呼叫 Flush (D3D10) 為官方機制,以清除可能需要這類機制的少數應用程式清除延後終結的物件。 如需此機制的詳細資訊,請參閱 延後解構和排清 (D3D10) 。 驅動程式也必須確保在清除期間,驅動程式的 DestroyDevice (D3D10) 函式傳回之前,會完全終結已延遲解構的任何物件。

淘汰允許修改 Free-Threaded DIS 的能力

針對 Direct3D 第 11 版,顯示裝置和即時內容的 API 層級概念仍會與顯示裝置的舊版概念在 DDI 層級組合在一起。 這種顯示裝置和即時內容統合可將與舊版 DIS (的相容性最大化,例如 Direct3D 10 DDI 版) ,並在透過多個版本的 DIS 支援多個 API 版本時減少驅動程式變換。 不過,這種顯示裝置和立即內容統合會導致更令人困惑的 DDI,因為執行緒網域並不明確。 相反地,若要瞭解多個介面的執行緒需求,以及這些介面內的函式,驅動程式開發人員必須參考檔。

Direct3D 第 11 版 API 的主要功能是允許多個執行緒同時進入建立和終結函式。 這類功能與允許驅動程式交換用於建立和終結的函式資料表指標不相容,因為D3D10DDI_DEVICEFUNCS和允許D3D10_1DDI_DEVICEFUNCS所指定函式的 Direct3D 版本 10 DDI 語意。 因此,在驅動程式傳回 creates (CreateDevice (D3D10) ) 之後,驅動程式不應該在驅動程式在 Direct3D 版本 11 DDI 下執行時修改這些特定函式指標來嘗試變更行為,而驅動程式則支援 DDI 執行緒。 這項限制適用于以 pfnCreatepfnOpenpfnDestroypfnCalcPrivatepfnCheck開頭的所有裝置功能。 裝置函式的其餘部分都與立即內容有強烈關聯。 因為單一線程一次會操作即時內容,所以定義完善,以繼續允許驅動程式熱交換立即內容函式資料表專案。

pfnRenderCb Vss pfnPerformAmortizedProcessingCb

Direct3D 第 10 版 API 函式會連結 Direct3D 執行時間的 pfnRenderCb 核心回呼函式來執行分攤處理 (也就是說,驅動程式會針對每個 API 函數呼叫執行分攤作業) 。 API 通常會使用此機會來修剪高浮水印,並排清其延後的物件解構佇列,以及其他專案。

為了讓核心回呼函式盡可能為驅動程式提供自由執行緒,當驅動程式支援 Direct3D 第 11 版 DDI 時,Direct3D API 不再使用 pfnRenderCb 。 因此,支援 Direct3D 11 DDI 版的驅動程式必須從驅動程式 DDI 函式的相同執行緒手動呼叫 pfnPerformAmortizedProcessingCb 核心回呼函式,該執行緒會在驅動程式在立即內容上提交命令緩衝區 (或類似的頻率) 。 由於作業應該修剪高水位線,因此在使用狀態重新整理 DDI 回呼函式時,在驅動程式產生命令緩衝區前置詞之前,最好這麼做。

此外,驅動程式應該注意 API 分攤問題,並嘗試平衡其使用 pfnPerformAmortizedProcessingCb 核心回呼函式的頻率。 在一個極端狀況下,驅動程式可能會導致過度處理。 例如,如果驅動程式一律呼叫 pfnPerformAmortizedProcessingCb 兩次, (回頭) ,可能是因為多引擎使用,驅動程式只會呼叫 pfnPerformAmortizedProcessingCb 一次。 在其他極端的情況下,如果驅動程式從未呼叫 pfnPerformAmortizedProcessingCb,驅動程式可能無法允許 Direct3D API 對整個框架執行任何工作,可能是因為替代的畫面轉譯設計所致。 驅動程式不需要比自然呼叫 pfnPerformAmortizedProcessingCb 更頻繁, (例如,如果驅動程式未在 1 毫秒的時間範圍內呼叫 pfnPerformAmortizedProcessingCb ,則必須花時間幫浦 API) 。 驅動程式只需要判斷哪一個現有的 pfnRenderCb 呼叫應該伴隨 pfnPerformAmortizedProcessingCb ,而且自然地符合作業的執行緒語意。

對於支援命令清單的驅動程式,每當這些驅動程式用盡會議室時,這些驅動程式也必須從延遲的內容呼叫 pfnPerformAmortizedProcessingCb , (與每個即時內容排清) 類似的頻率。 Direct3D 11 版執行時間至少預期會在這類作業期間修剪其高浮水印。 由於 Direct3D 第 11 版已放寬 與 pfnRenderCb 相關的執行緒語意,因此必須解決並行問題,才能讓 Direct3D 第 11 版繼續攔截 pfnRenderCb,而不受限制。

新的 DDI 錯誤碼

系統會建立D3DDDIERR_APPLICATIONERROR錯誤碼,以允許驅動程式參與 Direct3D 11 版 API 沒有的驗證。 先前,如果驅動程式傳回E_INVALIDARG錯誤碼,會導致 API 引發例外狀況。 偵錯層的存在會導致偵錯輸出,並指出驅動程式已傳回內部錯誤。 偵錯輸出會建議開發人員驅動程式有 Bug。 如果驅動程式傳回D3DDDIERR_APPLICATIONERROR,偵錯層會改為判斷應用程式發生錯誤。

回溯要求Free-Threaded CalcPrivate DIS

Direct3D 第 11 版回溯要求在 Direct3D 10 DDI 函式上以 pfnCalcPrivate 開頭的驅動程式函式必須具有可用執行緒。 此回溯需求符合 Direct3D 第 11 版 DDI 的行為,一律需要 pfnCalcPrivate*pfnCalcDeferredCoNtextHandleSize 函式,即使驅動程式指出它不支援 DDI 執行緒。 如需此回溯需求的詳細資訊,請參閱回溯 要求Free-Threaded CalcPrivate DIS

延遲解構和排清 D3D10

由於所有終結函式現在都是自由執行緒,因此 Direct3D 執行時間無法在解構期間排清命令緩衝區。 因此,終結函式必須延遲物件的實際解構,直到驅動程式可以確保操作立即內容的執行緒不再相依于該物件才能存留。 每個離散的即時內容方法都無法有效地使用同步處理來解決此解構問題;因此,只有在驅動程式排清命令緩衝區時,驅動程式才應該使用同步處理。 當 Direct3D 執行時間必須處理類似的問題時,也會使用相同的設計。

由於延遲解構的出現,Direct3D 執行時間提倡者無法容許延遲解構因應措施的應用程式會改用明確的機制。 因此,驅動程式必須在呼叫 Flush (D3D10) 函式時處理其延後解構佇列 (,即使命令緩衝區是空的) ,以確保這些機制實際運作。

需要同步解構形式的應用程式必須使用下列其中一種模式,視其所需的解構程度而定:

  • 在應用程式確保釋放該物件的所有相依性 (也就是命令清單、檢視、中介軟體等) 之後,應用程式會使用下列模式:

    Object::Release(); // Final release
    ImmediateContext::ClearState(); // Remove all ImmediateContext references as well.
    ImmediateContext::Flush(); // Destroy all objects as quickly as possible.
    
  • 下列模式是較繁重的解構:

    Object::Release(); // Final release
    ImmediateContext::ClearState(); // Remove all ImmediateContext references as well.
    ImmediateContext::Flush();
    ImmediateContext::End( EventQuery );
    while( S_FALSE == ImmediateContext::GetData( EventQuery ) ) ;
    ImmediateContext::Flush(); // Destroy all objects, completely.
    

主要例外狀況

主要是執行時間在呼叫驅動程式的 CreateResource (D3D11) 函式時建立的資源。 執行時間會將D3D11DDIARG_CREATERESOURCE結構的pPrimaryDesc成員設定為DXGI_DDI_PRIMARY_DESC結構的有效指標,以建立主要複本。 主要複本對於從 Direct3D 10 到 Direct3D 11 的上述變更有下列值得注意的例外狀況:

  • 驅動程式的 CreateResource (D3D11) DestroyResource (D3D10) 主要函式都不是自由執行緒,而且它們會共用立即的內容執行緒網域。 並行仍可存在於開頭為 pfnCreatepfnDestroy的函式,其中包括 CreateResource (D3D11) 和 DestroyResource (D3D10) 。 不過,主要複本的 CreateResource (D3D11) DestroyResource (D3D10) 無法存在平行存取。 例如,驅動程式可以偵測到其 CreateResource (D3D11) 或 DestroyResource (D3D10) 函式的呼叫適用于主要複本,進而判斷它可以在函式呼叫期間安全地使用或觸控立即內容記憶體。

  • Direct3D 執行時間無法延後主要解構,而且驅動程式必須在呼叫驅動程式的 DestroyResource (D3D10) 函式內適當地呼叫pfnDlocateCb函式。