0. Direct3D 12 개요
DirectX 12를 이용한 3D 프로그래밍 입문 예제(Frank D. Luna)를 따라 작성한다.
https://github.com/Microsoft/DirectX-Graphics-Samples
GitHub - microsoft/DirectX-Graphics-Samples: This repo contains the DirectX Graphics samples that demonstrate how to build graph
This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows. - GitHub - microsoft/DirectX-Graphics-Samples: This repo contains the Direc...
github.com
1. COM 객체
COM(Component Object Model) 은 DirectX의 독립성과 하위 호환성을 가능하게 하는 기술이다. COM 객체를 흔히 COM 인터페이스라고 부르지만 C++ 클래스로 간주하고 사용해도 무방하다. COM 객체의 메모리는 Microsoft::WRL::ComPtr (#include <wrl.h>)로 관리해준다. 아래는 사용할 컴 객체와 변수들이다.
ComPtr<IDXGIFactory> mFactory;
ComPtr<IDXGISwapChain> mSwapChain;
ComPtr<ID3D12Device> mDevice;
ComPtr<ID3D12Fence> mFence;
UINT64 mCurrentFence = 0;
ComPtr<ID3D12CommandQueue> mCommandQueue;
ComPtr<ID3D12CommandAllocator> mCommandAllocator;
ComPtr<ID3D12GraphicsCommandList> mCommandList;
static const int SwapChainBufferCount = 2;
int mCurrentBuffer = 0;
ComPtr<ID3D12Resource> mBackBuffer[SwapChainBufferCount];
ComPtr<ID3D12Resource> mDepthStencilBuffer;
ComPtr<ID3D12Heap> mRtvHeap;
ComPtr<ID3D12Heap> mDsvHeap;
D3D12_VIEWPORT mViewport;
D3D12_RECT mScissorRect;
UINT mRtvDescriptorSize = 0;
UINT mDsvDescriptorSize = 0;
UINT mCbvSrvUavDescriptorSize = 0;
// 초기화용 상수들
std::wstring mCaption = L"D3D App";
D3D_DRIVER_TYPE mDriverType = D3D_DRIVER_TYPE_HARDWARE;
DXGI_FORMAT mBackBufferFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
DXGI_FORMAT mDepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT;
int mWidth = 800;
int mHeight = 600;
2. 텍스처 형식
텍스처에는 특정 형식(format)의 자료 원소들을 DXGI_FORMAT 열거형으로 지정한다.
https://docs.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format
DXGI_FORMAT (dxgiformat.h) - Win32 apps
Resource data formats, including fully-typed and typeless formats. A list of modifiers at the bottom of the page more fully describes each format type.
docs.microsoft.com
무형식(typeless) 텍스처들은 일단 메모리만 확보해 두고, 형식은 파이프라인에 묶을 때 지정한다.
3. SwapChain 과 Presenting
애니메이션이 껌벅이는 현상을 피하기 위한 기법으로 버퍼(도화지)를 두 개 준비하여 전면 버퍼를 화면에 내보이는 동안 후면 버퍼에 다음 애니메이션을 그리고 전면 버퍼와 후면 버퍼의 역할을 교환하여 페이지가 전환되게 하는 것을 제시(presenting) 이라고 부른다.
이렇게 전, 후면 버퍼는 하나의 교환 사슬(SwapChain)을 형성한다. D3D에서 대표적인 교환사슬 인터페이스는 IDXGISwapChain이다.
4. 깊이 버퍼링
깊이 버퍼는 쉽게말해 가까운 물체인지 먼 물체인지의 정보를 담는 버퍼다. 깊이버퍼링 또는 z-버퍼링이라는 기법을 사용한다. 이 기법을 사용하면 그리는 순서와 무관하게 물체들이 가려진다.
5. 자원과 서술자
DirectX에서의 자원은 보통 버퍼와 텍스처를 말한다.
D3D에서는 무언가를 그릴 때 필요한 자원들을 파이프라인에 묶어(bind)주어야 하는데 이 자원들을 직접 묶지 않고, 해당 자원을 참조하는 서술자(descriptor) 객체를 묶는다. 서술자 객체는 GPU에게 자원을 서술해주는 하나의 간접층이다. 이 층을 두는 이유는 GPU 자원이 사실상 범용적인 메모리 조각이기 때문에 같은 자원을 여기저기에서 쓸 수 있게 해주는 것이다. 서술자는 말 그대로 자원의 상태를 서술(파이프라인의 어떤 단계에 어떻게 묶어야 하는지 등)해준다.
참고로 뷰 == 서술자 같은말이다.
이 책(Frank D. Luna DirectX12)에서는 다음과 같은 서술자들을 사용한다.
1. CBV/SRV/UAV(Constant Buffer View / Shader Resource View / Unorderd Access View): 상수버퍼, 셰이더 자원, 순서 없는 접근 서술
2. 표본추출기 서술자: 표본추출기(sampler) 자원 서술
3. RTV(Render Target View): 렌더 대상 자원 서술
4. DSV(Depth Stencil View): 깊이 스텐실 자원 서술
서술자들은 응용 프로그램 초기화 시점에서 생성하는 것을 권장한다.
6. 기능 수준
기능 수준(Feature Level)은 DX11 에서 도입된 것으로, D3D_FEATURE_LEVEL 열거형이 대표적이다. 이 기능 수준은 GPU가 지원하는 엄격한 집합을 정의한다.
7. DXGI(DirectX Graphics Infrastructure)
Direct3D와 함께 쓰이는 API로 여러가지 공통적인 그래픽 기능성을 처리한다. ex) 전체화면모드, 디스플레이 모드(해상도, 주사율 등) 같은 그래픽 시스템 정보들 열거 등의 기능을 제공한다.
8. 상주성
Direct3D 12에서 응용 프로그램 자원을 GPU 메모리부터 내림으로써('퇴거'), 그리고 필요하면 다시 올림으로써('입주') 자원의 상주성(GPU가 메모리에 들어있는지의 여부)을 관리한다.