Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] DXVK as a native library for wine-integration #926

Open
wants to merge 41 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@Guy1524
Copy link
Contributor

commented Feb 19, 2019

This WIP PR allows DXVK to be built and installed as a native system library (libdxvk.so) for use by wine, as recommended by Henri Verbeet. The accompanying wine code can be found here.

The goal of this PR is to allow easy integration of DXVK into wine, without manual installation or use of third party tools.

This branch uses function pointers passed in from the entry point when it needs access to windows-specific APIS, similar to VKD3D. Right now the pointers are stored in a global struct that is accessed by various parts of DXVK (vulkan_presenter.cpp, thread_generic.cpp, d3d11_device.cpp, and vulkan_loader.cpp), which may be a problem. Alternatively, for cleaner code, we could store the relevant function pointers as static members of the relevant class.

Another potential issue is the compiler directives making the code unmaintainable. This PR adds 12 new compiler directives. If anyone can find places where I can reduce this number, please share your ideas.

Finally, the biggest issue may be the duplication of dxgi_swapchain and dxgi_monitor code into wine. These classes are heavy in win32 specific functions, so instead of passing in a large amount of function pointers to keep these in DXVK, I had WineDXGISwapChainFactory::CreateSwapChainForHwnd pass the internal d3d11 presenter to wine, which is then used to create a DXGISwapChain for the application. If it would be preferable to keep the IDXGISwapChain inside of DXVK, I will change that.

Finally, there are some trivial things left to implement in DXVK Native.

  • Implement util::env::getExeName, which may require some code rearranging

  • Implement util::env::setThreadName

  • Implement ThreadFn::set_priority

馃惛

Guide to use:

  1. Clone my dxvk-native-headers project, these headers need to be separate from the DXVK repository since they are licensed under the GPL.

  2. Copy the native folder into DXVK's include directory

  3. Build DXVK normally, specifying /usr for the prefix
    Note: Don't use the package-release script, it isn't configured to build without a cross-file. Follow the manual instructions in the DXVK README, omitting the cross-file argument.
    Example command: meson --buildtype release --prefix /usr build.l64

  4. Run sudo ninja install to install the library

  5. Build wine with my modifications

  6. Create HKEY_CURRENT_USER\Software\Wine\Direct3D\external_d3d in your prefixes' registry as a string and set it to libdxvk.so

@Guy1524 Guy1524 force-pushed the Guy1524:wine-dxvk-integration branch from 6a34dbd to 7c0bfe8 Feb 20, 2019

@Guy1524 Guy1524 force-pushed the Guy1524:wine-dxvk-integration branch from 1e5b4f0 to 354dc43 Feb 20, 2019

@leonmaxx

This comment has been minimized.

Copy link

commented Feb 21, 2019

I did a build of dxvk and wine 4.2 with your patches for CentOS 7.6 and Fedora 28/29.
Tested only on CentOS: when I start a game with dxvk enabled it overwrites game's .exe file with DXVK state cache header and couple lines of dxvk log entries.
If I set DXVK_LOG_PATH and DXVK_STATE_CACHE_PATH to some other directory it will create a single log and state cache file with exact game's exe name, without _dxvk.log or .dxvk-cache suffixes.
I do not see what but something is broken in Logger::getFileName() and DxvkStateCache::getCacheFileName() when DXVK builds as Linux native library.

Build of libdxvk and patched Wine 4.2 for Fedora 28/29 if anyone wants to test: https://copr.fedorainfracloud.org/coprs/leonmaxx/wine-dxvk/

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 21, 2019

@leonmaxx Thank you for testing! I think I found the issue, pushing a commit now.

@leonmaxx

This comment has been minimized.

Copy link

commented Feb 21, 2019

Thanks but that didn't helped.
In getExeName() function variable fullPath with line readed from '/proc/self/cmdline' have 10+ '\0' null symbols after executable name. I fixed it with this patch:

diff -purN a/src/util/util_env_native.cpp b/src/util/util_env_native.cpp
--- a/src/util/util_env_native.cpp	2019-02-21 23:39:51.000000000 +0200
+++ b/src/util/util_env_native.cpp	2019-02-22 00:30:33.683256349 +0200
@@ -25,6 +25,9 @@ namespace dxvk::env {
         std::getline(cmdLineFile, fullPath);
     cmdLineFile.close();
 
+    while (*fullPath.rbegin() == '\0')
+        fullPath.erase(fullPath.size()-1);
+
     auto n = fullPath.find_last_of('/');
     auto e = fullPath.rfind(".exe");

This change does fix file names for log and state cache files.

The game I tried to run is "World Of Tanks" and it works if I run it with DXVK built as Win32 library.
When running WoT with DXVK built for Linux it hangs on startup with these suspicious lines in log:

...
warn:  D3D11CoreCreateDevice: Adapter is not a DXVK adapter
...
warn:  D3D11Device::CreateShaderModule: Class linkage not supported
warn:  D3D11Device::CreateShaderModule: Class linkage not supported
warn:  D3D11Device::CreateShaderModule: Class linkage not supported
...

Full startup log: https://gist.github.com/leonmaxx/aa671f05610a3b9ec6cfba87346b3e0d#file-worldoftanks_log-txt

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 21, 2019

Thank you for investigating this issue, I thought that cutting off the string after the exe would fix that, but I guess not. Or were the symbols before .exe?

In regards to the WoT issue, the adapter message is to be expected, as we are using wine's DXGI. The class linkage issues are probably unrelated, do they happen w/ the win32 build? Finally, can you test whether WoT works w/ wine's DXGI when on a windows build of d3d11?

@leonmaxx

This comment has been minimized.

Copy link

commented Feb 22, 2019

Or were the symbols before .exe?

After.

The class linkage issues are probably unrelated, do they happen w/ the win32 build?

Nope.

Finally, can you test whether WoT works w/ wine's DXGI when on a windows build of d3d11?

Will do later today.

@pchome

This comment has been minimized.

Copy link
Contributor

commented Feb 24, 2019

The goal of this PR is to allow easy integration of DXVK into wine, without manual installation or use of third party tools.

  1. Create HKEY_CURRENT_USER\Software\Wine\Direct3D\dxvk in your prefixes' registry as a DWORD and set it to 1

We (users) definitely want a setup.sh or a custom winetricks's verb to set this 馃槈

If anyone can find places where I can reduce this number, please share your ideas.

To reduce the number of required changes and/or improve PR/patch readability, you could do following:

  • remove src/d3d10/d3d10_include.h and src/dxvk/dxvk_include.h parts, it changes nothing
  • use __WINE__, e.g. add_project_arguments(['-DDXVK_NATIVE=1', '-D__WINE__'], language : 'cpp'),
    probably the only place where additional expression required is src/vulkan/vulkan_loader.cpp
  • move include/meson.build into include/native/ directory (repository), define com_headers = [] in main meson.build file
  • use ternary operator in meson.build files, e.g. name = dxvk_native ? 'libdxvk' : 'd3d11'+dll_ext

Maybe there is more places to pay attention, but I don't checked further than Files changed tab.

@gasinvein

This comment has been minimized.

Copy link

commented Feb 24, 2019

Can it be used for native apps, without wine/winelib?

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 25, 2019

@pchome Thanks for the advice, I'll get to work on that after completing Henri's recommendations.

@gasinvein In theory, yes, although a bit more work should be done to make that easier.

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 27, 2019

@leonmaxx Hey, can you test WoT w/ my latest commits? I redid part of the project for Henri, and I'm curious whether that resolves your issue. Thanks!

@leonmaxx

This comment has been minimized.

Copy link

commented Feb 27, 2019

@Guy1524 Will test later today. Thanks!

@leonmaxx

This comment has been minimized.

Copy link

commented Feb 27, 2019

@Guy1524 Seems like nothing is changed for WoT: log file.

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 27, 2019

Ah, OK. Thanks for testing, I'll look further into it soon.

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 28, 2019

Henri wanted me to change some things around, I updated the installation instructions to reflect these changes, make sure to update your headers if you wish to test.

@gasinvein

This comment has been minimized.

Copy link

commented Feb 28, 2019

The registry key should be HKEY_CURRENT_USER\Software\Wine\Direct3D\external_d3d, I guess.

@Guy1524

This comment has been minimized.

Copy link
Contributor Author

commented Feb 28, 2019

@gasinvein Yes, thanks for catching that!

@gasinvein

This comment has been minimized.

Copy link

commented Feb 28, 2019

Tested with Witcher 3 btw, works just fine.

@rsw0x

This comment has been minimized.

Copy link

commented Mar 10, 2019

Tested with Warframe, no issues as far as I can tell.

@leonmaxx

This comment has been minimized.

Copy link

commented Mar 10, 2019

I did a fresh rebuild (link), unfortunately nothing changed for WoT, same Class linkage not supported log spam and crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can鈥檛 perform that action at this time.