brunch

You can make anything
by writing

C.S.Lewis

by 상윤 May 16. 2024

D3D12 Barrier 1. 서론

'D3D12 배리어'라는 이름의 지옥

개발한 지 벌써 몇 년이나 지났음에도 아직까지 불분명한 부분이 남아있어서 정복이 안 되는 녀석이 있으니 그 이름 배리어 되시겠다. 특히나 D3D12에서의 배리어는 다른 모든 것들 중 으뜸으로 쳐야 하는데, DirectX라는 대중성을 휘어잡은 이름을 상속한 주제에 그 API 명세는 전혀 구체적이거나 명확하지 않아서 쓰는 이로 하여금 징검다리를 건너는 기분을 맛보게 하기 때문이다.


개인적으론 특정한 API 하나에 대해 정리하는 글은 딱히 쓰고 싶지 않았다. 하지만 D3D12는 항상 쓸 때마다 고통을 안겨주는 한 편 그때 필요한 정보들을 매번 다시 찾는 것도 시간낭비니 한 번쯤 정리해둬야지 싶어졌다. 그리고 나중에 필요할 때 나도 다시 참고하기도 하고 말이지.


때문에 내 개인적인 의견들을 기술하기에 앞서 이 글은 명세에 기술된 직접적인 원문을 우선 인용하고 첨언하는 방식으로 쓰일 것이다. 그리고 그에 이견이 있으신 분들은 쉽게 원문으로 참고하실 수 있게 링크 연결을 바로 덧붙여두겠다. 이 글은 GPU를 이용한 렌더링, 특히 D3D12를 이미 접해봤음을 가정하고 대부분의 용어 설명을 생략할 것이다. 또한 읽는이가 컴퓨터의 메모리 계층에 대한 이해가 있으며, 적당 수준의 GPU의 동작 원리도 어느 정도 갖고 있길 기대하며 써내려갈 것이다.


시작에 앞서

D3D12를 처음 시작한다고 가정해 보자. 어디서부터 시작해야 하는가? 바로 Microsoft 공식의 D3D12 명세다. 거기서부터 읽어 내려가면 이게 공식 문서가 맞나 싶을 정도로 불친절한 것을 알 수 있다. 갑자기 튀어나온 수많은 새로운 용어들이 있는데 그것에 대한 구체적인 정의가 어디에 제대로 쓰여져 있지 않은 것이다. 그나마 용어집에서 각각의 용어들을 정의하긴 하는데, 말 그대로 용어집에 불과한 만큼 이 문서 전체에 걸쳐서 사용할 단어들을 간단히 설명할 뿐 세부 정의는 존재하지 않는다.


예를 들어, 배리어의 용어집 상 설명은 다음과 같다.

resource barrier

A resource barrier notifies the driver that synchronization of multiple accesses to a single resource may be required, for example, reading and writing to the same texture.


그렇다면 구체적인 정의가 공식 명세 중에 있어야 할 것이라 생각할 수 있지만, 막상 처음으로 배리어를 주제로 다루는 장을 읽어보면 핵심을 비껴가는 설명들로 주를 이루고 있다. '리소스 당 상태' 관리의 책임을 우리에게 넘겼고, 우리는 그 상태라는 걸 관리하기 위해 배리어를 사용할 수 있다며 문서를 시작한다.


그런데 내가 '리소스 당 상태'라는 개념을 이전에 언급한 적이 있던가? 위에서 적당히 GPU 동작 원리 정도는 알길 바란다며 글을 시작했으니 그런 단어는 상식처럼 받아들여져야 하는 것으로 느껴졌을 수 있다. 혹은 앞서 용어집에서 배리어라는 것을 'resource barrier'라는 용어로 설명했으니, 리소스라는 게 배리어와 엮인다는 것 정도는 예측했을 수도 있겠다.


하지만 '리소스 당 상태' 라는 표현은 지금 여기서 처음 언급한 것이 맞다. 나도 어디 다른 API서 본 적 없고 D3D12에서 새로 나타난 용어다. 그런데도 공식 문서가 이런 식으로 새로운 용어들을 만들어내서 설명하고 있다. 리소스에 상태라는 것이 존재한다는 사실을 정의로부터 알게 되는 것이 아니고, 용어집에도 없어서 여기서 처음 마주친다. 그럼에도 '이거 알지? 너희가 이제부터 다루는 거야, 알겠지?' 하며 시작하는 꼴이다.


이것이 앞으로 마주칠 D3D12 명세라는 것의 실체로, 용어집에 없는 용어가 튀어나오는 일이라든가, 동작 정의가 불분명한 일은 앞으로도 흔할 것이다. 지난 세월의 나는 이걸 받아들이지 못해서 쉽게 화를 내고 분통을 터뜨려야 했지만 이젠 자연스럽게 그러려니 하고 넘어가게 됐다. 여러분도 빨리 받아들이는 것이 정신 건강에 도움이 될 것이다.


본격적인 시작 전에 하나 더, D3D12에는 배리어를 치는 두 가지 방법의 API 집합을 제공한다. 둘 중 더 최근에 공개된 쪽은 Enhanced Barrier라는 이름으로 발표되었고, 그에 대비해 이전 명세 상의 배리어를 Legacy Barrier라 칭한다. Legacy Barrier 쪽을 이후에 폐기시킬 계획은 또렷하지 않아 보이고, 오히려 Legacy 쪽과의 호환에 대한 구체적인 방법은 잘 마련되어 있다.


Enhanced Barrier가 새로 제안된 배경은 그 명세의 도입부에서도 언급되었듯, Legacy Barrier 명세의 불분명한 부분들과 여러 혼란스러운 부분들을 좀 더 명확히 하고 한계를 보완하기 위한 것이다. 일종의 패치인 샘인데, 그 형식은 또 다른 API인 Vulkan에서 익히 봐온 것과 유사한 방식을 취하고 있다. 자체적으로 설계한 칩을 사용하고 그 위에 직접 API까지 마련해서 제공하는 Apple이나, Sony에 비하면 취급해야 할 장치가 비교적 산만한 편인 PC환경이라 그런지 대체로 API의 생김새는 더욱 복잡해진 것처럼 보인다. 물론, 여전히 Mobile GPU 상에서의 특화 구현까지 신경 써야 하는 Vulkan의 복잡함에 비할 바는 아니다.


구체적으로 Legacy Barrier에선 Resource State라는 단조로운 개념을 사용하여 배리어의 범위를 설정하도록 하는데 리소스가 사용될 때 쓰이는 보편적인 명칭들을 일종의 상태로써 간략화하여 표현하였다. 그러나 너무 간략화한 덕분에 오히려 구체적인 동작을 너무 알 수가 없어 성능 하락으로 야기되기 쉬우며, 실제 기대하는 동작과는 다르거나 하나하나의 설명을 그 명세 자체만으론 이해하기가 어려운 면이 있다.


반면 Enhanced Barrier에선 동기화시킬 구간, 메모리의 접근 범위, 그리고 텍스쳐에 한해 놓인 메모리의 레이아웃을 변경하는 방법에 대해서 정확히 설정해야 하는 탓에 조작해야 할 값이 2~3 변수의 조합으로, 이전 Legacy의 방식에 비하면 복잡하게 느껴질 수 있다. 그 대신 언제, 어떻게, 무슨 일이 일어나는지에 대한 설명을 구체적으로 담고 있어 정확히 원하는 Barrier를 위해서 어떤 변수를 제어해야 하는지 이해하기엔 훨씬 낫다.


단순 비교만으로도 Legacy Barrier의 명세는 고작 A4 16쪽 분량이지만, Enhanced Barrier의 명세는 81쪽에 이른다. 계속 Vulkan 타령하기 뭣하지만, Vulkan에서 몇 백 쪽에 이르는 동기화의 대단원에 비하자면 아주 귀여운 수준이다.


D3D12의 개발자로써는 Enhanced Barrier가 등장한 이상, 앞으로의 개발에 Enhanced Barrier를 쓰는 쪽이 삶의 질과 인생의 방향이 더 나아지는 선택이겠으나, 혹시나 읽는이가 어떤 암초로 향하는 프로젝트에 승선하고 있을지도 모르니 구명정을 마련하는 양, 두쪽 모두를 살펴보기로 한다.


아래 써나갈 내용은 크게 4가지로 나뉠 것이고 다음과 같다.

Barrier Scope

Common Promotion/Decay

Compressed/Decompressed Layout

Multi-Queue Access


모쪼록 이 험난한 여정의 발걸음이 끝날 곳에선 D3D12 배리어로 고생하는 일이 없어질 수 있길 기대해 본다.

keyword
작가의 이전글 일기 4. 반갈 키보드
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari