DirectX로 본격적인 렌더링을 하기 이전 사용할 장치들에 대한 초기화가 필요하다. 초기화는 말 그대로 DirectX의 Init
시점에 이루어져야한다.
DirectX의 초기화는 다음과 같은 과정으로 진행된다.
- Device 생성
- 4X MSAA 품질 수준 지원 점검 ( 생략 가능 )
- CommandQueue, CommandList 생성
- Fence 생성
- SwapChain 설정
- Descriptor 크기 얻기
- Descriptor Heap 생성, Render Target View 생성, Depth Stencil View 생성
초기화할 것들에 대한 기본 이론들을 이전 글에서 정리하였으므로, 바로 순서대로 초기화를 진행해보자.
DirectX의 초기화는 Device(장치)를 생성하는 것으로 시작된다. Device는 GPU를 나타내는 객체로 Resource, View, CommandList 등 다른 인터페이스 객체들을 생성할때에 사용한다.
ComPtr<IDXGIFactory4> mdxgiFactory;
ComPtr<ID3D12Device> md3dDevice;
CreateDXGIFactory1(IID_PPV_ARGS(&mdxgiFactory);
HRESULT hardwareResult = D3D12CreateDevice(
nullptr /* Default Adapter (Base GPU) */,
D3D_FEATURE_LEVEL_11_0 /* 기대수준 -> DX11 */,
IID_PPV_ARGS(&md3dDevice)
);
일반적으로 Adapter
는 하드웨어 장치(GPU)이지만, DX11 레벨을 지원하는 하드웨어 장치를 생성할 수 없는 상황이 발생할 수 있다.
이 때, 하드웨어 그래픽 기능성을 흉내 내는 소프트웨어 디스플레이 어댑터(WARP)를 받는 장치를 생성하여 문제를 해결할 수 있다.
if(FAILED(hardwareResult)) // 하드웨어 장치를 생성할 수 없다면 {
// WAPR Adapter 객체
ComPtr<IDXGIAdapter> pWarpAdapter;
// Device에 제공할 WARP Adapter 가져오기
mdxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&pWarpAdapter));
// Device 생성
D3D12CreateDevice(
pWarpAdapter->get(),
D3D_FEATURE_LEVEL_11_0
IID_PPV_ARGS(&md3dDevice)
);
}
모든 DX11 장치는 4X MASS를 지원하기에, 위에서 정상적으로 Device가 생성되었다면 이 과정을 생략할 수 있다. 하지만 DirectX를 처음배우는 입장이기에 이 글에서는 지원 여부를 명시적으로 점검한다.
bool m4xMsaaState = false; // enable 4X MASS
UINT m4xMsaaQuality = 0; // quality level of 4X MASS
bool Get4xMsaaState() const {
return m4xMsaaState;
}
void Set4xMsaaState(bool value) {
if(m4xMsaaState != value) {
m4xMsaaState = value;
}
}
// MSAA 설정 구조체
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels;
// 구조체 세팅
msQulityLevels.Format = mBackBufferFormat;
msQulityLevels.SampleCount = 4; // 4X MSAA
msQulityLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
msQulityLevels.NumQualityLevels = 0;
// 백 버퍼 4X MSAA 지원 여부 검사
ThrowIfFailed(md3dDevice->CreateFeatureSupport(
D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
&msQualityLevels,
sizeof(msQualityLevels)
));
m4xMassQuality = msQualityLevels.NumQualityLevels;
// quality 값이 0이라면 지원 안함. assert로 끊엊주기
asset(m4xMassQuality > 0);