Direct3D設備管理器(Direct3D device manager)。本站提示廣大學習愛好者:(Direct3D設備管理器(Direct3D device manager))文章只能為提供參考,不一定能成為您想要的結果。以下是Direct3D設備管理器(Direct3D device manager)正文
這幾天在做dxva2硬件減速,找不到什麼材料,翻譯了一下微軟的兩篇相關文檔。並預備記載一下用ffmpeg完成dxva2,將在第三篇寫到。這是第一篇,英文舊址:https://msdn.microsoft.com/en-us/library/aa965267(v=vs.85).aspx
Direct3D設備管理器(Direct3D device manager)允許兩個或多個對象(object)共用同一個Direct3D 9 設備(device)。其中一個對象作為Direct3D 9 設備的擁有者。要能共享設備,擁有設備的對象(the owner)要創立Direct3D設備管理器,其他對象可以取得一個指向這個設備管理器的指針,然後經過設備管理器取得一個指向Direct3D 設備的指針。每個運用這個設備的的對象都有一個互斥鎖,避免與其他設備同時運用這個設備。(我的正文:即一次只能有一個對象運用設備,不能兩個對象同時運用同一個設備。這就是鎖的互斥功用)
留意:Direct3D 設備管理器只支持Direct3D 9 設備。不支持DXGI 設備.
要創立Direct3D 設備管理器, 需求調用DXVA2CreateDirect3DDeviceManager9函數。這個函數前往一個指向這個創立的設備管理器的IDirect3DDeviceManager9接口的指針,以及一個重置標志(reset token)。重置標志使得運用Direct3D 設備的對象可以經過這個設備管理器設置(或重置)設備。調用IDirect3DDeviceManager9::ResetDevice函數以初始化設備管理器,傳入Direct3D設備的指針和重置標志(這句翻譯的不好,就是把這兩個參數傳給函數來初始化設備,看上面的代碼就會明白)。
以下代碼展現如何創立和初始化設備管理器。
HRESULT CreateD3DDeviceManager( IDirect3DDevice9 *pDevice, UINT *pReset, IDirect3DDeviceManager9 **ppManager ) { UINT resetToken = 0; IDirect3DDeviceManager9 *pD3DManager = NULL; HRESULT hr = DXVA2CreateDirect3DDeviceManager9(&resetToken, &pD3DManager); if (FAILED(hr)) { goto done; } hr = pD3DManager->ResetDevice(pDevice, resetToken); if (FAILED(hr)) { goto done; } *ppManager = pD3DManager; (*ppManager)->AddRef(); *pReset = resetToken; done: SafeRelease(&pD3DManager); return hr; }
擁有設備的對象必需給其他對象提供一種取得IDirect3DDeviceManager9接口指針的方式。規范機制是完成IMFGetService接口。改服務的GUID是MR_VIDEO_ACCELERATION_SERVICE。
要在多個對象中共用設備,每個對象(包括擁有設備的對象)必需經過設備管理器去取得設備,如下:
(1)調用IDirect3DDeviceManager9::OpenDeviceHandle函數獲取設備句柄。
(2)要想運用設備,調用IDirect3DDeviceManager9::LockDevice並傳入設備句柄。該辦法前往一個指向IDirect3DDevice9 接口的指針。該辦法能以阻塞和非阻塞兩種形式調用,取決於fBlock參數的值。
(3)用完設備後,應調用IDirect3DDeviceManager9::UnlockDevice。這樣其他對象就可以運用這個設備了。
(4)加入前,調用IDirect3DDeviceManager9::CloseDeviceHandle封閉設備句柄。
你該當只在運用設備的時分才設置設備鎖(the device lock),由於設置設備鎖會阻止其他對象運用設備。(我的正文:這一點假如有疑惑,百度一下互斥鎖的定義就會明白了,就是一個避免多個對象同時運用同一個設備招致混亂的互斥機制)
擁有設備的對象(the ownder)可以經過調用ResetDevice函數在恣意時分切換到其他設備,特別地,在原始設備喪失的狀況下。設備喪失可以由各種緣由形成,包括改動顯示器分辨率,電源管理操作,鎖定或解鎖電腦,等等。更多狀況,請轉Direct3D文檔。
ResetDevice函數會把任何之前翻開的設備句柄置為有效。設備有效後,LockDevice函數前往DXVA2_E_NEW_VIDEO_DEVICE。假如發作這種狀況,封閉句柄並再次調用OpenDeviceHandle以重新取得新的設備句柄,如以下代碼鎖展現的。
上面的例子展現了如何翻開設備句柄和鎖設備(lock the device)。
HRESULT LockDevice( IDirect3DDeviceManager9 *pDeviceManager, BOOL fBlock, IDirect3DDevice9 **ppDevice, // Receives a pointer to the device. HANDLE *pHandle // Receives a device handle. ) { *pHandle = NULL; *ppDevice = NULL; HANDLE hDevice = 0; HRESULT hr = pDeviceManager->OpenDeviceHandle(&hDevice); if (SUCCEEDED(hr)) { hr = pDeviceManager->LockDevice(hDevice, ppDevice, fBlock); } if (hr == DXVA2_E_NEW_VIDEO_DEVICE) { // Invalid device handle. Try to open a new device handle. hr = pDeviceManager->CloseDeviceHandle(hDevice); if (SUCCEEDED(hr)) { hr = pDeviceManager->OpenDeviceHandle(&hDevice); } // Try to lock the device again. if (SUCCEEDED(hr)) { hr = pDeviceManager->LockDevice(hDevice, ppDevice, TRUE); } } if (SUCCEEDED(hr)) { *pHandle = hDevice; } return hr; }