DXGI 개요

Microsoft DXGI(DirectX Graphics Infrastructure)는 그래픽의 일부가 다른 부분보다 더 느리게 진화한다는 것을 인식합니다. DXGI의 주요 목표는 DirectX 그래픽 런타임과 독립적일 수 있는 하위 수준 작업을 관리하는 것입니다. DXGI는 향후 그래픽 구성 요소에 대한 공통 프레임워크를 제공합니다. DXGI를 활용하는 첫 번째 구성 요소는 Microsoft Direct3D 10입니다.

이전 버전의 Direct3D에서는 하드웨어 디바이스 열거, 렌더링된 프레임을 출력에 표시, 감마 제어 및 전체 화면 전환 관리와 같은 하위 수준 작업이 Direct3D 런타임에 포함되었습니다. 이러한 작업은 이제 DXGI에서 구현됩니다.

DXGI의 목적은 다음 다이어그램과 같이 커널 모드 드라이버 및 시스템 하드웨어와 통신하는 것입니다.

애플리케이션, dxgi, 드라이버 및 하드웨어 간의 통신 다이어그램

애플리케이션은 DXGI에 직접 액세스하거나 DXGI와의 통신을 처리하는 D3D11_1.h, D3D11.h, D3D10_1.h 또는 D3D10.h에서 Direct3D API를 호출할 수 있습니다. 애플리케이션이 디바이스를 열거하거나 데이터가 출력에 표시되는 방식을 제어해야 하는 경우 DXGI로 직접 작업할 수 있습니다.

이 항목에는 다음과 같은 섹션이 포함되어 있습니다.

Direct3D 11 하드웨어에서 지원되는 형식을 확인하려면 다음을 수행합니다.

어댑터 열거

어댑터는 컴퓨터의 하드웨어 및 소프트웨어 기능을 추상화한 것입니다. 일반적으로 컴퓨터에는 많은 어댑터가 있습니다. 일부 디바이스는 하드웨어(예: 비디오 카드)에서 구현되며 일부는 소프트웨어(예: Direct3D 참조 래스터라이저)에서 구현됩니다. 어댑터는 그래픽 애플리케이션에서 사용하는 기능을 구현합니다. 다음 다이어그램은 단일 컴퓨터, 2개의 어댑터(비디오 카드) 및 3개의 출력 모니터가 있는 시스템을 보여 줍니다.

비디오 카드 2장과 모니터 3개가 있는 컴퓨터 다이어그램

이러한 하드웨어를 열거할 때 DXGI는 각 출력(또는 모니터)에 대한 IDXGIOutput1 인터페이스와 각 비디오 카드 대한 IDXGIAdapter2 인터페이스를 만듭니다(마더보드에 기본 제공된 비디오 카드 경우에도). 열거형은 IDXGIFactory 인터페이스 호출 인 IDXGIFactory::EnumAdapters를 사용하여 비디오 하드웨어를 나타내는 IDXGIAdapter 인터페이스 집합을 반환하여 수행됩니다.

DXGI 1.1은 IDXGIFactory1 인터페이스를 추가했습니다. IDXGIFactory1::EnumAdapters1 은 비디오 하드웨어를 나타내는 IDXGIAdapter1 인터페이스 집합을 반환합니다.

Direct3D API를 사용할 때 특정 비디오 하드웨어 기능을 선택하려면 각 어댑터 핸들 및 가능한 하드웨어 기능 수준을 사용하여 D3D11CreateDevice 또는 D3D11CreateDeviceAndSwapChain 함수를 반복적으로 호출하는 것이 좋습니다. 이 함수는 지정된 어댑터에서 기능 수준을 지원하는 경우 성공합니다.

Windows 8 어댑터 열거에 대한 새로운 정보

Windows 8 "Microsoft 기본 렌더링 드라이버"라는 어댑터가 항상 존재합니다. 이 어댑터에는 0x1414 VendorId와 0x8c DeviceID가 있습니다. 이 어댑터에는 DXGI_ADAPTER_DESC2 구조의 Flags 멤버에 설정된 DXGI_ADAPTER_FLAG_SOFTWARE 값도 있습니다. 이 어댑터는 디스플레이 출력이 없는 렌더링 전용 디바이스입니다. DXGI는 이 어댑터에 대한 DXGI_ERROR_DEVICE_REMOVED 반환하지 않습니다.

컴퓨터의 디스플레이 드라이버가 작동하지 않거나 사용하지 않도록 설정된 경우 컴퓨터의 기본(NULL) 어댑터를 "Microsoft 기본 렌더링 드라이버"라고도 할 수 있습니다. 그러나 이 어댑터에는 출력이 있으며 DXGI_ADAPTER_FLAG_SOFTWARE 값이 설정되어 있지 않습니다. 운영 체제 및 앱은 기본적으로 이 어댑터를 사용합니다. 디스플레이 드라이버가 설치되거나 사용하도록 설정된 경우 앱은 이 어댑터에 대한 DXGI_ERROR_DEVICE_REMOVED 받은 다음 어댑터를 다시 열거해야 합니다.

컴퓨터의 기본 디스플레이 어댑터가 "Microsoft Basic Display Adapter"(WARP 어댑터)인 경우 해당 컴퓨터에는 두 번째 어댑터도 있습니다. 이 두 번째 어댑터는 디스플레이 출력이 없고 DXGI가 DXGI_ERROR_DEVICE_REMOVED 반환하지 않는 렌더링 전용 디바이스입니다.

렌더링, 컴퓨팅 또는 기타 장기 실행 작업에 WARP를 사용하려면 렌더링 전용 디바이스를 사용하는 것이 좋습니다. IDXGIFactory1::EnumAdapters1 메서드를 호출하여 렌더링 전용 디바이스에 대한 포인터를 가져올 수 있습니다. 또한 WARP 디바이스도 렌더링 전용 WARP 어댑터를 사용하므로 D3D11CreateDeviceDriverType 매개 변수에 D3D_DRIVER_TYPE_WARP 지정할 때 렌더링 전용 디바이스를 만듭니다.

프레젠테이션

애플리케이션의 작업은 프레임을 렌더링하고 DXGI에 해당 프레임을 출력에 표시하도록 요청하는 것입니다. 애플리케이션에 두 개의 버퍼를 사용할 수 있는 경우 다른 버퍼를 표시하는 동안 하나의 버퍼를 렌더링할 수 있습니다. 애플리케이션은 프레임을 렌더링하는 데 걸리는 시간 또는 프레젠테이션에 필요한 프레임 속도에 따라 두 개 이상의 버퍼가 필요할 수 있습니다. 생성된 버퍼 집합을 스왑 체인이라고 합니다.

스왑 체인 그림

스왑 체인에는 하나의 프런트 버퍼와 하나 이상의 백 버퍼가 있습니다. 각 애플리케이션은 자체 스왑 체인을 만듭니다. 출력에 대한 데이터 표시 속도를 최대화하기 위해 스왑 체인은 거의 항상 다음 그림과 같이 디스플레이 하위 시스템의 메모리에 만들어집니다.

디스플레이 하위 시스템 그림

디스플레이 하위 시스템(종종 비디오 카드 있지만 마더보드에서 구현될 수 있음)에는 GPU, DAC(디지털-아날로그 변환기) 및 메모리가 포함됩니다. 스왑 체인은 프레젠테이션을 매우 빠르게 만들기 위해 이 메모리 내에 할당됩니다. 디스플레이 하위 시스템은 프런트 버퍼의 데이터를 출력에 표시합니다.

스왑 체인은 전체 화면 또는 창 모드로 그리도록 설정되므로 출력이 창 또는 전체 화면인지 여부를 알 필요가 없습니다. 전체 화면 모드 스왑 체인은 디스플레이 해상도를 전환하여 성능을 최적화할 수 있습니다.

스왑 체인 만들기

Direct3D 9와 Direct3D 10 간의 차이점: Direct3D 10은 DXGI를 사용하는 최초의 그래픽 구성 요소입니다. DXGI에는 몇 가지 다른 스왑 체인 동작이 있습니다.
  • DXGI에서 스왑 체인은 스왑 체인을 만들 때 창에 연결됩니다. 이렇게 변경하면 성능이 향상되고 메모리가 절약됩니다. 이전 버전의 Direct3D를 사용하면 스왑 체인이 연결된 창을 변경할 수 있습니다.
  • DXGI에서 스왑 체인은 생성 시 렌더링 디바이스에 연결됩니다. Direct3D 만들기 디바이스 함수가 반환하는 디바이스 개체는 IUnknown 인터페이스를 구현합니다. QueryInterface를 호출하여 디바이스의 해당 IDXGIDevice2 인터페이스를 쿼리할 수 있습니다. 렌더링 디바이스를 변경하려면 스왑 체인을 다시 만들어야 합니다.
  • DXGI에서 사용할 수 있는 스왑 효과는 DXGI_SWAP_EFFECT_DISCARD DXGI_SWAP_EFFECT_SEQUENTIAL. Windows 8 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 스왑 효과도 사용할 수 있습니다. 다음 표에서는 Direct3D 9에서 DXGI 스왑 효과 정의에 대한 매핑을 보여 줍니다.

    D3D9 교환 효과 DXGI 스왑 효과
    D3DSWAPEFFECT_DISCARD DXGI_SWAP_EFFECT_DISCARD
    D3DSWAPEFFECT_COPY 버퍼가 1인 DXGI_SWAP_EFFECT_SEQUENTIAL
    D3DSWAPEFFECT_FLIP 버퍼가 2개 이상 있는 DXGI_SWAP_EFFECT_SEQUENTIAL
    D3DSWAPEFFECT_FLIPEX 버퍼가 2개 이상 있는 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL

스왑 체인의 버퍼는 특정 크기 및 특정 형식으로 만들어집니다. 애플리케이션은 시작할 때 이러한 값(또는 대상 창에서 크기를 상속할 수 있음)을 지정한 다음, 사용자 입력 또는 프로그램 이벤트에 대한 응답으로 창 크기가 변경되면 필요에 따라 수정할 수 있습니다.

스왑 체인을 만든 후에는 일반적으로 이미지를 렌더링하려고 합니다. 다음은 스왑 체인으로 렌더링할 Direct3D 컨텍스트를 설정하는 코드 조각입니다. 이 코드는 스왑 체인에서 버퍼를 추출하고, 해당 버퍼에서 render-target-view를 만든 다음, 디바이스에서 설정합니다.

ID3D11Resource * pBB;
ThrowFailure( pSwapChain->GetBuffer(0, __uuidof(pBB),    
  reinterpret_cast<void**>(&pBB)), "Couldn't get back buffer");
ID3D11RenderTargetView * pView;
ThrowFailure( pD3D11Device->CreateRenderTargetView(pBB, NULL, &pView), 
  "Couldn't create view" );
pD3D11DeviceContext->OMSetRenderTargets(1, &pView, 0);
        

애플리케이션이 프레임을 스왑 체인 버퍼로 렌더링한 후 IDXGISwapChain1::P resent1을 호출합니다. 그러면 애플리케이션이 다음 이미지를 렌더링할 수 있습니다.

스왑 체인의 관리 및 공급

이미지를 렌더링한 후 IDXGISwapChain1::P resent1 을 호출하고 다음 이미지를 렌더링합니다. 그것이 여러분의 책임의 범위입니다.

이전에 IDXGIFactory::MakeWindowAssociation을 호출한 경우 사용자는 Alt-Enter 키 조합을 누를 수 있으며 DXGI는 창 모드와 전체 화면 모드 간에 애플리케이션을 전환합니다. IDXGIFactory::MakeWindowAssociation 을 사용하는 것이 좋습니다. 사용자에 대한 표준 제어 메커니즘이 매우 필요하기 때문입니다.

설명된 것보다 더 많은 코드를 작성할 필요는 없지만 몇 가지 간단한 단계를 통해 애플리케이션의 응답성을 높일 수 있습니다. 가장 중요한 고려 사항은 출력 창의 크기 조정에 대한 응답으로 스왑 체인의 버퍼 크기를 조정하는 것입니다. 당연히 애플리케이션의 가장 좋은 경로는 WM_SIZE 응답하고 IDXGISwapChain::ResizeBuffers를 호출하여 메시지의 매개 변수에 포함된 크기를 전달하는 것입니다. 이 동작으로 인해 창의 테두리를 끌 때 애플리케이션이 사용자에게 잘 응답할 수 있지만 원활한 전체 화면 전환을 가능하게 하는 것도 바로 이 동작입니다. 이러한 전환이 발생할 때마다 창에 WM_SIZE 메시지가 표시되며, IDXGISwapChain::ResizeBuffers 를 호출하는 것은 최적의 프레젠테이션을 위해 버퍼의 스토리지를 다시 할당할 수 있는 스왑 체인의 기회입니다. 따라서 애플리케이션은 IDXGISwapChain::ResizeBuffers를 호출하기 전에 기존 버퍼에 있는 참조를 해제해야 합니다.

전체 화면 모드로 전환(가장 자연스럽게 WM_SIZE 대한 응답으로)에 대한 응답으로 IDXGISwapChain::ResizeBuffers 를 호출하지 않으면 대칭 이동 최적화가 배제될 수 있습니다. 여기서 DXGI는 전체 화면의 데이터 가치를 복사하는 대신 표시되는 버퍼를 단순히 교환할 수 있습니다.

IDXGISwapChain1::P resent1 은 출력 창이 DXGI_STATUS_OCCLUDED 통해 완전히 폐색되었는지 알려줍니다. 이 경우 프레임을 렌더링하는 데 사용되는 리소스가 낭비되므로 애플리케이션이 대기 모드(IDXGISwapChain1::P DXGI_PRESENT_TEST resent1)를 호출하는 것이 좋습니다. DXGI_PRESENT_TEST 사용하면 폐색 검사 수행하는 동안 데이터가 표시되지 않습니다. IDXGISwapChain1::P resent1이 S_OK 반환되면 대기 모드를 종료해야 합니다. 이렇게 하면 스왑 체인이 전체 화면 모드를 포기할 수 없으므로 반환 코드를 사용하여 대기 모드로 전환하지 마세요.

Windows 8 시작하는 Direct3D 11.1 런타임은 플립 모델 스왑 체인(즉, DXGI_SWAP_CHAIN_DESC 또는 DXGI_SWAP_CHAIN_DESC1 SwapEffect 멤버에 설정된 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 값이 있는 스왑 체인)을 제공합니다. 플립 모델 스왑 체인을 사용하여 출력에 프레임을 표시하면 DXGI는 백 버퍼 0에 쓰는 출력 병합기 렌더링 대상과 같은 모든 파이프라인 상태 위치에서 백 버퍼를 바인딩 해제합니다. 따라서 백 버퍼로 렌더링하기 직전에 ID3D11DeviceContext::OMSetRenderTargets 를 호출하는 것이 좋습니다. 예를 들어 OMSetRenderTargets 를 호출하지 않고 리소스에 렌더링되지 않는 컴퓨팅 셰이더 작업을 수행합니다. 플립 모델 스왑 체인 및 해당 이점에 대한 자세한 내용은 DXGI Flip Model을 참조하세요.

참고

Direct3D 10 및 Direct3D 11에서는 편의상 백 버퍼의 ID가 변경되므로 IDXGISwapChain1::P resent1을 호출한 후 IDXGISwapChain::GetBuffer를 호출하여 버퍼 0을 다시 검색할 필요가 없습니다. Direct3D 12에서는 발생하지 않으며 애플리케이션은 버퍼 인덱스를 수동으로 추적해야 합니다.

처리 창 크기 조정

IDXGISwapChain::ResizeBuffers 메서드를 사용하여 창 크기 조정을 처리할 수 있습니다. ResizeBuffers를 호출하기 전에 스왑 체인의 버퍼에 대한 모든 미해결 참조를 해제해야 합니다. 일반적으로 스왑 체인의 버퍼에 대한 참조를 보유하는 개체는 render-target-view입니다.

다음 예제 코드는 WM_SIZE 메시지에 대해 WindowProc 처리 기 내에서 ResizeBuffers 를 호출하는 방법을 보여 줍니다.

    case WM_SIZE:
        if (g_pSwapChain)
        {
            g_pd3dDeviceContext->OMSetRenderTargets(0, 0, 0);

            // Release all outstanding references to the swap chain's buffers.
            g_pRenderTargetView->Release();

            HRESULT hr;
            // Preserve the existing buffer count and format.
            // Automatically choose the width and height to match the client rect for HWNDs.
            hr = g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
                                            
            // Perform error handling here!

            // Get buffer and create a render-target-view.
            ID3D11Texture2D* pBuffer;
            hr = g_pSwapChain->GetBuffer(0, __uuidof( ID3D11Texture2D),
                                         (void**) &pBuffer );
            // Perform error handling here!

            hr = g_pd3dDevice->CreateRenderTargetView(pBuffer, NULL,
                                                     &g_pRenderTargetView);
            // Perform error handling here!
            pBuffer->Release();

            g_pd3dDeviceContext->OMSetRenderTargets(1, &g_pRenderTargetView, NULL );

            // Set up the viewport.
            D3D11_VIEWPORT vp;
            vp.Width = width;
            vp.Height = height;
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            g_pd3dDeviceContext->RSSetViewports( 1, &vp );
        }
        return 1;

DXGI 출력 및 크기 선택

기본적으로 DXGI는 창의 클라이언트 영역 대부분을 포함하는 출력을 선택합니다. alt-enter에 대한 응답으로 전체 화면으로 이동할 때 DXGI에서 사용할 수 있는 유일한 옵션입니다. 애플리케이션 자체에서 전체 화면 모드로 전환하도록 선택하는 경우 IDXGISwapChain::SetFullscreenState 를 호출하고 명시적 IDXGIOutput1 (또는 NULL을 전달합니다. 애플리케이션이 DXGI를 결정하도록 허용하려는 경우)을 전달할 수 있습니다.

전체 화면 또는 창이 있는 동안 출력의 크기를 조정하려면 IDXGISwapChain::ResizeTarget을 호출하는 것이 좋습니다. 이 메서드는 대상 창의 크기도 조정하므로 입니다. 대상 창의 크기가 조정되므로 운영 체제는 WM_SIZE 보내고 코드는 응답에서 IDXGISwapChain::ResizeBuffers 를 자연스럽게 호출합니다. 따라서 버퍼 크기를 조정한 다음 대상의 크기를 조정하는 것은 낭비입니다.

전체 화면 모드에서 디버깅

DXGI 스왑 체인은 절대적으로 필요한 경우에만 전체 화면 모드를 포기합니다. 즉, 디버그 창이 스왑 체인의 대상 창과 겹치지 않는 한 여러 모니터를 사용하여 전체 화면 애플리케이션을 디버그할 수 있습니다. 또는 DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH 플래그를 설정하지 않으면 모드가 완전히 전환되지 않도록 방지할 수 있습니다.

모드 전환이 허용되는 경우 스왑 체인은 출력 창이 다른 창에 의해 가려질 때마다 전체 화면 모드를 포기합니다. 폐색 검사 IDXGISwapChain1::P resent1 또는 애플리케이션이 응답하지 않는지 확인하기 위해 watch 별도의 스레드에서 수행됩니다(더 이상 IDXGISwapChain1::P resent1). 별도의 스레드에서 스위치를 발생시키는 기능을 사용하지 않도록 설정하려면 다음 레지스트리 키를 0이 아닌 값으로 설정합니다.

HKCU\Software\Microsoft\DXGI\DisableFullscreenWatchdog

스왑 체인 삭제

이렇게 하면 스레드 경합이 발생할 수 있으므로 스왑 체인을 전체 화면 모드에서 해제할 수 없습니다(이로 인해 DXGI에서 연속 불가능한 예외가 발생). 스왑 체인을 해제하기 전에 먼저 창 모드( IDXGISwapChain::SetFullscreenState( FALSE, NULL )사용)로 전환한 다음 IUnknown::Release를 호출합니다.

회전된 모니터 사용

애플리케이션은 모니터 방향에 대해 걱정할 필요가 없으며, 필요한 경우 DXGI는 프레젠테이션 중에 스왑 체인 버퍼를 회전합니다. 물론 이 추가 회전은 성능에 영향을 미칠 수 있습니다. 최상의 성능을 위해 다음을 수행하여 애플리케이션의 회전을 처리합니다.

  • DXGI_SWAP_CHAIN_FLAG_NONPREROTATED 사용합니다. 이렇게 하면 애플리케이션이 회전된 이미지를 생성할 것임을 DXGI에 알 수 있습니다(예: 프로젝션 행렬을 변경). 한 가지 주의해야 할 점은 이 플래그는 전체 화면 모드에 있는 동안에만 유효합니다.
  • 회전된 크기로 각 스왑 체인 버퍼를 할당합니다. 필요한 경우 IDXGIOutput::GetDesc 를 사용하여 이러한 값을 가져옵니다.

애플리케이션에서 회전을 수행하면 DXGI는 단순히 복사본과 회전 대신 복사본을 수행합니다.

Windows 8 시작하는 Direct3D 11.1 런타임은 플립 모델 스왑 체인(즉, DXGI_SWAP_CHAIN_DESC1 SwapEffect 멤버에 설정된 DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 값이 있는 스왑 체인)을 제공합니다. 플립 모델 스왑 체인에서 사용할 수 있는 프레젠테이션 최적화를 최대화하려면 해당 콘텐츠가 출력을 완전히 차지할 때 콘텐츠가 상주하는 특정 출력과 일치하도록 애플리케이션에서 콘텐츠를 지향하도록 하는 것이 좋습니다. 플립 모델 스왑 체인 및 해당 이점에 대한 자세한 내용은 DXGI Flip Model을 참조하세요.

모드 전환

DXGI 스왑 체인은 전체 화면을 전환할 때 출력의 표시 모드를 변경할 수 있습니다. 자동 표시 모드 변경을 사용하도록 설정하려면 스왑 체인 설명에 DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH 지정해야 합니다. 디스플레이 모드가 자동으로 변경되면 DXGI는 가장 적당한 모드를 선택합니다(크기와 해상도는 변경되지 않지만 색 깊이는 변경되지 않을 수 있음). 스왑 체인 버퍼 크기를 조정해도 모드 스위치가 발생하지 않습니다. 스왑 체인은 대상 출력에서 지원하는 디스플레이 모드와 정확히 일치하는 백 버퍼를 선택하는 경우 해당 출력에서 전체 화면 모드로 전환할 때 해당 디스플레이 모드로 전환된다는 암시적 약속을 합니다. 따라서 백 버퍼 크기 및 형식을 선택하여 디스플레이 모드를 선택합니다.

전체 화면 성능 팁

전체 화면 애플리케이션에서 IDXGISwapChain1::P resent1 을 호출하면 스왑 체인이 백 버퍼의 내용을 전면 버퍼로 대칭 이동합니다(blits와 반대). 이렇게 하려면 열거형 디스플레이 모드( DXGI_SWAP_CHAIN_DESC1 지정됨)를 사용하여 스왑 체인을 만들어야 합니다. 디스플레이 모드를 열거하지 못하거나 설명에서 표시 모드를 잘못 지정하지 않으면 스왑 체인이 비트 블록 전송(비트블렛)을 대신 수행할 수 있습니다. 비트 블렛은 추가 스트레치 복사본뿐만 아니라 일부 증가 비디오 메모리 사용량을 야기하고, 감지하기 어렵다. 이 문제를 방지하려면 스왑 체인을 만들기 전에 디스플레이 모드를 열거하고 스왑 체인 설명을 올바르게 초기화합니다. 이렇게 하면 전체 화면 모드에서 전환할 때 최대 성능을 보장하고 추가 메모리 오버헤드를 방지합니다.

다중 스레드 고려 사항

여러 스레드가 있는 애플리케이션에서 DXGI를 사용하는 경우 서로 다른 두 스레드가 완료되기를 기다리는 교착 상태를 만들지 않도록 주의해야 합니다. 이 문제가 발생할 수 있는 두 가지 상황이 있습니다.

  • 렌더링 스레드는 메시지 펌프 스레드가 아닙니다.
  • DXGI API를 실행하는 스레드는 창을 만든 스레드와 다릅니다.

전체 화면 스왑 체인을 사용할 때 렌더링 스레드에서 메시지 펌프 스레드가 대기하지 않도록 주의하세요. instance 경우 렌더링 스레드에서 IDXGISwapChain1::P resent1을 호출하면 렌더링 스레드가 메시지 펌프 스레드에서 대기할 수 있습니다. 모드 변경이 발생하면 Present1 이 ::SetWindowPos() 또는 ::SetWindowStyle()을 호출하고 이러한 메서드 중 하나가 ::SendMessage()를 호출하는 경우 이 시나리오가 가능합니다. 이 시나리오에서 메시지 펌프 스레드에 중요한 섹션이 보호되거나 렌더링 스레드가 차단되면 두 스레드가 교착 상태가 됩니다.

여러 스레드에서 DXGI를 사용하는 방법에 대한 자세한 내용은 다중 스레딩 및 DXGI를 참조하세요.

DLLMain의 DXGI 응답

DllMain 함수는 DLL을 로드하고 언로드하는 순서를 보장할 수 없으므로 앱의 DllMain 함수는 개체를 만들거나 해제하는 함수 또는 메서드를 포함하여 Direct3D 또는 DXGI 함수 또는 메서드를 호출하지 않는 것이 좋습니다. 앱의 DllMain 함수가 특정 구성 요소를 호출하는 경우 해당 구성 요소는 운영 체제에 없는 다른 DLL을 호출하여 운영 체제가 충돌할 수 있습니다. Direct3D 및 DXGI는 컴퓨터와 컴퓨터 간에 다른 DLL 집합(일반적으로 드라이버 집합)을 로드할 수 있습니다. 따라서 DllMain 함수가 Direct3D 또는 DXGI 함수 또는 메서드를 호출할 때 앱이 개발 및 테스트 컴퓨터에서 충돌하지 않더라도 다른 컴퓨터에서 실행될 때 작동이 중단될 수 있습니다.

운영 체제 작동이 중단될 수 있는 앱을 만들지 못하도록 DXGI는 지정된 상황에서 다음과 같은 응답을 제공합니다.

  • 앱의 DllMain 함수가 DXGI 팩터리에 대한 마지막 참조를 해제하면 DXGI에서 예외가 발생합니다.
  • 앱의 DllMain 함수가 DXGI 팩터리를 만드는 경우 DXGI는 오류 코드를 반환합니다.

DXGI 1.1 변경 내용

DXGI 1.1에서 다음 기능을 추가했습니다.

DXGI 1.2 변경 내용

DXGI 1.2에서 다음 기능을 추가했습니다.

  • 스테레오 스왑 체인
  • 대칭 이동 모델 스왑 체인
  • 최적화된 프레젠테이션(스크롤, 더티 사각형 및 회전)
  • 향상된 공유 리소스 및 동기화
  • 데스크톱 중복
  • 비디오 메모리의 최적화된 사용
  • 픽셀당 16비트(bpp) 형식 지원(DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM)
  • 디버깅 API

DXGI 1.2에 대한 자세한 내용은 DXGI 1.2 개선 사항을 참조하세요.

DXGI 프로그래밍 가이드