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 |