처리중입니다. 잠시만 기다려주세요.
TTJ 코딩클래스
정규반 단과 자료실 테크 뉴스 코딩 퀴즈
테크 뉴스
Hacker News 2026.08.09 25

QEMU 윈도우 게스트에 DirectX 11을 붙이는 Triton, 어떻게 만들었나

Hacker News 원문 보기

가상머신에서 3D 그래픽 가속을 제대로 쓰는 일은 오랫동안 미해결 과제였다. 특히 QEMU 기반 환경에서 윈도우 게스트에 현대적인 GPU 가속을 붙이는 시도는 번번이 벽에 부딪혔다. 윈도우 그래픽 드라이버라는 분야 자체가 극히 좁고, 관련 전문가 대부분이 소수의 그래픽 하드웨어 벤더에 몰려 있어 참고할 오픈소스 구현이 거의 없기 때문이다. UTM 팀이 공개한 Triton은 바로 이 지점을 겨냥한 새 윈도우 드라이버로, 앞서 선보인 Neptune과 결합해 QEMU 가상머신에서 완전한 DirectX 11 지원을 구현했다고 밝혔다.

Neptune은 VirtIO 위에서 Direct3D 호출을 직렬화해 하이퍼바이저 경계를 넘겨주는 프로토콜 전달 계층이다. 이 팀은 앞선 작업에서 리눅스 게스트·리눅스 호스트 조합으로 Wine 게임을 돌릴 때, 게스트 안에서 DXVK를 직접 쓰는 것보다 Neptune 경유가 더 빠르다는 결과를 얻었다. 다만 그 자체가 극적인 성과는 아니었고, 진짜 목표인 윈도우 게스트 그래픽 가속을 위한 토대였다는 점이 이번 발표의 맥락이다.

왜 d3d11.dll을 갈아끼우는 방식으로는 안 되는가

가장 손쉬운 접근은 Neptune의 Mesa 드라이버가 만들어내는 d3d11.dll과 dxgi.dll을 게임 실행 파일 옆에 놓아 윈도우 기본 라이브러리 대신 로드시키는 것이다. 실제로 DXVK→Vulkan→Venus 경로를 쓴 이전 시도들이 이 방식을 택했고 일부 게임은 이렇게도 구동된다. 그러나 한계가 뚜렷하다. 데스크톱 컴포지터(DWM)가 렌더링 결과를 하나의 이미지로만 인식하기 때문에 GPU 버퍼를 창 위치로 옮기는 데 CPU 블리팅이 필요해 성능이 떨어진다. 전체화면이라면 네이티브 스캔아웃 요령을 부릴 수 있어도 매끄러운 데스크톱 경험은 얻기 어렵다. 게다가 d3d11.dll과 dxgi.dll은 윈도우 핵심 구성요소라 시스템 파일 자체를 대체할 수 없고, 이런 변조를 탐지하는 안티치트가 있는 게임은 아예 막힌다.

윈도우에서 애플리케이션은 시스템의 Direct3D·DXGI 라이브러리와 대화하고, d3d11.dll이 상태 추적이라는 복잡한 작업을 맡아 정제된 명령 스트림을 사용자 모드 드라이버(UMD)로 넘긴다. UMD는 DDI를 구현하며 DXGI를 거쳐 커널 모드 드라이버(KMD)와 통신하고, KMD가 실제 하드웨어(이 경우 가상 하드웨어)를 구동한다. Wine에서는 API 호출을 가로채는 커스텀 d3d11.dll·dxgi.dll을 만들면 됐지만, 윈도우에서는 UMD와 KMD를 직접 구현해야 한다는 것이 근본적인 차이다.

DDI를 다시 API로 되돌리는 역변환

KMD 쪽은 다행히 선례가 있었다. anonymix007과 arehnman이 각자 Venus(Vulkan)용 KMD를 만들고 있었고, Neptune이 Venus를 본떠 설계된 덕에 DMA·커맨드 버퍼 같은 커널 인터페이스와 UMD-KMD 사이 규약이 사실상 동일했다. 팀은 기능이 더 많이 동작하던 anonymix007의 브랜치를 기반으로 삼았다. 남은 어려운 과제가 DirectX 11용 DDI 구현이었다. 참고할 만한 것은 Mesa의 DirectX 10 UMD(Gallium 호출을 내보내는 방식)와, 유일하게 동작하는 오픈소스 DX11 UMD인 VirtualBox 구현 정도였다. 그러나 VirtualBox는 DDI를 중간 바이트코드로 바꾼 뒤 호스트에서 다시 DirectX API로 해석하는 구조라 번역 엔진의 버그가 게임 호환성을 갉아먹는 것으로 알려져 있고, GPLv3 라이선스가 virglrenderer의 MIT나 QEMU의 LGPLv2와 충돌해 코드를 가져올 수도 없었다. 대신 어떤 DDI 프로토타입을 구현하고 어떤 것은 오류로 되돌려야 하는지에 관한 목록과 DXBC 서명 알고리즘 같은 실무 정보만 참고했다.

Triton이 택한 방향은 DDI 호출을 다시 DirectX API 호출로 되돌리는 역변환이다. d3d11.dll이 API를 DDI로 바꾸는 계층이라면, UMD가 그 반대로 되돌려주는 셈이다. 이렇게 하면 이미 검증된 Neptune 프로토콜을 그대로 쓸 수 있고, 호스트에서는 역직렬화된 명령이 곧 DirectX 11 API 호출이라 별도의 해석기가 필요 없다. VirtualBox가 게스트의 에미터·전송 계층에 더해 호스트의 인터프리터·디스패처까지 요구하는 것과 달리, 변환 단계가 하나 줄어 오류 여지도 줄어든다. 대부분의 DDI 호출은 API 등가물이 있어 핸들 매핑이나 열거형 차이 조회 정도로 변환이 끝난다.

셰이더 바이트코드와 스왑체인이라는 함정

가장 복잡한 대목은 DXBC 셰이더였다. DXBC는 마이크로소프트 셰이더 컴파일러 FXC가 HLSL로부터 뽑아내는 DirectX 12 이전 IR 포맷이다. 역변환 구조 덕에 Triton은 이 바이트코드를 디스어셈블하거나 변환할 필요 없이 그대로 통과시킬 수 있어 복잡도와 호환성 면에서 크게 이득을 봤다. 문제는 FXC가 바이트코드와 함께 내보내 d3d11.dll이 소비하는 메타데이터가, DDI 호출 시점에는 넘어오지 않는다는 점이다. 원래의 DXContainer 파일을 볼 수 없으니 호스트 렌더러가 기대하는 필드를 바이트코드를 해석해 재구성해야 한다. 팀은 이 부분을 AI 어시스턴트의 시행착오로 처리했다고 밝히면서, 구현에서 가장 취약하고 오류가 잦은 지점이라고 솔직하게 인정했다.

스왑체인 처리 방식도 방향을 바꿔야 했다. 리눅스에서 Wine용으로는 DXVK를 포크해 스왑체인 이미지를 DMAbuf 리소스로 내보내고 스왑체인 로직을 호스트 쪽에 두었지만, 윈도우에서는 DXGI가 백버퍼 생성과 프레임 페이싱, 모드 전환을 맡는 시스템 구성요소여서 이 구조가 대부분 우회됐다. DWM은 공유 텍스처 위에서 동작하므로 DXVK에 DMAbuf 내보내기뿐 아니라 가져오기까지 구현해야 했고, 그 결과 호스트 측 스왑체인 로직은 불필요해져 모든 관련 처리를 게스트 Neptune 드라이버로 옮겼다. 이는 Venus 설계와도 더 가깝게 맞아떨어져 virglrenderer를 깔끔하게 유지하는 부수 효과를 낳았다. 다만 macOS 호스트는 여전히 과제로 남아 있다. Venus가 macOS에서 돌아가며 백엔드 난제 상당수가 정리됐지만, DirectX를 처리할 세 주요 프로젝트가 모두 Wine을 겨냥해 설계돼 Neptune·Triton이 요구하는 공유 텍스처와 공유 펜스 기능이 빠져 있다. 리눅스에서 잘 통하던 DXVK도 macOS에서는 MoltenVK가 Vulkan을 Metal로 다시 옮겨야 해 불안정하고 손이 더 많이 간다는 점이 남은 숙제다.

실무자 관점에서 이 프로젝트가 주는 함의는 분명하다. 가상화 환경에서 윈도우 게스트의 GPU 가속은 그동안 안티치트 문제와 컴포지터 병목, 참고할 구현의 부재라는 삼중고에 막혀 있었는데, Triton은 정식 UMD·KMD 경로를 밟으면서도 중간 번역 계층을 최소화하는 설계로 이 문제들을 정면 돌파했다. 동시에 셰이더 메타데이터 재구성처럼 여전히 취약한 지점과 macOS 지원의 미완성 상태는, 실제 도입을 검토할 때 호환성 편차를 감안해야 한다는 현실적 경계이기도 하다.

이 뉴스가 유용했나요?

이 기술을 직접 배워보세요

AI 도구, 직접 활용해보세요

AI 시대, 코딩으로 수익을 만드는 방법을 배울 수 있습니다.

AI 활용 강의 보기

"비전공 직장인인데 반년 만에 수익 파이프라인을 여러 개 만들었습니다"

실제 수강생 후기
  • 비전공자도 6개월이면 첫 수익
  • 20년 경력 개발자 직강
  • 자동화 프로그램 + 소스코드 제공

매일 AI·개발 뉴스를 받아보세요

주요 테크 뉴스를 매일 아침 이메일로 전해드립니다.

스팸 없이, 언제든 구독 취소 가능합니다.