SwapChain
교환 사슬
[외주 과정]
- 현재 게임 세상에 있는 상황을 묘사
- 어떤 공식으로 어떻게 계산할지 던져줌
- GPU가 열심히 계산 (외주)
- 결과물 받아서 화면에 그려준다
[외주 결과물]을 어디에 받지?
- 어떤 종이(Buffer)에 그려서 건내달라고 부탁해보자
- 특수 종이를 만들어서 -> 처음에 건내주고 -> 결과물을 해당 종이에 받는다 OK
- 우리 화면에 특수 종이(외주 결과물) 출력해준다
[?]
- 그런데 화면에 현재 결과물 출력하는 와중에, 다음 화면도 외주를 맡겨야 함
- 현재 화면 결과물은 이미 화면 출력에 사용중
- 특수 종이를 2개 만들어서, 하나는 현재 화면을 그려주고, 하나는 외주 맡기고...
- Double Buffering!
- [0] [1]
현재 화면 [1] <-> GPU 작업중 [2] BackBuffer
-> [2] 작업 완료
-> 현재 화면 [2] <-> GPU 작업중 [1] BackBuffer
-> ... 반복
Double Buffering을 이용해 화면출력과 BackBuffer작업 처리
구식 소총 느낌? 총을 쏘고 뒤는 장전 뒤가 앞에 나와 총을 쏘고 앞은 뒤로가 총을 장전...
듣고있는 강의의 강사님이 현실세계에 비유한 SwapChain이다.
- 스왑 체인은 순차적으로 연결된 프레임 버퍼들의 집합.
- Front Buffer: 모니터와 직접 연결, 그래픽 카드만 접근 가능
- Back Buffer: 응용 프로그램이 그래픽 작업을 하는 영역이다.
- 프레젠테이션(Presentation)
- Back Buffer를 Front Buffer로 옮기는 작업.
void SwapChain::CreateSwapChain(const WindowInfo& info, ComPtr<IDXGIFactory> dxgi, ComPtr<ID3D12CommandQueue> cmdQueue) {
_swapChain.Reset();
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = static_cast<uint32>(info.width);
sd.BufferDesc.Height = static_cast<uint32>(info.height);
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = SWAP_CHAIN_BUFFER_COUNT;
sd.OutputWindow = info.hwnd;
sd.Windowed = info.windowed;
sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
dxgi->CreateSwapChain(cmdQueue.Get(), &sd, &_swapChain);
for (int32 i = 0; i < SWAP_CHAIN_BUFFER_COUNT; i++)
_swapChain->GetBuffer(i, IID_PPV_ARGS(&_rtvBurffer[i]));
}
SwapChain이 가질 성질을 정의한다.