
One of the features of
Parallels Desktop 12 for Mac is support for PC games. There are many games available only for Windows and Xbox, and using Parallels Desktop you can play these games on a Mac without rebooting - inside a virtual machine. Can we assume that the problem of PC games on Mac is completely solved? Not yet, but we are working on it. This article describes several examples of how we do it.
Why is it difficult to support DirectX in full?
In fact, the PC virtual machine, which allows you to run Windows on a Mac, does not in itself guarantee that PC games will work in it. The fact is that most games require DirectX support for a specific version of the video adapter, and providing this support falls entirely on the shoulders of video driver developers. Naturally, video drivers designed for “real” Nvidia, AMD and Intel video cards will not work in a virtual machine.
At the moment, the latest version of DirectX is DirectX 12, but it is not yet widespread. Another thing - the version of DirectX 11, already quite popular among game developers. However, since DirectX 10 exists - and is actively used in practice - the ability to work with DirectX 11 and higher on a video card that supports, for example, only DirectX 10, with limited functionality, so most new games written for DirectX 11 can work on DirectX 10 with no noticeable visual difference.
')

We provide support for DirectX, starting with the very first versions of Parallels Desktop for Mac. As Windows and DirectX evolved, Parallels Desktop also evolved. We supported DirectX 7, DirectX 8, DirectX 9, and for several years already DirectX 10, which is especially important in light of the above. But that part of the functionality of DirectX 10, which concerns the work of the video driver - the rules by which its commands should be interpreted and the image created - is described in the documentation rather succinctly. The number of different combinations, states, calls is very large, and simply reading the specification in order to create an unambiguous program code for it, which any PC game will allow to run and work, unfortunately, is unrealistic.
In addition, you should know that we provide support for DirectX 10 via OpenGL, i.e. convert the commands for DirectX into commands for OpenGL. But the same design in OpenGL and in DirectX may work somewhat differently, and different images may be drawn in different conditions. What remains? It remains to work by trial and error, i.e. run modern games that use DirectX 10 functionality, and work on bugs.
Our fight with Overwatch
We decided to test our support for DirectX 10 using the example of
Overwatch , a multiplayer shooter released by Blizzard Entertainment for all major gaming platforms, i.e. for PC, PS4 and Xbox One - but not for Mac. The Overwatch game takes advantage of DirectX 10 very intensively, so it turned out to be a good test of strength for our DX10 driver. And the game has earned - but with a lot of problems. Many things were rendered incorrectly, slowly. Here is how the game looked at first.

Below we describe only
three of the problems with which we had to face .
Controls and menu items
The first thing that caught our eye was that on NVidia and Intel video cards, Overwatch did not draw some of the menu items, indicators, and icons. We found the problem rather quickly - it turned out to be related to the discrepancy in the interpretation of the values of the built-in variable VertexID in vertex shaders. In the case of index rendering in DirectX, this variable is equal to the value of the “vertex index”, and in the case of working through OpenGL, the value BaseVertex is added to it. Texture shaders, which are then used to display menus and other "flat" game elements, use in their code a comparison of VertexID with predefined values. Since the drivers for NVidia and Intel work according to the OpenGL specification, they give the wrong picture. AMD drivers, on the other hand, do not add BaseVertex to VertexID, as a result, the error is superimposed on the error and the correct result is obtained.
It would have been easy to correct the situation with the
GL_ARB_shader_draw_parameters extension, but unfortunately, the Mac does not support it - at least for now. We found another solution - when NVidia and Intel are used, we pass the BaseVertex value inside the shader, and then subtract it from gl_VertexId. The result is a variable value that is correct from the point of view of DirectX 10 number. Of course, this does not happen on AMD video cards.
Problem with shadows
In fact, object shadows were drawn in Overwatch correctly. But on all the illuminated areas were visible stripes.

After we dealt with the shaders in detail, the reason was revealed in the configuration of the state of OpenGL. The RasterizerState function of the Direct3D 10 Runtime component has three values that define the adjustment of the depth of polygons: DepthBias, DepthBiasClamp and SlopeScaledDepthBias. Their OpenGL counterpart is reduced to calling glPolygonOffset with the correct parameters, and our mistake was that with DepthBias set to zero, we did not assume that SlopeScaledDepthBias might not be zero, because we considered that the polygon depth adjustment was turned off in this case.
Why hair fall out
The fact that all the characters in the Overwatch game under
Parallels Desktop either completely lost their hair, or cut their hedgehogs, caused a strong reaction in social networks and gave rise to a
lot of jokes .

However, it is worth noting that good-natured users did not notice that in the game not only the characters' hair, but also some other objects were absent in the game. Testing has shown that the reason for this exotic error is the lack of free texture channels. In OpenGL there can be no more than 16 for each type of shader. This limitation was due to the fact that the use of texture channels with numbers 16 and higher on AMD video cards leads to damage to the OpenGL state in the driver and problems in subsequent rendering. As a result, instead of all the other textures involved in rendering, the shader received black color, which in some cases led to the complete disappearance of the object being drawn from the scene. It must be said that we, of course, did not get rid of the problem itself, but since the Overwatch negative effect of removing this restriction was minimal, we decided to get rid of it for this case. It is worth noting that, in general, the problem of the lack of texture channels in OpenGL compared to DirectX 10 is acute, because the latter theoretically allows up to 128 resources to be used in a single drawing, and only saves that there are quite a few applications that use this feature.
Result
It took us less than a month to do all the work, and by correcting the mistakes - both described and a number of others - we achieved that now our users can actually play Overwatch under Parallels Desktop for Mac, and this game works in a virtualized environment quite quickly. This speed, of course, is not comparable with the speed of Overwatch on the PC, and in the case of serious loads the game slows down. But the goal of "catching up and overtaking the PC" was not intended by us. Using the example of Overwatch, we found problems in the operation of our virtual driver and were able to fix them. The results will help in supporting the work of other 3D-applications. And, of course, nothing compares to the positive feedback from Mac users - because now, thanks to us, they can play on this platform their old favorite games, which no one would have ever puzzled about transferring to Mac.

When will DirectX 11 support appear?
The fact is that OpenGL on Macs develops slowly and always noticeably lags behind the latest current versions. Even to support DirectX 10, we often lacked the existing OpenGL functionality on a Mac, had to resort to various tricks and emulate the missing features on our own. Now Mac supports OpenGL 4.1 and this is somehow enough for DirectX 10, but for the 11th version a number of key features are missing, for example, compute shaders. So much depends on whether Apple will continue to develop OpenGL on their machines.