Поделиться через


Функция D3D11On12CreateDevice (d3d11on12.h)

Создает устройство, которое использует функции Direct3D 11 в Direct3D 12, указывая существующее устройство Direct3D 12 для использования для взаимодействия с Direct3D 11.

Синтаксис

HRESULT D3D11On12CreateDevice(
  [in]            IUnknown                *pDevice,
                  UINT                    Flags,
  [in, optional]  const D3D_FEATURE_LEVEL *pFeatureLevels,
                  UINT                    FeatureLevels,
  [in, optional]  IUnknown                * const *ppCommandQueues,
                  UINT                    NumQueues,
                  UINT                    NodeMask,
  [out, optional] ID3D11Device            **ppDevice,
  [out, optional] ID3D11DeviceContext     **ppImmediateContext,
  [out, optional] D3D_FEATURE_LEVEL       *pChosenFeatureLevel
);

Параметры

[in] pDevice

Тип: IUnknown*

Указывает существующее устройство Direct3D 12 для взаимодействия с Direct3D 11. Может не иметь значение NULL.

Flags

Тип: UINT

Один или несколько побитовых флагов OR из D3D11_CREATE_DEVICE_FLAG. Это те же флаги, что и в D3D11CreateDeviceAndSwapChain. Указывает, какие слои среды выполнения следует включить. Флаги должны быть совместимы с флагами устройств, а его NodeMask должно быть подмножеством NodeMask , предоставляемого для текущего API.

[in, optional] pFeatureLevels

Тип: const D3D_FEATURE_LEVEL*

Массив из любого из следующих значений:

  • D3D_FEATURE_LEVEL_12_1
  • D3D_FEATURE_LEVEL_12_0
  • D3D_FEATURE_LEVEL_11_1
  • D3D_FEATURE_LEVEL_11_0
  • D3D_FEATURE_LEVEL_10_1
  • D3D_FEATURE_LEVEL_10_0
  • D3D_FEATURE_LEVEL_9_3
  • D3D_FEATURE_LEVEL_9_2
  • D3D_FEATURE_LEVEL_9_1

Первый уровень компонентов, который меньше или равен уровню компонентов устройства Direct3D 12, будет использоваться для выполнения проверки Direct3D 11. Создание завершится ошибкой, если не указаны допустимые уровни компонентов. Если задано значение NULL, по умолчанию будет задан уровень компонентов устройства Direct3D 12.

FeatureLevels

Тип: UINT

Размер (т. е. количество элементов в) массива pFeatureLevels .

[in, optional] ppCommandQueues

Тип: IUnknown* const *

Массив уникальных очередей для использования D3D11On12. Очереди должны иметь тип очереди 3D-команд.

NumQueues

Тип: UINT

Размер (то есть количество элементов в) массива ppCommandQueues .

NodeMask

Тип: UINT

Какой узел устройства Direct3D 12 следует использовать. Можно задать только 1 бит.

[out, optional] ppDevice

Тип: ID3D11Device**

Указатель на возвращенный ID3D11Device. Может иметь значение "NULL".

[out, optional] ppImmediateContext

Тип: ID3D11DeviceContext**

Указатель на возвращенный ID3D11DeviceContext. Может иметь значение "NULL".

[out, optional] pChosenFeatureLevel

Тип: D3D_FEATURE_LEVEL*

Указатель на возвращаемый уровень компонентов. Может иметь значение "NULL".

Возвращаемое значение

Тип: HRESULT

Этот метод возвращает один из кодов возврата Direct3D 12 , которые задокументированы для D3D11CreateDevice.

Этот метод возвращает DXGI_ERROR_SDK_COMPONENT_MISSING , если вы указали D3D11_CREATE_DEVICE_DEBUG в разделе Флаги и на компьютере установлена неправильная версия слоя отладки . Установите последнюю версию windows SDK, чтобы получить правильную версию.

Комментарии

Сигнатура функции PFN_D3D11ON12_CREATE_DEVICE предоставляется в виде определения типа, поэтому вместо статического связывания можно использовать методы динамического связывания (GetProcAddress).

Примеры

Для отрисовки текста через Direct3D 12 с помощью Direct2D через устройство 11On12 загрузите зависимости конвейера отрисовки.

// Load the rendering pipeline dependencies.
void D3D1211on12::LoadPipeline()
{
    UINT d3d11DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    D2D1_FACTORY_OPTIONS d2dFactoryOptions = {};
#if defined(_DEBUG)
    // Enable the D2D debug layer.
    d2dFactoryOptions.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;

    // Enable the Direct3D 11 debug layer.
    d3d11DeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    
    // Enable the Direct3D 12 debug layer.
    {
        ComPtr<ID3D12Debug> debugController;
        if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
        {
            debugController->EnableDebugLayer();
        }
    }
#endif

    ComPtr<IDXGIFactory4> factory;
    ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));

    if (m_useWarpDevice)
    {
        ComPtr<IDXGIAdapter> warpAdapter;
        ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

        ThrowIfFailed(D3D12CreateDevice(
            warpAdapter.Get(),
            D3D_FEATURE_LEVEL_11_0,
            IID_PPV_ARGS(&m_d3d12Device)
            ));
    }
    else
    {
        ComPtr<IDXGIAdapter1> hardwareAdapter;
        GetHardwareAdapter(factory.Get(), &hardwareAdapter);

        ThrowIfFailed(D3D12CreateDevice(
            hardwareAdapter.Get(),
            D3D_FEATURE_LEVEL_11_0,
            IID_PPV_ARGS(&m_d3d12Device)
            ));
    }

    // Describe and create the command queue.
    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
    queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

    ThrowIfFailed(m_d3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));

    // Describe the swap chain.
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    swapChainDesc.BufferCount = FrameCount;
    swapChainDesc.BufferDesc.Width = m_width;
    swapChainDesc.BufferDesc.Height = m_height;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.OutputWindow = Win32Application::GetHwnd();
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.Windowed = TRUE;

    ComPtr<IDXGISwapChain> swapChain;
    ThrowIfFailed(factory->CreateSwapChain(
        m_commandQueue.Get(),        // Swap chain needs the queue so that it can force a flush on it.
        &swapChainDesc,
        &swapChain
        ));

    ThrowIfFailed(swapChain.As(&m_swapChain));

    // This sample does not support fullscreen transitions.
    ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER));

    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

    // Create an 11 device wrapped around the 12 device and share
    // 12's command queue.
    ComPtr<ID3D11Device> d3d11Device;
    ThrowIfFailed(D3D11On12CreateDevice(
        m_d3d12Device.Get(),
        d3d11DeviceFlags,
        nullptr,
        0,
        reinterpret_cast<IUnknown**>(m_commandQueue.GetAddressOf()),
        1,
        0,
        &d3d11Device,
        &m_d3d11DeviceContext,
        nullptr
        ));

    // Query the 11On12 device from the 11 device.
    ThrowIfFailed(d3d11Device.As(&m_d3d11On12Device));

    // Create D2D/DWrite components.
    {
        D2D1_DEVICE_CONTEXT_OPTIONS deviceOptions = D2D1_DEVICE_CONTEXT_OPTIONS_NONE;
        ThrowIfFailed(D2D1CreateFactory(
            D2D1_FACTORY_TYPE_SINGLE_THREADED,
            __uuidof(ID2D1Factory3),
            &d2dFactoryOptions,
            &m_d2dFactory));
        ComPtr<IDXGIDevice> dxgiDevice;
        ThrowIfFailed(m_d3d11On12Device.As(&dxgiDevice));
        ThrowIfFailed(m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice));
        ThrowIfFailed(m_d2dDevice->CreateDeviceContext(deviceOptions, &m_d2dDeviceContext));
        ThrowIfFailed(DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(IDWriteFactory),
            &m_dWriteFactory));
    }

    // Query the desktop's dpi settings, which will be used to create
    // D2D's render targets.
    float dpi = GetDpiForWindow(Win32Application::GetHwnd());
    D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(
        D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
        D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
        dpi,
        dpi
        );

    // Create descriptor heaps.
    {
        // Describe and create a render target view (RTV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
        rtvHeapDesc.NumDescriptors = FrameCount;
        rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
        rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        ThrowIfFailed(m_d3d12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

        m_rtvDescriptorSize = 
            m_d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
    }

    // Create frame resources.
    {
        CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());

        // Create a RTV, D2D render target, and a command allocator for each frame.
        for (UINT n = 0; n < FrameCount; n++)
        {
            ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
            m_d3d12Device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);

            // Create a wrapped 11On12 resource of this back buffer. Since we are 
            // rendering all Direct3D 12 content first and then all D2D content, we specify 
            // the In resource state as RENDER_TARGET - because Direct3D 12 will have last 
            // used it in this state - and the Out resource state as PRESENT. When 
            // ReleaseWrappedResources() is called on the 11On12 device, the resource 
            // will be transitioned to the PRESENT state.
            D3D11_RESOURCE_FLAGS d3d11Flags = { D3D11_BIND_RENDER_TARGET };
            ThrowIfFailed(m_d3d11On12Device->CreateWrappedResource(
                m_renderTargets[n].Get(),
                &d3d11Flags,
                D3D12_RESOURCE_STATE_RENDER_TARGET,
                D3D12_RESOURCE_STATE_PRESENT,
                IID_PPV_ARGS(&m_wrappedBackBuffers[n])
                ));

            // Create a render target for D2D to draw directly to this back buffer.
            ComPtr<IDXGISurface> surface;
            ThrowIfFailed(m_wrappedBackBuffers[n].As(&surface));
            ThrowIfFailed(m_d2dDeviceContext->CreateBitmapFromDxgiSurface(
                surface.Get(),
                &bitmapProperties,
                &m_d2dRenderTargets[n]
                ));

            rtvHandle.Offset(1, m_rtvDescriptorSize);

            ThrowIfFailed(m_d3d12Device->CreateCommandAllocator(
                D3D12_COMMAND_LIST_TYPE_DIRECT,
                IID_PPV_ARGS(&m_commandAllocators[n])));
        }
    }
}

См. примечания о примере кода в справочном материале по Direct3D 12.

Требования

   
Целевая платформа Windows
Header d3d11on12.h
Библиотека D3D11.lib
DLL D3D11.dll

См. также раздел

Функции 11on12