程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> Direct3D設備管理器(Direct3D device manager)

Direct3D設備管理器(Direct3D device manager)

編輯:關於C++

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;
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved