Support us on Patreon to keep GamingOnLinux alive. This ensures all of our main content remains free for everyone. Just good, fresh content! Alternatively, you can donate through PayPal. You can also buy games using our partner links for GOG and Humble Store.
We do often include affiliate links to earn us some pennies. See more here.

A discussion on Native vs DXVK for Linux gaming

By -

With the recent work on "Proton" by Valve, and the ability to use DXVK with Wine prefixes outside of Steam, there has been intense interest in the performance of running games through Wine compared to native titles. I use the word "native" here loosely: it is intended to mean any game supported as running directly under a GNU/Linux system, and can include anything compiled directly for a GNU/Linux system, eON (Virtual Programming's porting tech), or games packaged with Wine itself (none of which yet include DXVK).

That some titles perform better, from an FPS number perspective, when using DXVK is clear, which has lead to some people asking why this is the case. It's the why that I'd like to discuss here; why DXVK is a winner in some cases, why native wins in others, and some of the drawbacks of each approach.

Please note that this wall-o-text is aimed at the less programmer-savvy crowd, but I welcome any comments from those with more experience on the matter as well. This is a discussion after all, not an attempt at a definitive guide.

For those that don't know, DXVK (in my opinion, a rather excellent project) is an implementation of DirectX 11 (and DirectX 10) built atop Vulkan, for use with Wine. Valve package Wine, DXVK, and some additional patches, together under the name of "Proton", but here I will stick to Wine+DXVK, or simply DXVK, to show that its use is not tied to Steam.


DXVK Performance

In many cases, DXVK will perform better than a native port. Why? After all, a native port shouldn't have any translation overhead. The short answer is: native ports often use OpenGL. That doesn't really explain much of course, but it's important to note that DXVK is built on Vulkan, and so using DXVK will run the rendering of a game ultimately through the Vulkan API, in order to mimic DX11. Many native games use OpenGL instead, although this is slowly changing and will be discussed later, but are ports of something originally designed around Windows and DX11. So the question of Native vs DXVK can at least partially be considered in terms of OpenGL vs Vulkan capabilities, and how each is used to behave like DX11.

 

Multithreading

The elephant in the room is, of course, OpenGL's lack of API level multithreading. I've written about this before, but the short version is that OpenGL is designed to run on a single thread: texture loading, shader generation, render command submission, all is intended to run from a single thread from the perspective of the OpenGL interface. While drivers might attempt to be clever behind the scenes, the application itself (the game engine) must consider it only as single threaded, and with mostly synchronous calls. As an example, to prepare a shader in OpenGL there might need to be first a file loaded, OpenGL resources created, then text passed into OpenGL to be compiled, OpenGL internal resources filled, additional information added (to be more specific, multiple shader objects linked together into a shader program), any errors checked for and handled, and then the shader can start to be used (which itself can take multiple steps to tell OpenGL what data to use with the shader!). And then maybe a texture can be uploaded. And then something else, and so on. This is typically done sequentially, and while there are ways of attempting some of it in parallel using OpenGL, it's unstable at best.

Compare this to Vulkan, where the resources for shaders can be allocated while loading files, the shaders are partially compiled to begin with, render commands can be constructed in the meantime in another thread, and data transfers to the GPU can be running while that's all happening. It's easy to see here that multiple tasks can be done in parallel; this isn't limited to loading resources, but can also be used with tasks that must be performed every single frame. If the developer really wishes to, then of course Vulkan can be made to run single threaded, but there's little point to requiring that.

This ability of Vulkan to separate out tasks that can run in parallel more easily, makes it far more suitable to running game engine code in a manner more closely resembling DX11.


Code Flow and Features

Vulkan is often called a low-level API. More importantly (and perhaps accurately), it is an explicit API (the developer must tell it very precisely what it should do), and it matches against modern hardware architectures far more closely than OpenGL. This makes Vulkan somewhat flexible in how it is used; difficult to learn perhaps, but adaptable, meaning that how data is handled, how and when GPU resources are allocated, etc, can be made to more closely match DX11. Remember that original games are often written with some variant of DirectX in mind, not OpenGL, and so being able to convert a game engine's logic pathways into something running on GNU/Linux requires fewer hoops to jump through when using Vulkan. This is a big benefit when using DXVK; perhaps some data can be copied directly into GPU memory using Vulkan, whereas OpenGL might need to copy it multiple times, with a bit of converting in between, to achieve the same effect (obviously a slower approach, impacting performance).

Recent versions of OpenGL more or less reach feature parity with DX11, but that can't always be guaranteed, and native games might have been developed before that time. DX11 might be used with an original game, but OpenGL 3.3 used on a GNU/Linux port. Lack of directly translatable features (Compute shaders, for example) only make the ability to use older OpenGL versions to emulate DX11 that much more difficult, and with less performance. DXVK is of course much newer and can take advantage of graphics capabilities that simply weren't available under GNU/Linux when the native port was created. This is an important point: a native port might be well done for the time it was created, but hampered by the graphics interfaces available at the time.


Porting and Effort: OpenGL

Note that prior I mentioned that DXVK is essentially an implementation of DX11, and so it has been a comparison of how Vulkan and OpenGL can be used to work like DX11. The question that can then be asked is: why not rewrite the game to behave more like OpenGL instead? Technically, this would narrow much of the performance gap if it could be done right. OpenGL still suffers from lack of multithreading capabilities, but engines could be designed to minimise the impact of that. The practicality of the situation is, however, that time and effort is required, and rewriting a game engine is no simple feat, if feasible at all. Whatever works to get it shipping is often the best call that can be made.
If the game can start with OpenGL, then it makes it somewhat easier to have performance parity between platforms, however for a long time some of the desirable features that developers wanted were simply not available. OpenGL based code pathways lost out to DirectX, and so much of the work in getting a game to GNU/Linux has been porting after it's been developed to run on Windows.

Factor in developer experience afterwards: there are likely more developers familiar with DX11 than with OpenGL when it comes to game development, at least outside of the indie space.


Porting and Effort: DXVK

Running through Wine, DXVK does not require a particular game to have been ported to GNU/Linux. There's no real porting effort behind the game - the effort is behind a DX11 implementation. Comparisons become a case of looking at DX11 implementations, not game engine changes. This can be both good and bad: the game will come with whatever quirks it has on Windows, and relies on DX11 behaving correctly, but it also means that new quirks are not introduced. The focus of more experienced programmers on a single task (a DX11 implementation) benefits multiple games, rather than each game needing a porting team.


DXVK Drawbacks

Up to now I've perhaps made it sound like DXVK is some wonderland that will always defeat a native port. This is not the case, something I daresay is best illustrated by Feral's work on Rise of the Tomb Raider. The focus of native benefits here is primarily when using recent graphics technology (i.e Vulkan) - while not technically a requirement, in all practical scenarios it will be the case.


Generic

DXVK is generic. It's an attempt to provide an implementation that many games can directly use. This does come with drawbacks (the extent of which can be debated, but they are drawbacks nonetheless). Game specific optimisations are either more difficult, or more limited in scope, with DXVK. Native titles can carry these optimisations further: customise shaders to better suit Vulkan, perhaps texture formats can be changed, or even the threading capabilities further enhanced (remember that Vulkan is newer than DX11). DXVK must also try to support all features of DX11. Native titles do not. This might result in some graphical differences, but can also mean performance is much superior on a native port (if done right), or indeed that a native port will work at all where DXVK will not.

There's another area that causes quite a bit of stutter either initially with DXVK, or always within a game: resource construction. In terms of Vulkan, this will mostly apply to shaders and "pipelines". While shaders are more commonly known about, a pipeline is a data object that describes to Vulkan how rendering will occur: what shaders are going to be used, what hardware features will be needed, the types of resources that will be provided, the format of the resources, and so on. A pipeline contains all that information in one object, but if any of the information were to change, then a new pipeline object must be constructed. This is a very simplified explanation of course, but constructing a new pipeline is relatively expensive, and it's not normally known ahead of time. The same principle with shaders: constructing them and getting them ready is not known ahead of time, particularly with DXVK. Various mechanisms exist to cache them once built, so that later times running through the game they can be loaded much faster, but they must still be loaded at some point, and ultimately cannot be used until they are.

This construction of resources can have an impact on game performance. DXVK cannot tweak a game to attempt to hide the delay of this construction process, where as a native port can (with sufficient developer effort). It's worth noting that the impact of this is going to be highly game specific, and may need quite a bit of developer effort.


Developer Experience

As mentioned earlier, developers for larger titles will likely have more experience with DX11 than with OpenGL. This lack of experience in OpenGL means those older titles may have not been written in quite an efficient manner. I've personally looked across the API calls for various games and been aghast at what was done. The reality is that time available, developer experience, testing resources, etc, have simply been nowhere near what is needed for a quality port. In one particular case, given the effort that was required of a couple of developers, I'm amazed they had anything running at all in the time available!

Ultimately, however, this does mean that DXVK is benefiting from more time, effort, testing, and experience than those developers could hope to give to a native port, especially comparing OpenGL to DX11.

This is perhaps changing with Vulkan, and may not represent the state for newer ports where it is used. Feral, Croteam, Valve, and others, have shown that native titles using Vulkan directly can perform very well going forward. If DX11 is not used for a game, but Vulkan is directly used instead, then of course DXVK no longer becomes applicable.
DXVK of course will continue to benefit older titles, so this ends up being a win-win for gamers.


Stability

I've mostly looked at performance up until now, but a game that crashes most of the time probably isn't as good of an experience as one that performs less, but is more stable.

OpenGL in particular has a few areas of ambiguity. It lacked, and still lacks to a degree, formal driver test suites. Microsoft on the other hand controlled the quality of DirectX far more directly, and it's hard to argue against the documentation, examples, developer tools, and overall resources that Microsoft have supplied to developers for DirectX. This has lead to not only developers being able to test, debug, and tweak their code with more confidence on a Windows platform, but arguably driver quality (performance and stability) being higher for DirectX than for OpenGL. This in turn has invariably affected the quality of native titles on GNU/Linux - the effort required to ensure a game working across multiple hardware and software configurations has been traditionally quite high. DXVK can actually be more stable in some cases simply because it can rely on more thoroughly tested drivers.

Stability is a double edged sword though - DXVK relies on the stability of Wine itself, and naturally on the stability of the original Windows game. My own personal opinion on the matter is that this depends on the game: with older titles, Wine+DXVK might end up being more stable, but newer titles might give that edge to a native port.

It's worth noting that stability is something Khronos have been trying to improve with Vulkan. Driver test suites are available, validation layers for Vulkan are invaluable to a developer, documentation and tutorial resources are actively being worked on, and the standard of Vulkan itself improves with feedback from developers and the community. This all helps DXVK, but also makes the ideal situation being that DXVK is not required for new games if they can use Vulkan directly to begin with.


The Future

Graphics APIs are changing. DX12, Vulkan, and Metal, are slowly encroaching on the older interfaces, giving more capabilities to developers. But these changes take time, and game engines will need to adopt the new technologies. DX11 in particular is still heavily entrenched in a lot of game development, and many games released today will likely have DX11 support. This makes DXVK relevant for some time to come, with both newer titles and the vast catalogue of older games.

GNU/Linux systems are also constantly being changed. New library versions are released, new hardware supported, new APIs developed. Games are not indefinitely supported, and may not work with a new kernel, new driver, new glibc. Like with dos games now running on DOSBox, Wine provides a way for such games to continue to be played, and with software such as DXVK, played without a drastic performance loss.

Equally, continued changes mean new games natively supported on GNU/Linux benefit from newer versions of OpenGL, and of course Vulkan. Improved driver quality from all vendors when compared to even a handful of years ago has made gaming much more enjoyable. Wine+DXVK and native games can quite happily coexist. On a personal note, I like that there's even discussion of which approach runs better - it shows that games now run, and can run well on Linux.

Article taken from GamingOnLinux.com.
Tags: Editorial
44 Likes
The comments on this article are closed.
7 comments

Nevertheless Feb 5, 2019
Reading this I just remembered something that I think fits the article.

Two years ago I asked the Croteam devs in the Steam forums if they could tell me why I could see only one CPU core going up to 100% and all the others staying at 25% ( https://steamcommunity.com/app/257510/discussions/0/135509024341635313/?ctp=2#c135509823661294050 ), while I was playing the Vulkan version of The Talos Principle, but still the performance was way better than the OpenGL version. I got answer:

"AlenL [developer] 23 Feb, 2017 @ 7:23pm
You are getting 100% CPU load because the CPU is not stalling and waiting for GPU. But you are getting better performance because it uses less cycles to generate rendering commands on Vulkan. That's completely logical.
You are not seeing additional core performance because we haven't implemented native multithreading on Vulkan in that build yet. We have that in the works, but it is not yet ready for release. So your Vulkan and OpenGL are running same threading engines for now."

and

"But nowadays, most games are more limited by CPU overhead. Hence Vulkan."

So even single threaded Vulkan is much more efficient than OpenGL. I guess DX11 performance might come single threaded Vulkan close.
YoRHa-2B Feb 5, 2019
Quoting: NeverthelessSo even single threaded Vulkan is much more efficient than OpenGL. I guess DX11 performance might come single threaded Vulkan close.
Vulkan draw calls and friends are, for the most part, dirt cheap. There's very little (but still some) state tracking going on in the driver, and you as an engine developer can build thin abstractions that fit your needs, again with minimal state tracking, rather than using an overly generic abstraction that ends up doing way more than you actually need, and doesn't necessarily do it well, both in terms of CPU and GPU performance.

Unfortunately, the latter still seems to be a common pitfall, and we end up with games that run significantly worse on D3D12 than they do with D3D11, even when CPU limited. Latest prominent example of that being Resident Evil 2, which runs faster with D3D11->Vulkan translation than it does with their native D3D12 renderer on Windows. And that just shouldn't happen.


Last edited by YoRHa-2B on 5 February 2019 at 12:07 pm UTC
Nevertheless Feb 5, 2019
Quoting: YoRHa-2B
Quoting: NeverthelessSo even single threaded Vulkan is much more efficient than OpenGL. I guess DX11 performance might come single threaded Vulkan close.
Vulkan draw calls and friends are, for the most part, dirt cheap. There's very little (but still some) state tracking going on in the driver, and you as an engine developer can build thin abstractions that fit your needs, again with minimal state tracking, rather than using an overly generic abstraction that ends up doing way more than you actually need, and doesn't necessarily do it well, both in terms of CPU and GPU performance.

Unfortunately, the latter still seems to be a common pitfall, and we end up with games that run significantly worse on D3D12 than they do with D3D11, even when CPU limited. Latest prominent example of that being Resident Evil 2, which runs faster with D3D11->Vulkan translation than it does with their native D3D12 renderer on Windows. And that just shouldn't happen.

I must say I'm somewhat glad it's not (only) Vulkan that has such problems...
And do you change the CPU limitation with DXVK, or is it even possible without generating lots of errors?
Nevertheless Feb 5, 2019
Quoting: Guest
Quoting: GuestAn awful lot of modern ports (eg Feral, VP etc) use translation layers like DXVK anyway - it's not like porting houses are writing whole new renderers for AAA titles - that'd be cost and time prohibitive.

So really, we're comparing "porting house X's DXVK equivalent" (for Feral, IndirectX? for VP, eON) - some using OGL, some using Vulkan - to DXVK, not "native opengl" to DXVK.

Yes, the bulk of the work is some kind of translation layer, but there are additional changes around that that are sometimes made. So it's not a "pure" translation in all cases. Even VP can actually recompile the original game to work better with eON, if they have source code access.
Even within that, shaders contribute a lot to performance, and if a porting company can modify those to work better with Vulkan, then it _can_ make quite a big difference.
Still, the bulk of performance improvements come by just using Vulkan instead of OpenGL, no matter which way it's done. Vulkan is just better for modern systems - and it's DXVK, Feral, Croteam, Valve, etc (as far as GNU/Linux is concerned) who have shown just why there's been so much excitement over it. Hopefully we'll see less games using DX11 going forward, and more using Vulkan directly (or DX12 I suppose, but fingers crossed for Vulkan instead!).

I guess with more freedom and responsibilities you can easily do things not exactly right.. I suppose it's not DX12 or Vulkan to blame.
Nevertheless Feb 5, 2019
Quoting: Guest
Quoting: NeverthelessI guess with more freedom and responsibilities you can easily do things not exactly right.. I suppose it's not DX12 or Vulkan to blame.

Oddly enough, I think more people are doing it "right" with Vulkan than with OpenGL. Developers need help: documentation, debugging tools, stable drivers, examples, all that kind of thing. Khronos have put just as much effort into developer help as they have with the API, so as I see it Vulkan even wins out against OpenGL in that regard!
There's a tweet somewhere from someone who developed entirely on nVidia, and then with almost no changes it ran perfect on AMD hardware (the one change was a different bit of hardware support that should have been properly queried, and was actually caught by the validation layers and reported to the developer). That's something that was actually difficult to say for OpenGL.

...but yes, a developer can still bugger up if they ignore all that help. Last I heard, Unreal Engine has a load of validation errors with Vulkan, and I'm not sure on the state of Unity3D and Vulkan right now. Not enough free time to play around that much. And if Vulkan crashes out, it's usually a bit more spectacular than OpenGL crashing out.

(damn I gotta stop blabbing on, it's just an area that I'm passionate about)

No, don't stop your passions! You wrote a great article and I love learning more and completing my picture about the topic!
If I am informed correctly programming OpenGL was is a bit like programming a black box. I suppose laboriously programming Vulkan is much more predictable (if you know what you're doing) than guessing what the OGL black box needs.
Nevertheless Feb 5, 2019
Quoting: Guest
Quoting: GuestVery detailed and well written article, thank you. But... I just can't see how having a (near) perfect translation layer between DX12 and Vulkan is supposed to bring more developers to adopt Vulkan over DX12, and in the long run start developing games for our OS. I mean, the whole point of Proton, from a developer point of view, is "don't worry about nothing, don't change your practices, keep using what you are using right now (most often DX11/DX12) because Proton will take care of everything". Why should any developer move away from DX12 if they can reach the Linux and MacOS (using MoltenVK I guess) markets with their DX12 games?

DX12 is a different case to DX11 here, because DX12 is (in my mind) classed as a new API architecture. I'll confess that my knowledge of DX12 is limited - I use GNU/Linux exclusively on the desktop now, and so have little interest in developing for DX12, but it's still an important API to consider.

Short version though is that it's not really known if DX12 will completely take off, or Vulkan, or something else. It also depends on how much mobile influence there is - Vulkan is pretty much the only option going forward with Android, and of course there's Metal for iOS. Khronos themselves recognise this and so started the portability initiative - write in portable Vulkan, and it will just run on top of DX12, Metal, or Vulkan - whatever the underlying OS (desktop or mobile) supports. Oh, and web browsers should be considered too, which has Vulkan work starting as well (ok, a web browser doesn't affect a AAA game much, but it adds weight to general developer experience, and that might well creep into all graphics areas).

So how that all plays out remains to be seen. There's little bearing in that on why DXVK outperforms some (many!) native ports for GNU/Linux though, so I didn't really touch on it much in the article.

Great! Let's collect the best arguments to use Vulkan in favor of anything else. Here are my ideas:

-unlike DX availlable to any platform that wants to support it
-multithreading support to avoid CPU limitations
-performance on par with DX12. Only custom APIs for special hardware could reach higher efficieny
-more future proof than easier to use older APIs
-multi GPU support
-has tools to convert Vulkan code to DX12 and Metal
-the enormous flexibility of Vulkan that DXVK is a bright showcase for


Last edited by Nevertheless on 5 February 2019 at 9:45 pm UTC
Purple Library Guy Feb 5, 2019
Quoting: Guest(damn I gotta stop blabbing on, it's just an area that I'm passionate about)
Blab away, old bean. Interesting stuff.
While you're here, please consider supporting GamingOnLinux on:

Reward Tiers: Patreon. Plain Donations: PayPal.

This ensures all of our main content remains totally free for everyone! Patreon supporters can also remove all adverts and sponsors! Supporting us helps bring good, fresh content. Without your continued support, we simply could not continue!

You can find even more ways to support us on this dedicated page any time. If you already are, thank you!
The comments on this article are closed.