DXGI(DirectX Graphics Infrastructure).
DXGI(DirectX Graphics Infrastructure)는Direct3D와 함께 쓰이는 API이다. DXGI에 말린 기본 착안은 , 여러 그래픽 API들에 공통인 그래픽 관련 작업들이 존재한다는 것이다.
예를 들어 매끄러운 2차원 애니메이션을 위해서는 2차원 렌더링 API 에도 3차원 렌더링 API처럼 교환사슬과 페이지 전환이 필요하다. 이 때문에 교환 사슬을 대표하는 인터페이스인 IDXGISwapchain을 실제로 DXGI API 의 일부이다.
DXGI는 그 밖에도 여러 가지 공통적인 그래픽 가능성을 처리한다.
이를 테면 전체화면 모드전환 , 디스플레이 에댑터나 모니터, 지원되는 디스플레이 모드 ( 해상도, 갱신율등 ) 같은 그래픽 시스템정보의 열거 등의 기능은 DXGI 가 제공한다. 또한, 지원되는 표현 형식들도 DXGI에 정의되어 있다. ( DXGI FORMAT ).
그럼 Direct3D 초기화 과정에 쓰이는 몇 가지 DXGI 개념들과 인터페이스들을 간략하게 살펴보자.
DXGI 의 핵심 인터페이스 중 하나인 DXGIFactory 인터페이스가 있다 .
이 인터페이스는 주로 IDXGISwapchain 인터페이스 생성과 디스플레이 어댑터 열거에 쓰인다. 디스플레이 어댑터는 그래픽 기능성을 구현한다.
일반적으로, 디스플레이 이댑터는 물리적인 하드웨여 장치 ( 이를 테면 그래픽 카드) 이다 .
그러나, 하드웨어 그래픽 기능성을 흉내내는 소프트웨어 디스플레이 어댑터도 존재한다. 하나의 시스템에 여러 개의 어댑터가 있을 수 있다 ( 이를 테면 한 시스템에 여러 개의 그래택 카드가 장착되어 있을 수 있다).
디스플레이 어댑터를 대표하는 인터 페이스는 IDXGIAdapter이다.
다음코드는 시스템에 있는 모든 어댑터를 열거하는 방법을 보여준다.
//시스템의 모든 디스플레이 어댑터를 열거한다.
void D3DApp::LogAdapters()
{
UINT i = 0;
IDXGIAdapter* adapter = nullptr;
std::vector<IDXGIAdapter*> adapterList;
while (mdxgiFactory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND)
{
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
std::wstring text = L"***Adapter";
text += desc.Description;
text+= L'\n';
OutputDebugString(text.c_str());
adapterList.push_back(adapter);
++i;
}
for (size_t i = 0; i < adapterList.size(); ++i)
{
LogAdapterOutputs(adapterList[i]);
}
}
다음은 이 메서트의 출력 예이다.
* * * Adapter : NIDIA GeForce GTX 760
* * * Adapter : Microsoft Basic Render Driver
" Microsoft Basic Render Dirver " 는 Window 8 이상에 포함된 소프트웨어 디스플레이 어댑터이다. 한 시스템에 모니터가 여러 개 연결되어 있을 수 있다 .모니터는 디스플레이 출력 ( display output ) 의 한 예이다.
디스플레이 출력은 IDXGIOutput 인터페이스가 대표한다.
각 어댑터에는 출력들의 목록이 연관되어 있다. 예를 들어 어떤 시스템에 그래픽 카드가 두개, 모니터가 세 개 연결되어 있으며, 세 모니터 중 둘은 한 그대픽 카드에 물려있고나머지 하나는 다른 한 그래픽 카드에 물려있다고하자.
그러면 한 어댑터에는 출력이 둘인 목록이 연관되며 다른 한 어댑터에는 출력이 하나인 출력목록이 연관된다.
다음은 주어진 한 어댑터에 연관된 모든 출력을 열거하는 코드이다.
//주어진 어댑터와 연관된 모든 출력을 열거한다.
void D3DApp::LogAdapterOutputs(IDXGIAdapter* adapter)
{
UINT i = 0;
IDXGIOutput* output = nullptr;
while (adapter->EnumOutputs(i, &output) != DXGI_ERROR_NOT_FOUND)
{
DXGI_OUTPUT_DESC desc;
output->GetDesc(&desc);
std::wstring text = L"***Output : ";
text += desc.DeviceName;
text += L"\n";
OutputDebugString(text.c_str());
LogOutputDisplayModes(output, mBackBufferFormat);
ReleaseCom(output);
++i;
}
}
MSDM 문서화에 따르면 , " Microsoft Basic Render Driver " 에는 출력이 없다.
하나의 모니터는 여러 디스플레이 모드를 지원한다. DXGI_MODE_DESC 구조체에는 하나의 다스플레이 모드를 서술하는 여러 멤버들이 있다.
typedef struct DXGI_MODE_DESC
{
UINT Width; //가로 해상도 (너비).
UINT Height; //세로 해상도 (높이).
DXGI_RATIONAL RefreshRate;
DXGI_FORMAT Format; //디스플레이 형식.
DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; //스캔방식 : 순차주사 (프로그레시브), 비월 주사(인터레이스).
DXGI_MODE_SCALING Scaling; //영상을 모니터 크기에 맞게 늘리거나 줄이는 방식.
} DXGI_MODE_DESC;
typedef struct DXGI_RATIONAL
{
UINT Numerator;
UINT Denominator;
} DXGI_RATIONAL;
typedef enum DXGI_MODE_SCANLINE_ORDER
{
DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED = 0,
DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE = 1,
DXGI_MODE_SCANLINE_ORDER_UPPER_FIELD_FIRST = 2,
DXGI_MODE_SCANLINE_ORDER_LOWER_FIELD_FIRST = 3
} DXGI_MODE_SCANLINE_ORDER;
typedef enum DXGI_MODE_SCALING
{
DXGI_MODE_SCALING_UNSPECIFIED = 0,
DXGI_MODE_SCALING_CENTERED = 1,
DXGI_MODE_SCALING_STRETCHED = 2
} DXGI_MODE_SCALING;
다음 코드는 주어진 출력과 디스플레이 형식을 지원하는 모드 디스플레아 모드를 담은 목록을 얻는 방법을 보여준다 .
/주어진 출력과 픽셀 형식의 조합이 지원하는 모든 디스플레이 모드를 나열한다.
void D3DApp::LogOutputDisplayModes(IDXGIOutput* output, DXGI_FORMAT format)
{
UINT count = 0;
UINT flags = 0;
//nullpter을 인수로 해서 호출하면 목록의 크기(모드 개수)를 얻게 된다.
output->GetDisplayModeList(format, flags, &count, nullptr);
std::vector<DXGI_MODE_DESC> modeList(count);
output->GetDisplayModeList(format, flags, &count, &modeList[0]);
for (auto& x : modeList)
{
UINT n = x.RefreshRate.Numerator;
UINT d = x.RefreshRate.Denominator;
std::wstring text =
L"Width = " + std::to_wstring(x.Width) + L" " +
L"Height = " + std::to_wstring(x.Height) + L" " +
L"Refresh = " + std::to_wstring(n) + L"/" + std::to_wstring(d) +
L"\n";
::OutputDebugString(text.c_str());
}
}
다음은 이 코드의 출력의 예이다.
*** output : \\.\DISPLAY2
…
width = 1920, Height = 1080, Refresh = 59950 / 1000
width = 1920, Height = 1200, Refresh = 59950 / 1000
이러한 디스플레이 모드 열거는 전체 화면 모드로 갈 때 특히나 중요하나 전체 화면 성능을 극대화하려면, 지정된 디스플레이 모드( 갱신률 포함 )가 반드시 모니터가 지원하는 한 디스플레이 모드와 정확히 일치해야 한다. 모니터가 지원하는 디스플레이 모드들을 열거해서 그 중 하나로 지정하면 그러한 일치가 보장된다.
DXGI 개요 - Win32 apps
이 항목에는 다음과 같은 섹션이 포함되어 있습니다.
learn.microsoft.com