Direct3D Administrador de dispositivos

El administrador de dispositivos de Microsoft Direct3D permite que dos o más objetos compartan el mismo dispositivo Microsoft Direct3D 9. Un objeto actúa como propietario del dispositivo Direct3D 9. Para compartir el dispositivo, el propietario del dispositivo crea el administrador de dispositivos direct3D. Otros objetos pueden obtener un puntero al administrador de dispositivos desde el propietario del dispositivo y, a continuación, usar el administrador de dispositivos para obtener un puntero al dispositivo Direct3D. Cualquier objeto que use el dispositivo contiene un bloqueo exclusivo, lo que impide que otros objetos usen el dispositivo al mismo tiempo.

Nota

El Administrador de dispositivos direct3D solo admite dispositivos Direct3D 9. No admite dispositivos DXGI.

 

Para crear el administrador de dispositivos direct3D, llame a DXVA2CreateDirect3DDeviceManager9. Esta función devuelve un puntero a la interfaz IDirect3DDeviceManager9 del administrador de dispositivos, junto con un token de restablecimiento. El token de restablecimiento permite al propietario del dispositivo Direct3D establecer (y restablecer) el dispositivo en el administrador de dispositivos. Para inicializar el administrador de dispositivos, llame a IDirect3DDeviceManager9::ResetDevice. Pase un puntero al dispositivo Direct3D, junto con el token de restablecimiento.

En el código siguiente se muestra cómo crear e inicializar el administrador de dispositivos.

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;
}

El propietario del dispositivo debe proporcionar una manera de que otros objetos obtengan un puntero a la interfaz IDirect3DDeviceManager9 . El mecanismo estándar consiste en implementar la interfaz IMFGetService . El GUID del servicio se MR_VIDEO_ACCELERATION_SERVICE.

Para compartir el dispositivo entre varios objetos, cada objeto (incluido el propietario del dispositivo) debe acceder al dispositivo a través del administrador de dispositivos, como se indica a continuación:

  1. Llame a IDirect3DDeviceManager9::OpenDeviceHandle para obtener un identificador para el dispositivo.
  2. Para usar el dispositivo, llame a IDirect3DDeviceManager9::LockDevice y pase el identificador del dispositivo. El método devuelve un puntero a la interfaz IDirect3DDevice9 . Se puede llamar al método en modo de bloqueo o en modo de no bloqueo, en función del valor del parámetro fBlock .
  3. Cuando haya terminado de usar el dispositivo, llame a IDirect3DDeviceManager9::UnlockDevice. Este método hace que el dispositivo esté disponible para otros objetos.
  4. Antes de salir, llame a IDirect3DDeviceManager9::CloseDeviceHandle para cerrar el identificador del dispositivo.

Debe contener el bloqueo del dispositivo solo mientras usa el dispositivo, ya que mantener el bloqueo del dispositivo impide que otros objetos usen el dispositivo.

El propietario del dispositivo puede cambiar a otro dispositivo en cualquier momento llamando a ResetDevice, normalmente porque se perdió el dispositivo original. La pérdida de dispositivos puede producirse por diversos motivos, incluidos los cambios en la resolución del monitor, las acciones de administración de energía, el bloqueo y el desbloqueo del equipo, etc. Para obtener más información, consulte la documentación de Direct3D.

El método ResetDevice invalida los identificadores de dispositivo que se abrieron anteriormente. Cuando un identificador de dispositivo no es válido, el método LockDevice devuelve DXVA2_E_NEW_VIDEO_DEVICE. Si esto ocurre, cierre el identificador y llame a OpenDeviceHandle de nuevo para obtener un nuevo identificador de dispositivo, como se muestra en el código siguiente.

En el ejemplo siguiente se muestra cómo abrir un identificador de dispositivo y bloquearlo.

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;
}

Aceleración de vídeo de DirectX 2.0