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

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

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



저는 벌칸에 대해서 공부하면서 RenderMonkey 와 유사한 VulkanMonkey 라는 셰이더 편집 도구를 만든다는 최종 목표를 가지고 있습니다. 이 연구 시리즈도 그것을 구현하는 과정에서 발생하는 여러 가지 의문들에 대해서 스스로 답을 내면서 만들어지고 있는 것입니다.



하지만 프로젝트를 진행하다가 벽에 부딪히게 되었습니다. 기존의 D3D9 이나 OpenGL 과는 다르게 Vulkan 은 여러 개의 큐를 가질 수 있으며 커맨드들이 비동기적으로 실행될 수 있기 때문에, RenderMonkey 와 같은 TreeView 구조의 워크스페이스 관리는 비직관적입니다.


이 때문에 구조가 맘에 안 들어 디바이스 생성후 더 이상 진행을 못하고 있었습니다. 물론 마샬링 구조를 결정하는 문제 때문에 프로젝트를 3 차례나 엎고 다시 만드는 데 걸리는 시간이 꽤 길긴 했지만( 현재는 C# <--> C++/CLI <---> C++ 의 구조를 가집니다. 이 부분에 대해서는 나중에 한 번 공유하도록 하겠습니다 ), 그건 과거의 문제이고 미래로 나아가지 못하는 원인은 워크스페이스 구조였습니다.


그런데 오늘 갑자기 나아가야 할 방향이 떠 올랐습니다. 벌칸은 매우 높은 수준으로 파이프라인화되어 있는 API 입니다. 이미 이런 형태를 잘 반영하고 있는 도구들이 존재하고 있는데 삽질을 했다는 생각이 들었습니다. 그건 바로 Graphics Profiler 들입니다. 예를 들어 NSight Graphics 를 보면 다음과 같습니다.



Scrubber View 에서 큐당 커맨드의 흐름을 확인할 수 있습니다. 그리고 이벤트 뷰와 API 인스펙터 뷰에서 세부사항을 확인할 수 있죠.


VulkanMonkey 에서는 커맨드 단위가 아니라 렌더 패스 단위의 흐름을 파악할 수 있도록 만들면 되겠다는 생각이 들었습니다. 커맨드 버퍼 내부에서 동기화를 해야 하는 경우는 거의 없을 것이라고 생각하기 때문입니다.


그러면 아래와 같은 형태로 렌더 패스를 배치할 수 있습니다. 물론 실제 걸리는 시간은 알 수 없으니 적절히 너비를 사용자가 조정하게 만들어야겠죠. 아래 그림에서는 세마포어를 사용해서 "Light Accumulation" 렌더 패스가 시작되기 전에 "CSM3Depth" 렌더 패스에 대해 웨이트하도록 하는 상황을 상정했습니다. 물론 실제 구현 측면에서 보면, "Light Accumulation" 의 첫 번째 커맨드 버퍼를 Submit 할 때 Wait 를 하는 상황이겠죠.




그리고 각각의 렌더 패스의 인스펙터창에서는 세부적인 설정들을 할 수 있도록 하는 거죠. 이렇게 하면 전체적인 흐름을 볼 수 있습니다. 


여기에다가 특정 시점까지의 렌더 패스 실행 결과만을 실행할 수 있는 기능까지 추가하면, 프레임 디버거처럼 중간과정을 확인하는 것도 가능할 것입니다. 


좀 더 나아가면 렌더 패스 내의 커맨드 퍼버들까지 가시화해 줄 수 있으면 금상첨화라는 생각이 듭니다. 그러면 하나씩 그리는 과정도 추적할 수 있겠죠.


이제 좀 앞으로의 구현 방향이 잡히는 기분입니다. 물론 이런 UX 를 구현하려고 생각하니 끔찍하긴 하지만 말이죠.


더 좋은 아이디어가 있으면 댓글 남겨 주시면 감사하겠습니다.

+ Recent posts