장치 초기화

원래벌레·2022년 8월 3일
0

🌞 DirectX를 배우는 이유

  • DirectX는 프로그래머가 컴퓨터의 GPU에게 명령을 내릴 수 있는 것이라고 생각하면 된다.

  • GPU는 여러가지 제조사가 있을 것이다. Intel이 됐든, Nvdia가 됐든, 이러한 회사 각각이 다른 정책을 가지고 GPU와의 연동을 지원한다면 프로그래머 입장에서 보았을 때 개발을 하기가 까다로울 것이다. 그렇기 때문에 이러한 GPU를 제작하는 회사들은 마이크로소프트 사에서 만든 DirectX를 기준으로 GPU를 제작하는 것이다.

🌞 Engine 중요 요소 4가지


> 🌼 Device

Device는 비유를 하자면 인력사무소의 개념으로, Device를 통해서 모든 GPU에 대한 일감을 주고, 받는 역할을 한다.

중요 메소드

::D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device));
// 중요한 메소드 나중에 알아 볼 것

앞으로 GPU에게 일을 시킬 때는 device를 이용하여 시키겠다는 일련의 과정이 담긴 메소드이다.


> 🌼 CommandQueue

CommandQueue 는 비유하면 일감목록 이다.
CPU와 GPU는 하는 일에 대해서 동기화가 되어야 할 것이다. 만약에 그렇지 못하면 먼저 CPU가 일을 GPU에게 바로바로 넘겨주고, GPU가 이를 받게되면 앞에 일이 전부다 끝나지도 않았는데 새로운 일을 받게 되면서 렌더 되는 화면에 올바르지 못할 것이다. 하지만 그렇다고 GPU가 일을 하는 중에 CPU는 놀게끔, 그리고 CPU가 일 할 때는 GPU가 놀게끔 하는 방식은 비효율적이기 때문에, 외주목록 즉 CommandQueue에 일감을 차곡차곡 기록했다가 한 방에 요청하는 것이다. 이렇게 해준다면 GPU가 일을 할 때는 CPU는 일감을 차곡차곡 쌓아주고, CPU는 GPU에게 일감을 줄 수 있을 것이다. 또한 CommandQueue에서는 fence라는 것을 사용는데, 이 fence라는 녀석은 CPU와 GPU의 동기화를 해결해주는 eventHandler 이다.


> 🌼 SwapChain

SwapChain은 비유로 하자면 외주과정 이다.
1) 현재 게임 세상에 있는 상황을 묘사
2) 어떤 공식으로 어떻게 계산할지 던져줌
3) GPU가 열심히 계산 (외주)
4) 결과를 받아서 화면에 그려준다.

위의 4가지의 과정을 행하는 것이 SwapChain 이다.

SwapChain에서 눈여겨 볼 것은 바로 DoubleBuffer이다. ( 면접에서 자주 나옴 )

DoubleBuffer에 대한 설명은 아래와 같다.

외주결과물 을 어디에 받지?
1) 어떤 종이(Buffer)에 그려서 건내달라고 부탁해보자
2) 특수 종이를 만들어서 -> 처음에 건내주고 -> 결과물을 해당 종이에 받는다. OK
3) 우리 화면에 특수 종이 ( 외주 결과물 ) 출력해준다.

의문점
1) 그런데 화면에 현재 결과를 출력하는 와중에, 다음 화면도 외주를 맡겨야 한다.
2) 현재 화면 결과물은 이미 화면 출력에 사용 중이다.
3) 특수 종이를 2개 만들어서, 하나는 현재 화면을 그려주고, 하나는 외주 맡기고..

👉 Double Buffering!

0 or 1
현재 화면 [0] <-> GPU 작업중 [1] BackBuffer

중요메소드

dxgi->CreateSwapChain(cmdQueue.Get(), &sd, &_swapChain);

> 🌼 DescriptorHeap

DescriptorHeap 을 비유하자면 기안서와 같다. 우리는 Device를 만들고, SwapChain을 통해서 두개의 버퍼에 해당하는 Resource를 만들어 주었다. 하지만 컴퓨터 입장에서 본다면, 이 Resource가 하는 일이 무엇인지 알 수가 없다. 그렇기 때문에 이 DescriptorHeap을 통해서 각종 리소스를 어떤 용도로 사용하는지 꼼꼼하게 적어서 넘겨주는 역할을 한다.

중요 메소드

device->CreateDescriptorHeap(&rtvDesc, IID_PPV_ARGS(&_rtvHeap));

device->CreateRenderTargetView(...)

첫번째 메소드를 이용하여 Heap공간을 만들어 주고, 두번째 메소드를 통하여 힙 영역에서 설명에 해당되는 객체인 RenderTargetView가 들어가게 된다. 이렇게 들어간 객체들은 GPU와 CPU 측면 모두에서 관리가 되게된다. GPU뿐 아니라 CPU에서도 관리를 하는 이유는 CPU가 GPU의 정보를 가져 올 순 없기 때문에, GPU에 생성된 Heap에 영역에 번호를 매겨 이를 맵핑하는 역할을 한다.


Device를 통해서 GPU와 연동 -> SwapChain을 통해 두개의 버퍼를 할당 -> DescriptorHeap을 통하여 두 버퍼가 할 일을 힙에 저장 -> CommandQueue를 통해서 일거리들이 할당되고 화면이 렌더링 된다.

profile
학습한 내용을 담은 블로그 입니다.

0개의 댓글