티스토리 뷰

반응형

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

 

반응형

'DirectX12 > Direct3D' 카테고리의 다른 글

Direct3D Hull Shader triangle patch (작성 중.)  (0) 2023.10.18
Direct3D의 다중표본화과 기능 수준.  (0) 2023.06.06
다중표본화의 이론.  (0) 2023.06.04
자원과 서술자.  (0) 2023.05.27
깊이 버퍼링(Depth Buffering).  (0) 2023.05.25
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함