[d3d9] Add device import interop API
As requested by @doitsujin in #4497, I have added an API to import existing Vulkan devices. Here is an example of how it could be used to add an async compute queue when creating the device. First, all device creation info is queried with GetDeviceCreateInfo, then the device is created in userspace and passed to ImportDevice. I have tested this extensively in a project under active development and can confirm that it works. Feedback or nits are welcomed!
I have personally tested it on AMD and NVIDIA on Linux and NVIDIA on Windows (both MSVC and Mingw).
EDIT: The new API in of July 2025 has three separate calls to get device info: QueryDeviceExtensions, QueryDeviceQueues, and QueryDeviceFeatures. These correspond to calls in DxvkDeviceCapabilities. The only changes to the backend are to support importing separate transfer and sparse queues. A separate transfer queue may be preferable for concurrency. A separate sparse queue may be necessary for compatibility with devices that do not support sparse binding on the main graphics queue.
@AlpyneDreams Not sure if you saw it, but there's a warning that's probably worth fixing:
../../../src/d3d9/d3d9_interop.cpp: In member function ‘virtual HRESULT dxvk::D3D9VkInteropInterface::GetDeviceCreateInfo(UINT, D3D9VkDeviceCreateInfo**)’:
Warning: ../../../src/d3d9/d3d9_interop.cpp:92:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘const size_t’ {aka ‘const unsigned int’} [-Wsign-compare]
92 | for (int i = 0; i < queueCount; i++) {
| ~~^~~~~~~~~~~~
@WinterSnowfall Thanks, fixed!
Rebased.
Rebased to 2.5.2
Apologies for the silence, will look at this again after the next release, we had some regressions to take care of.
Fixed an issue where VkDeviceMemoryOverallocationCreateInfoAMD was stored as a local variable instead of with everything else in the pNext chain that was causing segfaults on AMD.
Rebased to 2.5.3 and squashed some fixes.
Been a while, but I am going to start working on improving device / instance creation now, at least to the point where required features / extensions etc can be queried from DXVK and then be fed back into it.
@doitsujin
Been a while, but I am going to start working on improving device / instance creation now, at least to the point where required features / extensions etc can be queried from DXVK and then be fed back into it.
Okay, I've updated the PR to use those new query functions, and I also removed a lot of stupid cruft I left in the initial version of the PR. I'm going to switch this to draft until I have time to do more testing, though.
It seems like importDevice still doesn't support specifying a transfer or sparse queue. Should I extend it to support those as optional parameters like I did in the initial version of the PR?
I have updated the example code to show how the current device import API is used to add extra queues in a production environment
Rebased to 2.7
Added commits to support separate transfer and sparse queues. A separate transfer queue may be preferable for concurrency. A separate sparse queue may be necessary for compatibility with devices that do not support sparse binding on the main graphics queue. This makes minor tweaks to the backend, should not affect existing functionality.
I have tested the latest additions in production and can confirm it works, it creates a separate transfer queue and uses the main queue for sparse. I've updated the example with new changes required to do this.