커뮤니티를 살펴보면 종종 “D3Dx.dll과 dxgi.dll 라이브러리를 교체하면 게임 프레임이나 스터터링(Stuttering)이 개선된다”는 글을 찾아볼 수 있습니다. 실제로 길드워나 마비노기 영웅전과 같은 일부 타이틀에서는 그 효과가 벤치마크를 통해 증명된 바 있습니다.
최근 제가 즐겨하는 마비노기에서도 DXVK를 적용했을 때 체감 성능이 향상되었다는 흥미로운 후기들을 여럿 접하게 되었습니다.
다만 제가 이해하기로 플레이오네 엔진의 핵심 병목은 GPU의 처리 성능이라기보다는 엔진 구조에서 비롯되는 CPU 측의 Single-thread bottleneck에 더 가깝다고 생각했습니다. 따라서 Graphics API 교체만으로 근본적인 성능 개선을 기대하기는 어려울 것이라 판단했습니다.
때문에, 단순히 체감적인 부분에 머무르지 않고 객관적인 현상을 파악하고자, 직접 모니터링 로그를 수집하여 두 환경의 실측 데이터를 비교 및 분석해 보았습니다.
1. 테스트 환경 및 방법론
보다 정확하고 재현 가능한 비교를 위해 Frame time과 Presentation path를 로그로 남겼습니다.
- 측정 도구: Intel PresentMon
- 시나리오: 마비노기 던바튼 5채널 광장(오브젝트·캐릭터 밀도가 높은 구간), 백그라운드는 모니터링 툴만 존재, i5-14500HX + RTX 4060 laptop
- 절차: Native DX9과 DXVK 적용 상태에서 동일 위치에서 시작해 동일 동선으로 이동하며 동일 조건으로 기록
2. 벤치마크 결과 (실측 데이터)
Intel PresentMon을 활용하여 Native DX9 상태와 DXVK 적용 상태에서 각각 30초씩 측정 후 추출한 실측 CSV 데이터의 비교 결과입니다.
수치적으로 살펴보면 순정 상태 대비 Average FPS는 약 29% 하락, 5% Low FPS는 약 21% 하락, 1% Low FPS는 무려 약 42% 하락했습니다. 1% Low FPS가 낮아질수록 유저가 체감하는 Stuttering(스터터링, 끊김 현상)이 급격히 증가하는데, 수집된 로그에서도 DXVK를 적용했을 때 Low percentile의 프레임 저하가 두드러짐을 확인할 수 있었습니다.
3. 결과 해석 (기술적 관점)
일반적인 DX9 기반 게임에서 DXVK가 성능상 이득을 제공하는 경우는 보통 Driver 및 Runtime 경로의 비효율성이 전체 파이프라인의 병목이거나, GPU 자원에 여유가 있어 CPU 단의 오버헤드를 상쇄할 수 있는 환경일 때 나타납니다. 하지만 마비노기의 경우는 반대로 다음과 같은 구조적 요인들이 겹쳐 역효과가 났다고 볼 수 있습니다.
Graphics Pipeline 관점에서의 비교
한 프레임을 화면에 렌더링하기 위해서는 애플리케이션이 Graphics API에 명령(Draw call 등)을 쌓고 → Driver와 Runtime이 이 명령들을 GPU 큐(Queue)로 넘긴 후 → GPU가 최종적으로 명령을 실행하는 반복적인 과정이 필요합니다. 여기서 핵심은 단순히 “GPU 성능이 높다”가 아니라, CPU 측에서 매 Frame마다 API 및 Driver와 Sync(동기화)를 맞추고 Command Buffer를 빌드하는 과정이 Frame budget(프레임을 그려내는 데 할당된 시간)을 얼마나 소모하느냐입니다.
- Native DX9 경로: Windows 환경에서 제공하는 D3D9 → DX9 User-mode driver stack → Kernel scheduler → GPU로 이어지는, 수십 년간 튜닝되어 온 기존 경로를 그대로 거칩니다.
- DXVK 경로: 게임 클라이언트가 뱉어내는 동일한 D3D9 계열의 API 호출을 받은 직후, 이 **D3D9 명령어들을 Vulkan API call & submit으로 번역하는 Translation layer(번역 계층)**가 중간에 삽입됩니다.
즉, 전체적인 Pipeline 상에서 CPU가 처리해야 할 단계적 부담이 증가하며, Main thread(메인 스레드)가 이미 쉴 틈 없이 돌아가는 환경일수록 이러한 추가 오버헤드가 극명하게 Frame time 지연으로 반영됩니다.
아래는 두 처리 경로를 Logical blocks로 단순화하여 도식화한 다이어그램입니다 (실제 구현 및 Threading 모델은 드라이버 및 운영체제 버전마다 상이합니다).
flowchart LR subgraph nat["순정 Native DX9"] direction TB n1["엔진 / 게임 로직"] --> n2["D3D9 API"] n2 --> n3["DX9 Runtime · User driver"] n3 --> n4["Kernel scheduler / GPU"] end subgraph dxvk["DXVK"] direction TB v1["엔진 / 게임 로직"] --> v2["D3D9 API"] v2 --> v3["DXVK Translation · Vulkan build"] v3 --> v4["Vulkan Driver"] v4 --> v5["Kernel scheduler / GPU"] end
PresentMon 모니터링이 제공하는 지표는 단순한 GPU의 렌더링 속도뿐만 아니라, 의도된 명령이 렌더링을 거쳐 실제 출력 장치(디스플레이)까지 나타나는 전체 과정의 End-to-end delay를 반영합니다. 따라서 CPU 측에서 처리 단계가 추가됨에 따라, GPU Usage(사용률)가 동일하게 유지된다 하더라도 Average FPS 및 Low FPS가 동반으로 악화되는 현상이 나타나는 것입니다.
① Main thread & Translation overhead
통상적인 게임 환경에서의 프레임 드랍은 CPU가 Graphics API와 동기화를 시도하거나 Driver 경로에서 병목을 유발해 발생하는 Stall(대기 상태) 과 밀접한 연관이 있습니다. 이런 경우 DXVK를 통해 DX9 호출을 Vulkan 환경으로 추상화하여 오버헤드 구조를 비틀었을 때 성능적으로 이득을 볼 수 있습니다.
그러나 플레이오네 엔진은 게임 씬 처리, 스크립트 실행 연산, Physics(물리) 등의 집중적인 로직 수행으로 인해 이미 특정 단일 코어의 Main thread 점유율이 한계 수준에 다다르는 특징이 강합니다. 이런 상황에서 DXVK의 실시간 API 명령 번역 및 Submit 경로 등의 부담이 CPU 코어에 추가 할당되면 정해진 Frame budget 내에서 Rendering을 위한 CPU 연산과 기존의 클라이언트 게임 로직이 서로 자원 경쟁을 벌이게 되어 치명적인 프레임 페이싱(Frame pacing) 문제로 터져 나옵니다.
② Shader compile에 따른 Micro-stuttering 단점
1% Low FPS 구간에서 두 배가량 큰 폭락세를 보인 현상의 가장 직관적인 원인으로는 실시간 Shader(셰이더) 변환 및 컴파일 동작을 꼽을 수 있습니다.
기본 Native 경로에서는 미리 최적화된 Cache 및 Pipeline 상에서 흡수하고 지나가던 비용들이, DXVK를 통하게 되면서 뷰포트 내에 **새로운 파티클, 이펙트, 메쉬 등의 Draw call이 나타나는 순간마다 SPIR-V 중간 코드로 변환 및 컴파일(Compile)**되는 막대한 지연 시간으로 직결될 확률이 높습니다. 이는 결과적으로 짧은 시간 단위에 집중적인 Frame time spike(순간적인 렌더링 지연 수치 폭증) 현상으로 표출되었음이 로그에서 증명됩니다.
물론 DXVK의 셰이더 캐시가 충분히 구축된 이후에는 이러한 스터터링이 일부 완화될 수 있으나, 초기 구동이나 새로운 이펙트가 등장할 때마다 발생하는 치명적인 프레임 드랍 구조 자체를 피하기는 어렵습니다.
③ 1% Low Frame에 대한 시스템 수준 가설
측정된 1% Low FPS의 급격한 하락과 프레임 타임 스파이크가 어떤 단일 병목에서만 비롯되는지는, PresentMon 수준의 로그만으로는 좁히기 어렵고 GPU·CPU 타임라인을 포함한 심층 프로파일링이 추가로 필요합니다. 그럼에도 불구하고, 시스템 아키텍처 관점에서 다음과 같은 복합적 원인 후보를 가설 형태로 정리해 볼 수 있습니다.
- DXVK 번역 및 셰이더 컴파일 경로(②와 연계): 새로운 Draw call이 유입될 때 SPIR-V 변환·파이프라인 컴파일이 끼어들면서, 그 처리가 특정 구간에서 단일 논리 스레드(또는 이에 긴밀히 동기화된 경로)에 부하를 집중시켰을 가능성. (②에서 서술한 Micro-stuttering 메커니즘과 같은 축입니다.)
- 레거시 엔진 로직과 현대 그래픽 스택의 상호작용: 과거에 고정된 D3D9 시대의 상태 전이·드로 순서가, Vulkan 측 드라이버·IR 최적화가 가정하는 사용 패턴과 어긋나 번역·제출 경로에서 오히려 최적화 여지를 줄이는 형태로 동작했을 가능성.
- OS·런타임 차원의 스케줄링·동기화 비용: 번역 계층이 끼어들면서 DXVK·드라이버·커널 사이에 추가 스레드·펜스·큐 동기가 늘고, 그에 따른 컨텍스트 스위칭이나 대기 구간이 CPU 예산을 더 압박했을 가능성.
- 드라이버·벤더별 경로 의존성: 본 테스트는 NVIDIA 드라이버 + 해당 노트북 GPU 조합에 한정됩니다. 동일한 SPIR-V·파이프라인 부하라도, 드라이버 버전·내부 최적화·게임 프로파일 유무에 따라 지연 분포가 달라질 수 있으며, “특정 클라이언트가 생성하는 IR을 항상 최적으로 처리하지 못한다”는 식의 환경 의존적 가설로만 두는 것이 타당합니다.
위 항목들은 상호 배타적이지 않고 동시에 기여했을 수 있으며, 실제 기여도는 추후 프로파일링으로만 줄일 수 있습니다.
4. 결론
요약하자면, 위에서 **실측으로 확인한 지표(①·②)**와 ③에서 가설로만 열어 둔 시스템 수준 후보를 함께 고려할 때, 마비노기와 같이 구형 엔진 특유의 Single-thread bottleneck을 가지고있는 게임에서는 Graphics API Wrapper가 성능 향상을 보장해주지 않습니다.
새로운 레이어가 개입하면서 발생할 수밖에 없는 Translation, Sync, Compile overhead 요소들이 코어를 괴롭히면, 최저 프레임 방어는 고사하고 Average 및 Low percentile이 동반 추락하는 역효과를 볼 수 있습니다.
직접 측정한 현 환경과 테스트 시나리오 조건에서 살펴본 바에 따르면, 마비노기는 순정 상태의 Native DX9 구동이 벤치마크상 Average 및 Low percentile 지표 모두에서 훨씬 더 안정적인 성능을 보였습니다.
결론적으로 “마비노기에 DXVK를 복사해 넣으면 프레임 증가와 렉이 없어진다”는 말은 실제로는 그렇지 않을 확률이 높습니다. 따라서 맹목적인 도입보다는, 본인의 하드웨어 환경에서 직접 모니터링 툴을 활용해 실측 데이터를 확인한 후 적용 여부를 판단하시길 권장합니다.
끝으로 덧붙이자면, 현재로써는 DXVK 패치로 인해 직접적인 제재 내역(밴)은 보고된 바를 찾지는 못했습니다만, 기술적으로 클라이언트 변조 행위에 위배되므로 필자는 권장하지 않습니다.