주의 : 이 문서는 초심자 튜토리얼이 아닙니다. 기본 개념 정도는 안다고 가정합니다. 초심자는 [ Vulkan Tutorial ] 이나 [ Vulkan Samples Tutorial ] 을 보면서 같이 보시기 바랍니다.

주의 : 완전히 이해하고 작성한 것이 아니므로 잘못된 내용이 포함될 수 있습니다.

주의 : 이상하면 참고자료를 참조하세요.

정보 : 본문의 소스 코드는 Vulkan C++ exmaples and demos 를 기반으로 하고 있습니다. 



Installable Client Driver


Vulkan 로더는 ICD 라는 라이브러리와 통신함으로써 피지컬 디바이스( Physical Device, 실제 그래픽스 카드 )와 통신합니다.



레이어 정보를 기술하기 위해서 json 매니페스트를 유지하듯이, ICD 정보를 기술하기 위한 json 매니페스트 파일도 존재합니다. 


HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{Adapter GUID}\000X\VulkanDriverNameWow

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Class\{SoftwareComponent GUID}\000X\VulkanDriverNameWow


추가적으로 다음과 같은 경로에 정보가 있다면 읽어들이기도 합니다.


HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\


그런데 "{Adapter GUID}" 와 "{SoftwareComponent GUID}" 는 클래스 아이디로서 이미 정해져 있는 값이 있습니다. "{Adapter GUID}" 는 디스플레이 어댑터를 의미하는 클래스 아이디로서 이것도 이미 정해져 있는 값이 있습니다. 실제로 Vulkan-Loader 소스에서도 하드코딩해서 사용하고 있더군요.


장치 관리자에서 찾아 봤더니 "{4d36e968-e325-11ce-bfc1-08002be10318}" 였습니다. 이는 Intel 카드에서도 동일한 값을 가지고 있었습니다.



Software-Component 라는 것은 Windows 10 에서 실질적인 드라이버 소프트웨어를 의미하는 것 같더군요. 이것의 클래스 아이디도 "{5c4c3332-344d-483c-8739-259e934c9cc8}" 로 정해져 있었습니다.


어쨌든 "{Adapter GUID}" 와 관련한 레지스트리를 찾아 보니 "0000" 에는 다음과 같이 Nvidia 그래픽스 카드가 사용하는 Vulkan Driver 의 정보가 들어 있었습니다.



"0001" 에는 Intel 그래픽스 카드를 위한 정보가 들어 있었는데 Vulkan 을 지원하지 않는지 특별한 정보가 없었습니다. 실제로 Physical-Device 를 열거해도 나오지 않습니다.


"{SoftwareComponent GUID}" 와 관련한 레지스트리에는 별 정보가 없었고, "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\Drivers\" 는 아예 존재하지도 않았습니다.


어쨌든 "VulkanDriverNameWow" 가 가리키는 경로에는 ICD 용 json 파일이 있습니다. 이름이 "nv-v64.json" 이더군요. 열어 보니 다음과 같은 정보가 담겨 있었습니다.



"ICD" 필드에 "library_path" 와 "api_version" 이 기입되어 있어서 적절한 라이브러리와 버전을 찾을 수 있도록 하고 있습니다. 추가적으로 "VK_LAYER_NV_optimus" 레이어도 등록하고 있네요.


Physical Device


Vulkan 에서 physical device 는 VkPhysicalDevice 라는 디스패쳐블 오브젝트로서 정의됩니다. 그런데 이 오브젝트는 응용프로그램에서 생성하는 것이 아닙니다. vkEnumeratePhysicalDevices() 함수를 통해서 열거할 수만 있습니다. 왜냐하면 피지컬 디바이스는 OS 가 로드되면서 이미 생성되어 있는 상태이기 때문입니다.


다른 열거 함수들과 마찬가지로 count 를 획득한 다음에 실제 데이터를 채웁니다.



앞에서 레지스트리에 대해서 이야기할 때 언급했듯이 제 머신에는 Vulkan 을 지원하는 카드가 하나밖에 없기 때문에 "Geforce GTX 980" 만 잡힙니다. 


일단 피지컬 디바이스를 획득하면 거기에서 피지컬 디바이스의 속성과 기능 등을 획득할 수 있습니다.



이 정보들은 CapsViewer 에서 확인할 수 있으며 아래와 같이 대응됩니다.

  • deviceProperties 는 "Limits" 에 대응합니다.
  • deviceFeatures 는 "Features" 에 대응합니다.
  • deviceMemoryProperties 는 "Memory" 에 대응합니다.



QueueFamily 정보도 피지컬 디바이스에서 가지고 오는 것이긴 한데 나중에 따로 언급하도록 하겠습니다.


Physical Device Group


Vulkan 은 1.1 부터 여러 개의 GPU 를 응용프로그램에서 사용하는 기능을 제공합니다. 


[ 3 ] 에 따르면 제조사( vendor )에 중립적( neutral )이라고 합니다. 예전의 SLI 나 Cross-Fire 는 드라이버가 각 GPU 에 태스크를 분배하는 방식이었지만, Vulkan 은 이를 개발자가 할 수 있도록 지원한다고 합니다. 그리고 여기에 사용되는 피지컬 디바이스들은 디바이스 그룹이라는 개념으로 묶여 하나의 로지컬 디바이스로 관리된다고 합니다.


안타깝게도 제 머신의 Intel 카드가 Vulkan 을 지원하지 않아서 테스트는 못 해 봤지만 제조사-중립적인 기능이라니... 정말 혁신적인 것 같습니다.


정리


머신에는 여러 개의 그래픽스 카드가 존재할 수 있으며, Vulkan 은 ICD 를 통해서 그 장치들을 열거하고 거기에 접근할 수 있습니다. 이러한 그래픽스 카드들은 VkPhysicalDevice 로 표현되며, 그것을 통해서 피지컬 디바이스의 여러 가지 속성과 기능들을 열거할 수 있습니다.


일단 피지컬 디바이스를 선택하면, 이제 실제로 사용할 로지컬( logical ) 디바이스를 생성할 준비가 된 것입니다.


참고자료


[ 1 ] Architecture of the Vulkan Loader Interface, LUNAR XCHANGE.


[ 2 ] Vulkan 1.1 Specificiation, Khronos.


[ 3 ] Vulkan 1.1 out today with multi-GPU support, better DirectX compatability, ars TECHNICA.

+ Recent posts