D3D11On12CreateDevice 함수(d3d11on12.h)

Direct3D 12에서 Direct3D 11 기능을 사용하는 디바이스를 만들고 Direct3D 11 interop에 사용할 기존 Direct3D 12 디바이스를 지정합니다.

구문

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 11 interop에 사용할 기존 Direct3D 12 디바이스를 지정합니다. NULL이 아닐 수 있습니다.

Flags

형식: UINT

D3D11_CREATE_DEVICE_FLAG 하나 이상의 비트 OR 플래그입니다. D3D11CreateDeviceAndSwapChain에서 사용하는 플래그와 동일한 플래그입니다. 사용하도록 설정할 런타임 계층을 지정합니다 . 플래그 는 디바이스 플래그와 호환되어야 하며 NodeMask 는 현재 API에 제공된 NodeMask 의 하위 집합이어야 합니다.

[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

이 메서드는 D3D11CreateDevice에 대해 문서화된 Direct3D 12 반환 코드 중 하나를 반환합니다.

이 메서드는 Flags에서 D3D11_CREATE_DEVICE_DEBUG 지정하고 잘못된 버전의 디버그 계층이 컴퓨터에 설치된 경우 DXGI_ERROR_SDK_COMPONENT_MISSING 반환합니다. 최신 Windows SDK를 설치하여 올바른 버전을 가져옵니다.

설명

함수 서명 PFN_D3D11ON12_CREATE_DEVICE typedef로 제공되므로 정적으로 연결하는 대신 동적 연결 기술(GetProcAddress)을 사용할 수 있습니다.

예제

11On12 디바이스를 통해 Direct2D를 사용하여 Direct3D 12에서 텍스트를 렌더링하려면 렌더링 파이프라인 종속성을 로드합니다.

// 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
헤더 d3d11on12.h
라이브러리 D3D11.lib
DLL D3D11.dll

추가 정보

11on12 함수