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

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

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



VkInstance 를 생성할 때 VkApplicationInfo 라는 것이 필요합니다. 거기에는 ApiVersion 이라는 필드가 있습니다.



명세에서의 설명을 보면 다음과 같습니다.


apiVersion must be the highest version of Vulkan that the application is designed to use, encoded as described in the API Version Numbers and Semantics section. The patch version number specified in apiVersion is ignored when creating an instance object. Only the major and minor version of the instance must match those requested in apiVersion.


- Vulkan specification 1.1.96


이 필드에는 VK_API_VERSION_1_0 이나 VK_API_VERSION_1_1 을 넣게 됩니다. 이것은 다음과 같이 정의되죠.



그리고 VK_MAKE_VERSION 은 다음과 같이 정의되어 있습니다.



여기에서 문제가 하나 발생합니다. 제가 지금 제 로컬 머신에 받아 놓은 LUNARG Vulkan SDK 의 버전은 1.1.85.0 입니다. 그리고 LUNAR XCHANGE 에 가 보면 여러 가지 버전들이 있는 것을 알 수 있죠.



여기에는 버전 번호가 하나 더 있어 헷갈립니다. VK_MAKE_VERSION 은 3 개 항목을 입력으로 받는데요, 여기에는 네 번째 버전이 하나 더 들어 가 있습니다.


대체 이 버전들의 의미는 무엇이고, 왜 패치 버전은 사용하지 않는 것일까요?


Api Version



Vulkan 명세에 의하면, Vulkan API 는 세 개의 버전 정보로 정의되며 32 비트 정수 안에 패킹( packing )됩니다; Major, Minor, Patch.



이것은 명세의 버전과 동일합니다. Vulkan 명세에서는 각 버전에서의 차이점을 다음과 같이 설명하고 있습니다.


  • Major 버전에서는 API 셋들이 변경됩니다. 보통 새로운 기능과 인터페이스가 추가되며, 기능이 변경되기도 합니다. 그리고 기능이 없어지거나 수정되기도 하죠. 즉 하위 버전과의 호환성이 유지되지 않을 수 있습니다. 아직 1.1 밖에 안 된 상황이라 미래에도 이런 일이 벌어질 지는 미지수네요.

  • Minor 버전에서는 새로운 기능이 추가되고, 일부 기능들은 변경되거나 없어질 수 있습니다. 하지만 없어진 기능들을 위한 인터페이스는 그대로 유지됩니다.

  • Patch 버전에서는 명세나 헤더가 조금만 변경됩니다. 보통 버그때문에 변경되는 것으로서 하위 호환성이 유지되어야만 합니다.


그러면 LUNARG SDK 의 버전은 무엇일까요? SDK 버전의 처음 세 개는 Vulkan Api 버전과 동일합니다. 단지 같은 버전에 대해서 다시 패치할 때 마지막 버전을 넣습니다.


$(Major).$(Minor).($Patch).($LUNARG_Patch)


뭐 사람이 하는 일이다보니 실수가 없을 수는 없겠죠. Api 버전은 명세일 뿐이고 실제 구현은 다르기 때문에 이런 버전을 추가한 것으로 보입니다.


Comparing patch versions


그런데 왜 ApiVersion 을 넣을 때는 patch 버전이 무시되는 것일까요?


안타깝게도 Vulkan SDK 에서 배포하고 있는 라이브러리들은 이름에 버전정보를 담고 있지 않습니다. 그리고 헤더에다가도 버전 정보를 담고 있지 않죠; 예를 들어 "vulkan-1-1-85.lib" 같은 라이브러리나 "VkCreateDevice_1_1_85()" 같은 함수는 없습니다. 아마도 Dll Hell 을 피하기 위해 항상 가장 높은 버전을 사용하도록 하고 있는 것으로 보입니다. 심지어는 라이브러리 이름조차 major 버전만을 사용합니다; "vulkan-1.lib".


그러므로 VK_MAKE_VERSION 에서는 패치 번호가 무시됩니다. 


제가 처음에 Api Version 을 입력할 때는 이걸 모르고 있었습니다. Api Version 에 patch 버전을 넣을 수 있길래 버전별로 그 결과를 비교할 수 있겠다 싶어서, 다음과 같이 만들었는데 쓸데 없는 짓이었군요.



만약 LUNARG SDK 의 1.1.85.0 버전에서 발생하던 버그가 1.1.92.1 버전에서 해결되었는지 알고자 한다면, 두 개의 SDK 를 모두 깔아 놓고 "VULKAN_SDK", "VK_SDK_PATH" 등의 환경변수를 변경해 가면서 테스트하는 수밖에 없습니다.


환경변수 설정을 batch 파일 등을 통해서 동적으로 제어할 수 있으면, 결과를 비교하는 더 나은 개발 환경을 만들 수는 있을 것 같습니다.

+ Recent posts