티스토리 뷰

Direct3D를 학습하다 보면, Direct3D를 초기화하는 부분에서 부가 API들이 출몰하기 시작합니다. 그 중 DXGI를 이해하는 데 어려움을 겪고 있었기 때문에 정리하게 되었습니다. DXGI(DirectX Graphics Infrastructure) 는 Microsoft 문서에서 다음과 같이 설명하고 있습니다 :

DXGI (Microsoft DirectX Graphics Infrastructure)는 그래픽 어댑터 열거, 디스플레이 모드 열거, 버퍼 형식 선택, 프로세스 간(예 : 응용 프로그램과 데스크탑 창 관리자(DWM) 간) 자원 공유, 렌더링된 프레임을 디스플레이하기 위한 창 또는 모니터에 표시하는 작업을 처리합니다.

DXGI는 Direct3D 10, 11, 그리고 12에서 사용됩니다.

대부분 그래픽 프로그래밍이 Direct3D에서 수행되지만, DXGI를 사용하여 최종 구성(eventual composition) 및 디스플레이를 위해 창, 모니터 또는 기타 그래픽 구성 요소에 프레임을 표시할 수 있습니다. 또한 DXGI를 사용하여 모니터의 콘텐츠를 읽을 수 있습니다.

 

즉, DXGI는 Direct3D와 함께 쓰이는 API로써, 기본 착안은 여러 그래픽 API들에 공통인 그래픽 관련 작업들이 존재하는 것들을 한데 묶은 것이라 볼 수 있습니다. 가령, 2차원 및 3차원 렌더링 모두에 유효환 교환 사슬(swap chain)이나 페이지 전환, 어탭터, 모니터, 디스플레이 모드 등의 그래픽 시스템 정보 열거 등을 의미합니다.

 

자세한 설명은 아래 섹션들을 참조하시면 되겠습니다.

 

 

 

개요(DXGI Overview)


DXGI는 그래픽의 일부분이 다른 부분들에 비해 느리게 발전하는 것을 인지하고 있습니다. DXGI의 최우선 목표는 DirectX 그래픽스 런타임에 독립적인 저수준(low-level) 작업들을 관리하는 것입니다. DXGI는 미래의 그래픽스 구성 요소(components)를 위한 공통 프레임워크를 제공합니다; DXGI를 첫 번째로 이용한 컴포넌트는 Microsoft Direct3D 10입니다.

 

Direct3D의 이전 버전에서, 하드웨어 장치를 열거하거나, 출력을 위해 렌더링된 프레임을 표시하는 것, 감마 조정(controlling), 그리고 풀스크린 전환을 관리하는 것과 같은 저수준 작업들은 Direct3D 런타임에 포함되어 있었습니다. 이 작업들은 이제 DXGI에서 구현됩니다.

 

DXGI의 목적은 커널 모드 드라이버 및 시스템 하드웨어와 통신하는 것입니다. 아래 다이어그램에서 이를 나타냅니다:

그림1. DXGI Diagram

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

 

 

 

어댑터 열거(Enumerating Adapters)


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

그림2. 컴퓨터 및 어댑터의 구성 예

 

이러한 하드웨어를 열거할 때 DXGI는 각 출력(또는 모니터)에 대한 인터페이스 IDXGIOutput1와 각 비디오카드에 대한 인터페이스 IDXGIAdapter2를 만듭니다(마더보드에 내장된 비디오카드인 경우에도). 열거는 비디오 하드웨어를 나타내는 IDXGIAdapter 인터페이스 세트를 반환하기 위해 IDXGIFactory 인터페이스에서 호출가능한 IDXGIFactory::EnumAdapters를 사용하여 수행됩니다.

DXGI 1.1에서는 IDXGIFactory1 인터페이스를 추가하여, IDXGIFactory1::EnumAdapters1을 통해 비디오 하드웨어를 나타내는 IDXGIAdapter1 인터페이스 세트를 반환받을 수 있습니다.

 

 

 

Windows 8에 대한 어댑터 열거의 새 소식

Windows 8부터는 "Microsoft Basic Render Driver"라는 어댑터가 항상 존재합니다. 이 어댑터의 VendorID는 0x1414이고, DeviceID는 0x8c입니다. 이 어댑터에는 DXGI_ADAPTER_DESC2 구조체의 플래그 멤버에 DXGI_ADAPTER_FLAG_SOFTWARE 값이 설정되어 있습니다. 이 어댑터는 디스플레이 출력이 없는 렌더 전용 장치로, DXGI는 이 어댑터에 대해 DXGI_ERROR_DEVICE_REMOVED를 반환하지 않습니다.

 

컴퓨터의 디스플레이 드라이버가 작동하지 않거나 비활성화된 경우, 컴퓨터의 기본(NULL) 어댑터를 "Microsoft Basic Render Driver"라고도 합니다. 그러나 이 어댑터에는 출력을 가지고 있으며 DXGI_ADAPTER_FLAG_SOFTWARE 값 세트를 가지고 있지 않습니다. 운영 체제 및 어플리케이션은 이 어댑터를 디폴트으로 사용할 수 있습니다. 만약 디스플레이 드라이버가 설치되거나 사용가능하면, 어플리케이션은 이 어댑터에 대해 DXGI_ERROR_DEVICE_REMOVED를 수신받으며 이후 어댑터들을 다시 열거해야만 합니다.

 

컴퓨터의 기본 디스플레이 어댑터가 "Microsoft Basic Display Adapter"(WARP 어댑터)일 때 컴퓨터는 두 번째 어댑터 역시 가지고 있습니다. 이 두 번째 어댑터는 디스플레이 출력이 없는 렌더 전용 장치이며, DXGI가 DXGI_ERROR_DEVICE_REMOVE를 반환하지 않습니다.

참고 : WARP는 Windows Advanced Rasterization Platform의 약자로, 자세한 사항은 Microsoft 문서를 통해서 확인하실 수 있습니다.

 

만약 렌더링, 계산, 또는 다른 장기간 실행 작업에 WARP를 사용하려고 한다면 렌더링 전용 장치를 사용하는 것이 좋습니다. IDXGIFactory1::EnumAdapters1 메소드를 호출하여 렌더링 전용 장치에 대한 포인터를 얻을 수 있습니다. 사용자 역시 D3D11CreateDeviceDriverType 파라미터 안에 D3D_DRIVER_TYPE_WARP를 지정함으로써 렌더전용 장치를 생성할 수 있는데 WARP 장치 역시 렌더 전용 WARP 어댑터를 사용하기 때문입니다.

 

 

 

프레젠테이션(Presentation)


애플리케이션의 작업은 프레임을 렌더링하고 DXGI에 해당 프레임을 출력에 표시하도록 요청하는 것입니다. 어플리케이션에 사용가능한 버퍼가 두 개 있으면 다른 버퍼를 제공하면서 하나의 버퍼를 렌더링할 수 있습니다. 어플리케이션은 한 프레임을 렌더링하는 데 걸리는 시간 또는 프레젠테이션에 필요한 프레임 레이트에 따라 두 개 이상의 버퍼가 필요할 수 있습니다. 작성된 버퍼 세트를 아래와 같이 스왑 체인이라고 합니다.

그림3. 스왑 체인에 사용되는 버퍼 세트

 

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

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

 

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

 

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

 

 

 

기타


이번 포스팅은 DXGI에 대한 전반적인 개요만 설명한 것으로, 스왑 체인 생성 방법, 어댑터의 열거 방법 등에 대한 구현은 포스팅이 길어지는 관계로 생략하였습니다. 이에 대한 자세한 사항은 인터넷 또는 Microsoft | DXGI Overview에서 살펴볼 수 있습니다.

 

 

 

레퍼런스


참고자료
Microsoft | 개발자 센터 - DXGI
Microsoft | 개발자 센터 - DXGI Overview
Microsoft | 개발자 센터 - Windows Advanced Rasterization Plastform (WARP)
Direct 12를 이용한 3D 게임 프로그래밍 입문0
티스토리 Studing 블로그 | [DirectX12]기본지식 - DXGI(DriectX Graphics Infrastructure

 

'개발 > DirectX' 카테고리의 다른 글

DXGI API로 보는 구성 요소 1(IDXGIFactory, IDXGIAdapter, IDXGIOutput)  (2) 2019.12.22
XMVECTOR와 XMFLOAT  (1) 2019.11.26
댓글