포스트

고급컴퓨터그래픽스 11. Vulkan

고급컴퓨터그래픽스 11. Vulkan

건국대학교 고급컴퓨터그래픽스 김형석 교수님의 수업을 정리한 내용입니다.

Structure

Pasted image 20241129091423.png

Vulkan을 사용하는 Application의 계층 구조는 위와 같다. Vulkan Library 사용자는 가장 먼저 Instance를 생성해야 한다. Instance를 통해 초기 환경설정을 셋팅한다. Instance는 현재 프로세스를 실행중인 Device의 GPU를 찾아 읽기 전용인 Physical Device 객체를 생성한다. Physical Device에 접근하여 GPU의 전용 속성을 확인할 수 있다. 이후 프로그래머는 Logical Device를 통해 GPU를 조작한다. Logical Device는 Physical Device에 의존하는 GPU를 조작하는 Interface라고 보면 된다. Logical Device를 통해 CPU, Memory <-> GPU로 데이터를 전송하는 Bus를 만들며, 큐의 내용으로 Command Buffer를 전송한다.

Command, Command Buffer, Command Pool

Queue를 통해 GPU로 여러 Command를 전송할 수 있고, Command는 Command Buffer에 담아서 덩어리 단위로 전송한다. Command으로는 크게 그래픽 Command, 컴퓨팅 Command, 메모리 관리 Command가 존재한다.

Command Buffer는 Command Pool에 등록되어 메모리를 할당받는다. 마치 C에서 malloc으로 객체의 메모리 사이즈를 얼만큼 할당하고 언제 해제할 것인지 명시하듯, Vulkan에서는 메모리 관리가 프로그래의 책임이다. 따라서 Buffer 객체의 메모리를 할당받기 위해 Command Pool을 사용한다. Command Pool로 생성된 Command Buffer의 메모리는 Command Pool을 조작하여 일괄적으로 관리할 수 있게 된다.

즉 프로그래머는 Command Pool를 통해 얼만큼 사이즈의 메모리를 가진 Command Buffer를 할당받는다. 이후 Command를 Command Buffer에 등록하고, 이 Command Buffer 단위를 Queue를 통해 GPU로 전송할 수 있다.

Descriptor Set, Descriptor Pool

Pasted image 20241129101902.png

DescriptorSet은 Shader에서 사용할 Uniform Resource들을 관리하는 하나의 단위이다. DescriptorPool을 만들고, Pool을 통해 DescriptorSet를 할당받을 수 있다. 이후 Texture 또는 int, float, vec3, mat4같은 Uniform 변수에 전달할 데이터를 Set에 등록한다. Texture가 아닌 정보(int, mat4 등..)는 하나씩 Set에 등록하는게 아니라, 하나의 Buffer로 묶어 DescriptorSet에 등록한다. 그 이유는, CPU<->GPU 사이의 통신은 무조건 Buffer 단위로 동작하기 때문이다.

Image, Sampler

Sampler는 Shader가 Image를 어떻게 읽어야 하는지 정보를 제공하는 객체다. 따라서 Image 하나만 넘기면 안되고, 반드시 Image와 같이 Sampler를 제공해야 한다. 즉 Shader에서 Texture를 입력받아 사용하고 싶다면 DescriptorSet을 할당받아 Image와 Sampler를 등록하고, Texture를 사용하고 싶은 Shader가 등록된 RenderPass 사용 전 DescriptorSet를 바인딩하면 Shader에서 Texture를 불러와 사용할 수 있다.

Render Pass, Pipeline, CPU memory와 GPU memory, Heap, Render 이후 생성된 Image는 GPU에서 바로 Display됨. 파일 저장등의 이유로 CPU로 가져와야할 땐 명령어를 사용함.

Swap Chain

Pasted image 20241129093732.png

Swap Chain이라는 Collection은 여러개의 Image Buffer를 갖는다. 이를 통해 Double Buffering, Triple Buffering, … 등등의 Multiple Buffering을 구현할 수 있다. Double Buffering을 사용해서 Tearing 현상을 해결하려면, Image Buffer 개수를 2개를 만들고, 하나의 Image Buffer를 Display에 활성화 하고, 활성화되지 않은 Image Buffer는 초기화->Rendering를 수행하고 Rendering이 마치면 Image Buffer를 Swap한다. 이후 비활성화된 Buffer를 Clear하고 다시 Rendering를 수행하는 과정을 반복하여 Tearing 현상을 해결한다.

Surface

API 사용자는 Instance 생성 후, Surface를 생성해야 한다. Surface는 API 사용자와 운영체제 Display System 사이의 Interface 역할을 한다. API 사용자는 Window 버전, Mac 버전, Android 버전을 따로따로 개발하는 것이 아니라, 그저 Surface를 사용하여 Display를 조작하면 된다. 그에 맞춰 Vulkan API 수준에서 운영체제에 맞게 알맞게 동작된다.