Skip to content

[viogpu3d] Virtio GPU 3D acceleration for windows - #943

Open
max8rr8 wants to merge 1 commit into
virtio-win:masterfrom
max8rr8:viogpu3d
Open

max8rr8 wants to merge 1 commit into
virtio-win:masterfrom
max8rr8:viogpu3d

Conversation

@max8rr8

@max8rr8 max8rr8 commented Jul 18, 2023 •

Copy link
Copy Markdown

Hello! This series of changes spanning across multiple repositories introduce support for 3d accelerated virtiogpu windows guests.

Demo image

Wglgears window is rendered with wgl on virgl and window below it is cube rendered with d3d10umd on virgl.

How to test

NOTE: This driver does have some rendering glitches and might crash. Try at your own risk.
0. Create qemu windows VM with VirtIO GPU with 3d acceleration enabled. It is highly recommended to use "disposable" virtual machine to test, loss of data might occur.

  1. Use patched version of virglrenderer from this repo branch viogpu_win
  2. Compile from source OR download pre-built drivers.
  3. Install drivers on target VM. Note: if drivers were not signed you need to manually select them in device manager.

Known issues

  • FIXED: Frames displayed on screen are lagging behind

  • FIXED: D3d10 clearing color is not supported

  • FIXED: D3d10 applications using DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_SEQUENTIAL are not displayed.

  • Rendering glitches in WinUI3 apps.

    There are some rendering glitches in apps based on WinUI3 (maybe other apps too), best way to see them is to install WinUI3 Gallery from microsoft store and navigate around it. Haven't yet invistigated.

  • Vscode (possibly other electron apps) does not render

    Black window. Requires implementation of PIPE_QUERY_TIMESTAMP_DISJOINT in virglrenderer.

  • No preemption

    Kernel-mode driver does not implement preemption, and i am very confised about how to implement it in WDDM. VioGpu3D disables preemption systemwide to workaround lack of preemption implementation, but this is not ideal. Would appreciate some help.

Siblings

@vrozenfe

Copy link
Copy Markdown
Collaborator

@max8rr8
Hi Max,

Thank for a very impressive work you've done.
Please give us some time to go through your code and
see how to integrate it into our upstream repository.

Nice work!
All the best,
Vadim.

Comment thread viogpu/viogpu3d/BUILDING.md Outdated
5. Build and install mesa binaries: `ninja install`
6. Go to `viogpu` directory of this repository
7. Run: `.\build_AllNoSdv.bat`
8. Compiled drivers will be available in `viogpu\viogpu3d\objfre_win10_amd64\amd64\viogpu3d` No newline at end of file

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @max8rr8,

This instruction is not clear to me. Can you please describe it more with directory examples? What dependencies should be installed and how configured? (Example: https://github.com/virtio-win/kvm-guest-drivers-windows/wiki/Building-the-drivers-using-Windows-11-21H2-EWDK).
I looked into the mesa compilation guide and it looks completely different.

meson setup builddir/
meson compile -C builddir/
sudo meson install -C builddir/

Several questions:

  1. What is %MESA_PREFIX% and where it defined?
  2. Can we use any precompiled MESA for Windows (for example https://fdossena.com/?p=mesa/index.frag)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is %MESA_PREFIX% and where it defined?

%MESA_PREFIX% environment variable is set during build process, it points to directory where mesa installs its files.

Can we use any precompiled MESA for Windows

I don't think so, as pointed out in mesa MR when building user-mode driver we have to build it with specific mesa flags to build only virgl driver (to avoid conflicts)

@max8rr8 max8rr8 Jul 20, 2023 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building instruction

NOTE 1: this is valid for now, until changes are not in upstream repositories
NOTE 2: this assumes that all build dependencies(meson, WDK, ninja, etc...) are installed

Part 1: Virglrenderer

On host machine it is required that patched version of virglrenderer is used.

  1. Acquire source code git clone --branch viogpu_win https://gitlab.freedesktop.org/max8rr8/virglrenderer && cd virglrenderer
  2. Create install directory mkdir install and build directory: mkdir build && cd build
  3. Configure build meson --prefix=$(pwd)/../install (we set prefix to install libvirglrenderer not globally but to previously created dir install)
  4. Compile and install ninja install
    Now ensure that qemu loads libvirglrenderer from install directory, this can be done by setting LD_LIBRARY_PATH to something like /some/path/to/starter_dir/virglrenderer/install

Part 2: Build mesa

Now inside virtual machine with build tools installed create working directory, then inside it (this assumes use of Powershell):

  1. Create mesa prefix dir mkdir mesa_prefix and set env MESA_PREFIX to its path: $env:MESA_PREFIX="$PWD\mesa_prefix"
  2. Get patched mesa source code git clone --depth 10 --branch viogpu_win https://gitlab.freedesktop.org/max8rr8/mesa and then cd into it cd mesa
  3. Create build directory mkdir build && cd build
  4. Configure build meson .. --prefix=$env:MESA_PREFIX -Dgallium-drivers=virgl -Dgallium-d3d10umd=true -Dgallium-wgl-dll-name=viogpu_wgl -Dgallium-d3d10-dll-name=viogpu_d3d10 -Db_vscrt=mt, build options explained:
  • --prefix=$env:MESA_PREFIX set installation path to dir created in step 1
  • -Dgallium-drivers=virgl build only virgl driver
  • -Dgallium-d3d10umd=true build DirectX 10 user-mode driver (opengl one is build by default)
  • -Dgallium-d3d10-dll-name=viogpu_d3d10 name of generated d3d10 dll to viogpu_d3d10.dll
  • -Dgallium-wgl-dll-name=viogpu_wgl name of generated wgl dll to viogpu_wgl.dll
  • -Db_vscrt=mt use static c runtime (see this comment)
  1. Build and install (to mesa prefix): ninja install

Part 3: Build driver

Now that mesa is build and installed into %MESA_PREFIX% viogpu3d will be built (in case %MESA_PREFIX is not set viogpu3d inf generation is skipped)

  1. Acquire source code git clone --branch viogpu_win https://github.com/max8rr8/kvm-guest-drivers-windows and cd into it cd kvm-guest-drivers-windows
  2. Go to viogpu cd viogpu
  3. (optional, but very useful) setup test code signning from visual studio
  4. Call build .\build_AllNoSdv.bat

Part 4: Installation

Now copy kvm-guest-drivers-windows\viogpu\viogpu3d\objfre_win10_amd64\amd64\viogpu3d to target VM and install it.

EDIT: Added gallium-windows-dll-name to mesa parameters.
EDIT2: More changes related to dll naming in mesa parameters

@max8rr8

max8rr8 commented Jul 21, 2023 •

Copy link
Copy Markdown
Author

Changes:

  • Fixed crash caused by use of PAGED_CODE at DISPATCH_LEVEL in flip timer. Instead of using ExTimer, separate flipping thread is used.
  • Building system now checks for viogpu related dll's specifically when deciding whether to compile viogpu3d
  • Renamed DLL's and updated build instructions due to changes requested by mesa

@max8rr8

max8rr8 commented Jul 24, 2023

Copy link
Copy Markdown
Author

Changes:

  • Re-implemented RotateResourceIdentites. This fixed biggest issue of frames lagging behind, now using driver becomes pretty smooth experience.
  • Implemented clear_render_target similarly to i915
  • Implemented support for staging resources and kernel-mode Present BLT which fixes window display in applications using DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_DISCARD.

Pre-built driver provided in description was updated with these changes.

@mincore

mincore commented Aug 1, 2023 •

Copy link
Copy Markdown

I've tested the driver on win10, and got a black screen. But if change the guest os to ubuntu(same qemu command line), glxgears performs well. (glxinfo shows that the renderer is NVIDIA gpu)

env

guest os:
win 10 enterprise ltsc + viogpu3d

host os:
fedora38, qemu 8.0.3 with virglrenderer

qemu command line

-display egl-headless,rendernode=/dev/dri/card1 -device virtio-vga-gl -trace enable="virtio_gpu*" -D qemu.log

virglrenderer.log

gl_version 46 - core profile enabled
GLSL feature level 460
vrend_check_no_error: context error reported 3 "" Unknown 1282
context 3 failed to dispatch DRAW_VBO: 22
vrend_decode_ctx_submit_cmd: context error reported 3 "" Illegal command buffer 786440
GLSL feature level 460
vrend_check_no_error: context error reported 5 "" Unknown 1282
context 5 failed to dispatch DRAW_VBO: 22
vrend_decode_ctx_submit_cmd: context error reported 5 "" Illegal command buffer 786440
GLSL feature level 460
GLSL feature level 460
GLSL feature level 460
GLSL feature level 460
GLSL feature level 460
vrend_check_no_error: context error reported 9 "" Unknown 1282
context 9 failed to dispatch DRAW_VBO: 22

qemu_strace.log

virtio_gpu_features virgl 0
virtio_gpu_features virgl 0
virtio_gpu_cmd_get_edid scanout 0
virtio_gpu_cmd_get_display_info
virtio_gpu_cmd_ctx_create ctx 0x1, name
virtio_gpu_cmd_ctx_create ctx 0x2, name
virtio_gpu_cmd_res_create_3d res 0x1, fmt 0x1, w 1280, h 1024, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x2, res 0x1
virtio_gpu_cmd_res_back_attach res 0x1
virtio_gpu_cmd_res_create_3d res 0x2, fmt 0x1, w 1280, h 1024, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x2, res 0x2
virtio_gpu_cmd_res_create_2d res 0x3, fmt 0x2, w 1280, h 1024
virtio_gpu_cmd_res_back_attach res 0x3
virtio_gpu_cmd_set_scanout id 0, res 0x1, w 1280, h 1024, x 0, y 0
virtio_gpu_cmd_res_flush res 0x1, w 1280, h 1024, x 0, y 0
virtio_gpu_cmd_set_scanout id 0, res 0x1, w 1280, h 1024, x 0, y 0
virtio_gpu_cmd_res_flush res 0x1, w 1280, h 1024, x 0, y 0
virtio_gpu_cmd_ctx_create ctx 0x3, name
virtio_gpu_cmd_ctx_destroy ctx 0x3
virtio_gpu_cmd_ctx_create ctx 0x3, name
virtio_gpu_cmd_res_create_3d res 0x4, fmt 0xb1, w 48, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x4
virtio_gpu_cmd_res_create_3d res 0x5, fmt 0xb1, w 4000, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x5
virtio_gpu_cmd_res_create_3d res 0x6, fmt 0xb1, w 16, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x6
virtio_gpu_cmd_res_create_3d res 0x7, fmt 0xb1, w 48, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x7
virtio_gpu_cmd_res_create_3d res 0x8, fmt 0xb1, w 240012, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x8
virtio_gpu_cmd_res_create_3d res 0x9, fmt 0xb1, w 102400, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x9
virtio_gpu_cmd_res_create_3d res 0xa, fmt 0xb1, w 144, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xa
virtio_gpu_cmd_res_create_3d res 0xb, fmt 0xb1, w 160000, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xb
virtio_gpu_cmd_res_create_3d res 0xc, fmt 0xb1, w 16000, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xc
virtio_gpu_cmd_res_create_3d res 0xd, fmt 0xb1, w 240000, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xd
virtio_gpu_cmd_res_create_3d res 0xe, fmt 0xb1, w 192, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xe
virtio_gpu_cmd_res_create_3d res 0xf, fmt 0xb1, w 16, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0xf
virtio_gpu_cmd_res_create_3d res 0x10, fmt 0xb1, w 272, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x10
virtio_gpu_cmd_res_create_3d res 0x11, fmt 0xb1, w 240, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x11
virtio_gpu_cmd_res_create_3d res 0x12, fmt 0xb1, w 272, h 1, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x12
virtio_gpu_cmd_res_create_3d res 0x13, fmt 0x1, w 50, h 50, d 1
virtio_gpu_cmd_ctx_res_attach ctx 0x3, res 0x13
virtio_gpu_cmd_ctx_create ctx 0x4, name
virtio_gpu_cmd_res_back_attach res 0x13
virtio_gpu_cmd_res_back_attach res 0x4
virtio_gpu_cmd_res_back_attach res 0x5
virtio_gpu_cmd_res_back_attach res 0x6
virtio_gpu_cmd_res_back_attach res 0xa
virtio_gpu_cmd_res_back_attach res 0xe
virtio_gpu_cmd_res_back_attach res 0xf
virtio_gpu_cmd_res_back_attach res 0x10
virtio_gpu_cmd_res_back_attach res 0x11
virtio_gpu_cmd_res_back_attach res 0x12
virtio_gpu_cmd_ctx_submit ctx 0x3, size 74220

@max8rr8

max8rr8 commented Aug 2, 2023

Copy link
Copy Markdown
Author

I've tested the driver on win10, and got a black screen. But if change the guest os to ubuntu(same qemu command line), glxgears performs well. (glxinfo shows that the renderer is NVIDIA gpu)

It seems to be an bug in virglrenderer on nvidia related to GL_PRIMITIVE_RESTART_NV. You can try to apply this diff to fix it, but it's a bit hacky solution.

@CE1CECL

CE1CECL commented Aug 4, 2023

Copy link
Copy Markdown

What versions of windows does it go down to?
In my case, I am experimenting with https://github.com/CE1CECL/qemu-vmvga and it works with vista (no 3d yet), trying to get 3D to work right now.

@foxlet

foxlet commented Aug 6, 2023 •

Copy link
Copy Markdown

I tried the pre-built driver on Windows 10 22H2 and it only showed a black screen before hard-locking and resetting. Also tested the same config with Ubuntu which had working virgl.

Using -display gtk,gl=on -device virtio-vga-gl on an AMD R9 6900HS + RX 6700S host.
virglrenderer was compiled from git (considering that it's already been merged in).
qemu is version 7.2.4

qemu.log

@Conan-Kudo

Copy link
Copy Markdown

Can we validate that this works with Windows 7 too? It's a fairly common virtualization guest for playing older games, and it's still WDDM class.

@max8rr8

max8rr8 commented Aug 13, 2023

Copy link
Copy Markdown
Author

What versions of windows does it go down to?

Current driver theoretically supports windows 8.1, but it is built for and tested only on Windows 10 22H2. But it is important to note that support for blob resources which are required to improve performance and support vulkan will require using WDDM 2 which lift minimum windows version to 10.

Can we validate that this works with Windows 7 too?

I doubt it will work with current code, it might be possible to adapt it for windows 7, but i do not have interest in doing that (though wouldn't mind if someone else will adapt code). Plus at some point driver will have to use WDDM 2 which will splitting codebases or more likely require either dropping support for older OS.

I tried the pre-built driver on Windows 10 22H2 and it only showed a black screen before hard-locking and resetting. Also tested the same config with Ubuntu which had working virgl.

Nothing seems wrong in attached qemu.log. I don't see any lines like GLSL feature level 460 that should be printed to stdout, can you also attach stdout of qemu.
Although it could be issue in kernel driver then the only way to know what's wrong is to attach kernel debugger to vm.

@Torinde

Torinde commented Aug 14, 2023 •

Copy link
Copy Markdown

That's great @max8rr8!
It seems your focus is on modern software (Win8.1/10) and you plan going upwards in support (D3D12/Vulkan/venus). In that regards - do you plan adding:

  • video encoding/decoding acceleration
  • lvp/llvmpipe/softpipe - fallback when no compatible GPU is present on the host or to run the graphics on a high-corecount CPU instead of its weak integrated GPU? Or if possible to combine the two (augment the performance of a weak GPU with llvmpipe running on the CPU cores)

For the retro direction, above was mentioned Win7 and in addition I think such virgl/venus GPU will be very useful also for:

@RedGreenBlue09

RedGreenBlue09 commented Aug 19, 2023 •

Copy link
Copy Markdown

I compiled and tried it, but I got the BSOD DRIVER_CORRUPTED_EXPOOL.
Host: Windows 11 Pro (10.0.22621.2070), NVIDIA driver 536.67
Guest: Windows 10 Enterprise (10.0.16299.15)

First, I compiled QEMU in MSYS2 like this:

cp /c/Program\ Files\ \(x86\)/Windows\ Kits/10/Include/10.0.22621.0/um/WinHv*\
 /ucrt64/x86_64-w64-mingw32/include/

./configure \
--target-list=x86_64-softmmu,i386-softmmu,arm-softmmu \
--cpu=x86_64 \
--enable-lto \
--enable-malloc=jemalloc \
--enable-avx2 \
--enable-dsound \
--enable-hax \
--enable-iconv \
--enable-lzo \
--enable-opengl \
--enable-png \
--enable-sdl \
--enable-sdl-image \
--enable-spice \
--enable-spice-protocol \
--enable-tcg \
--enable-whpx \
--enable-virglrenderer \
--disable-docs 

I compiled virglrenderer (upstream) like your comment above, then replaced the dll in QEMU dir with the newly built one.

Then I compiled mesa with VS (MinGW GCC prints a bunch of errors related to the WDK headers, so I gave up):

meson setup build/ -Dgallium-drivers=virgl -Dgallium-d3d10umd=true -Dgallium-wgl-dll-name=viogpu_wgl -Dgallium-d3d10-dll-name=viogpu_d3d10 --backend=vs

It outputs to my root folder (C:\) so I copied bin to a directory named mesa_prefix.
I opened cmd, set MESA_PREFIX to the mesa_prefix directory then compiled viogpu.sln with msbuild (Configuration="Win10 Release", Platform=x64).

I signed the output in viogpu\viogpu3d\objfre_win10_amd64\amd64\viogpu3d:

for /R . %a in (*.exe, *.sys, *.dll) do signtool sign /f "Surface.pfx" /t "http://timestamp.sectigo.com" /fd certHash "%a"

Then I booted up the VM, enabled test signing and then install the driver. The screen instantly went black and Windows crashes.

WinDBG, qemu logs and VM command line attached. I tried using serial kernel debug but it just hangs forever at boot so I analyzed the dump file instead.

windbg.txt
qemu.log
cmdline.txt

@RedGreenBlue09

Copy link
Copy Markdown

Additionally, I tried booting Linux Mint 20.2 live cd but QEMU itself crashed on some heap corruption issue. I replaced the original MSYS2 virglrenderer dll which fixed it. The Windows 10 guest BSOD remains.

@max8rr8

max8rr8 commented Aug 20, 2023

Copy link
Copy Markdown
Author

Hi @RedGreenBlue09, it seems that kernel crash happened during driver unloading (VioGpu3DRemoveDevice in backtrace) and while it is a problem, it is not the root cause for driver not working on your system as for some unknown reason windows triggers driver unload.

You should try to attach windbg to running vm (try to use network debugging instead of serial, it works for me). Additionally when connecting to vm from windbg enable break on connection and run following command

bp  watchdog!WdLogEvent5_WdError "k; g"

This windbg command should add backtrace logging to all errors happening in dxgkrnl. After you ran that command continue kernel execution with windbg command g or a button in gui. Then get full log and send it there, so we can analyze what actually went wrong (why does unload happen).

@RedGreenBlue09

Copy link
Copy Markdown

Hi @RedGreenBlue09, it seems that kernel crash happened during driver unloading (VioGpu3DRemoveDevice in backtrace) and while it is a problem, it is not the root cause for driver not working on your system as for some unknown reason windows triggers driver unload.

You should try to attach windbg to running vm (try to use network debugging instead of serial, it works for me). Additionally when connecting to vm from windbg enable break on connection and run following command

bp  watchdog!WdLogEvent5_WdError "k; g"

This windbg command should add backtrace logging to all errors happening in dxgkrnl. After you ran that command continue kernel execution with windbg command g or a button in gui. Then get full log and send it there, so we can analyze what actually went wrong (why does unload happen).

I will test again later. Also, if I use VGA + virtio-gpu-gl setup the driver don't load and it have error 49 in device manager. The error message is something like "Windows unloaded the driver because it has reported problems"

@RedGreenBlue09

Copy link
Copy Markdown

... Network debug also hangs like serial. Interestingly that doesn't happen with ReactOS.

@RedGreenBlue09

RedGreenBlue09 commented Aug 20, 2023 •

Copy link
Copy Markdown

I have no luck with live kernel debug. I tried using accel tcg, official qemu, none of these helps. If
I enable boot debug, Windows boot manager itself freezes. Absolutely no idea.

Edit: Even ditching OVMF for SeaBIOS, it still freezes.

@RedGreenBlue09

Copy link
Copy Markdown

@max8rr8 Okay, I'm sorry for the rant. It doesn't hang forever, just 30 minutes :((. I tried your command and got an error:

0: kd> bp  watchdog!WdLogEvent5_WdError "k; g"
Bp expression 'watchdog!WdLogEvent5_WdError ' could not be resolved, adding deferred bp

@RedGreenBlue09

RedGreenBlue09 commented Aug 21, 2023 •

Copy link
Copy Markdown

After reloading symbols, the error is gone. Here is the new log.

windbg2.txt

@DemiMarie

Copy link
Copy Markdown

A big part of the problem here is that a lot of Microsoft's documentation on graphics drivers is only available under NDA.

Yikes! Any idea why this is? Is there enough public documentation to be able to write a working driver?

I wonder if a closed-source commercial offering would be more feasible. Since the driver would only be distributed in binary form, the developers might be able to sign any needed NDAs and so gain access to the needed documentation. Since the driver would cost money, there might be a better chance to fund continued development.

  • Thanks to Valve's work, there's far less desire for Windows guests for gaming. The few games that don't work under Proton also won't run in a VM for the same reason (aggressive anticheat), and will run horribly if at all with virgl anyway

What about non-game applications like AutoCad and SolidWorks?

@anonymix007

Copy link
Copy Markdown

So, first priority is DirectX, not OpenGL/Vulkan/OpenAL/etc.

I kinda agree here, but not fully. Basically, Windows requires DirectX from GPUs. If there is no UMD it will just unload the kernel driver. This means that it is not realistically possible to implement 3D acceleration in VMs without providing some DirectX UMD. That is, there are some ways to bypass these limitations for some use cases, but experimenting would take a lot of time, so I'm not sure if it would be worth it.
Anyway, layered DirectX UMDs should be fine, i.e. it seems that d3d10umd+virgl is enough for basic things. However, there are some missing features and inherent problems because of virgl. I have ported d3d10umd to work with Zink on Venus and that also kinda works as one can see in my Mesa MR (separate branch for that is in my fork). Also I have a few ideas on how to implement a UMD differently for better results.

If D3D12 is required for WHQL then there will be no WHQL driver in the near future. But who cares anyway? Test signing is fine for VMs and one could hack Windows to make it accept self-signed drivers. Eventually, once this matures enough, we might get an attestation signed driver which should just work if installed manually. AFAIU that's basically what that Fedora VirtIO ISO contains anyway.

The only evidence I've seen of him involved with this recently is that he provided private assistance to anonymix for his Vulkan effort.

Yes, we've chatted a lot privately and I really appreciate that. Without his work porting Venus would not be possible.

A big part of the problem here is that a lot of Microsoft's documentation on graphics drivers is only available under NDA

Some documentation is available though. It's just that sometimes things just don't work even though they should because Windows just want me to do some little stupid thing which I literally have no way of knowing about. Trying different ideas takes a lot of time, obviously.

What about non-game applications like AutoCad and SolidWorks?

As per my measurements, Venus in Linux is ~60% native. Layered DirectX implementations will have even bigger performance hit, but if that's enough then these applications are a valid use case.

Speaking of splitting the 3D driver from the display-only one, right now I'm doing a major rewrite of the kernel driver to hopefully improve stability and rethink some of the design choices which just don't work well for Venus. But there's only so much I can do in my spare time, you all should be more patient. Maybe if there was some company sponsoring this effort then this would go faster, but here we are. This is a fun hobby and a good exercise regardless.

@anonymix007

Copy link
Copy Markdown

@abitofzoe any chance you could try a debug build of UTM and get a full stack trace with line numbers from it?
There seem to be two places in that function function that have an abort() call. If I have to guess, it's probably this one:
https://github.com/anholt/libepoxy/blob/1b6d7db184bb1a0d9af0e200e06a0331028eaaae/src/gen_dispatch.py#L746
I would assume the issue is in the OpenGL driver. MoltenGL seems to be GLES 2.0, and this function appears to be from GL 3.1.

@DemiMarie

Copy link
Copy Markdown

Anyway, layered DirectX UMDs should be fine, i.e. it seems that d3d10umd+virgl is enough for basic things.

Would it be possible to implement a D3D12 UMD on top of Mesa’s Vulkan code? I’m not suggesting you go ahead and implement this, just asking if it can be done.

@anonymix007

Copy link
Copy Markdown

Would it be possible to implement a D3D12 UMD on top of Mesa’s Vulkan code?

I think so, but that's like really a lot of work. But I don't think this makes much sense to do, VKD3D should be good for most apps, and DWM seems mostly fine with just D3D10.

@DemiMarie

Copy link
Copy Markdown

Would it be possible to implement a D3D12 UMD on top of Mesa’s Vulkan code?

I think so, but that's like really a lot of work. But I don't think this makes much sense to do, VKD3D should be good for most apps, and DWM seems mostly fine with just D3D10.

Would this support D3D12 buffer sharing? I think that would be the main problem.

@anonymix007

Copy link
Copy Markdown

Do you mean ID3D12Device::CreateSharedHandle? This should be possible, yes. Exporting and importing shared resources already works in my Venus port, I even tested that with d3d10umd+zink. It will probably require some extra work to make VKD3D handle these properly outside of Wine environment, but should be doable.

@DemiMarie

Copy link
Copy Markdown

Do you mean ID3D12Device::CreateSharedHandle? This should be possible, yes. Exporting and importing shared resources already works in my Venus port, I even tested that with d3d10umd+zink. It will probably require some extra work to make VKD3D handle these properly outside of Wine environment, but should be doable.

I’m not familiar with D3D at all. I just know that ideally, apps would not be aware that there is not a native D3D12 UMD and instead a translation layer.

Curious: what makes a native D3D12 UMD so much harder than a D3D10 UMD?

@anonymix007

Copy link
Copy Markdown

VKD3D is not D3D12 UMD, it's a whole D3D runtime replacement. Unless an app is using some internal runtime details (most should not do this, I'd only expect Windows itself to use them, i.e. DWM does as per one of the comments above) it should not care whether there's a "real" D3D12 runtime or a layered one.

From an application development perspective, D3D12 is more complicated to use than D3D10/11 for the same reasons as why Vulkan is more complicated than OpenGL. Same is true for UMDs. For example, one difference is that D3D10 DDI has less mandatory functions than D3D11 DDI. And D3D12 DDI is even bigger. D3D12 also requires WDDM 2.0+ while here we're stuck with WDDM 1.3. Once again, this all is possible to do, but let's not get ahead of ourselves. Stable D3D10 and Vulkan are the priority for now, but there could be some future improvements for sure.
Also, there is already one open-source D3D10 UMD (namely, d3d10umd with zink or virgl backends) and there is exactly zero open-source D3D12 UMDs.

@matheuswillder

Copy link
Copy Markdown

#943 (comment):

Subscribed to this issue because I have mutiple windows VMs without proper video acceleration, and virgl has been working fine across my linux VMs so it would be great if we can have something similar for windows.
But nope, looks like its not gonna happen. End up getting an Arc Pro B50. Cheapest SR IOV one can find out there, max 16 windows VMs is more than enough for me.
Looking glass also is promising, but a lack of proper documentation and a lack of serious hypervisor support made it look more like a toy.

Never say never.

As I discussed previously, this is definitely possible.

It's just a question of actually putting in the development effort to support DirectX 12 and Vulkan.

Due to personal issues, I haven't been following any discussions in this PR, but as someone who opened the first issue to track this in #773, months before #841 and this PR, which have been open for years, I would like to thank everyone for their effort and dedication.

Regardless of whether it's merged someday or not, know that all the effort and dedication put in this PR are greatly appreciated.

@SyntheticBird45

Copy link
Copy Markdown

https://github.com/felixdoerre/primus_vk any chance vulkan could also be supported?

also I wonder if AI cloud help making a patch

lmao you ask a genuine question on a dead PR and you get downvoted for proposing AI to do the job 50 whiners (including me) didn't made for years.

@Hi-Angel

Hi-Angel commented Jun 8, 2026

Copy link
Copy Markdown

https://github.com/felixdoerre/primus_vk any chance vulkan could also be supported?
also I wonder if AI cloud help making a patch

lmao you ask a genuine question on a dead PR and you get downvoted for proposing AI to do the job 50 whiners (including me) didn't made for years.

That's because if you have to ask "can we code with AI", the answer is "no".

AI is an instrument, not a person. If you don't know what you're doing, and care so little that instead of digging yourself you ask "can we use AI", this implies you don't have the necessary understanding how to use it.

@DemiMarie

Copy link
Copy Markdown

Speaking of splitting the 3D driver from the display-only one, right now I'm doing a major rewrite of the kernel driver to hopefully improve stability and rethink some of the design choices which just don't work well for Venus.

Will there be any blockers for supporting native contexts in the future?

To be honest, I think that a working accelerated driver would be useful even if it was a closed-source commercial product. Jason Donenfield had to reverse-engineer parts of Windows to make WinTun and WireGuardNT work, and I suspect the D3DKMT API is much larger. Someone writing a closed-source driver could sign the NDAs and see all the documentation.

This would be an admission of defeat, but anyone using Windows is using closed-source software anyway.

@anonymix007

Copy link
Copy Markdown

https://github.com/felixdoerre/primus_vk
any chance vulkan could also be supported?

Vulkan is possible to implement, but that repo doesn't help it in any way, it's completely unrelated.

Will there be any blockers for supporting native contexts in the future?

Only time will tell, for now I don't see any. And since my GPU recently got unofficial support, I'm eager to try. Main problem is that these are much more complex compared to Venus, and even getting them to build will take quite a bit of time.

To be honest, I think that a working accelerated driver would be useful even if it was a closed-source commercial product.

VMware has one (and there's more from others), VirtualBox Guest Additions even contain an open-source one. I personally don't think commercial driver will be able to attract enough customers to be viable, so my plan always was to publish the source code once it's ready, but maybe dual licensing is the way to go.

Someone writing a closed-source driver could sign the NDAs and see all the documentation.

I doubt Microsoft would even propose such documentation under NDA unless there is a huge corporation behind this. I don't have one. Do you?

Anyway, at this point my new driver is close to being ready for the public release. It's currently on par with the old one based on this PR and is even better in some places. But given that it's not using any of the code from this repo, I don't really see a point in a PR.

@SyntheticBird45

Copy link
Copy Markdown

@anonymix007 I'm excited to see it when it comes out.

@CE1CECL

CE1CECL commented Jun 9, 2026

Copy link
Copy Markdown

To be honest, I think that a working accelerated driver would be useful even if it was a closed-source commercial product.

https://github.com/CE1CECL/qemu-vmvga is a thing, by the way. Its just a drop in replacement to the QEMU source code, and you use VMware's SVGA driver (from VMware Tools) and thats it.
I chose VMware over Parallels & VBoxVGA because

  • Linux kernel Framebuffer support (Parallels lacks it, though it may have a out of tree module, not sure though)
  • Down to Windows 95 support, Up to Windows 11 (VBoxVGA lacks 9x Support)
  • Mac OS X Kext with acceleration (OpenGL only/Non-Metal, but only VMware SVGA has a implementation/Kext for it)
  • OpenGL 4.3 and Direct3D 11 (Parallels only has OpenGL 4.1 and Direct3D 11, and VBoxVGA only has Direct3D 9Ex)

Though it is still in need of help/in development for 3D. Basic 2D works but the point of the full rewrite was mainly Windows Aero to work in software with QEMU.

@alpytron

Copy link
Copy Markdown

Hi,

I ran into a reproducible guest bugcheck / boot loop when driving this driver to a 4K-class mode (e.g. a maximized ~3840×2160 SPICE client window, which QEMU turns into the EDID preferred mode). Two small root causes:

  1. VioGpuObj::Init (viogpu/common/viogpu_queue.cpp) logs m_pSegment->GetSize() in the "segment too small" branch, but m_pSegment is assigned only after that check — it's still NULL, so any oversized-framebuffer mode bugchecks instead of failing gracefully.

  2. The frame segment min in VioGpuAdapter::HWInit is 16 MB (already // FIXME), too small for a 4K framebuffer (3840×2160×4 = 31.6 MB).

Fix (base viogpu3d, +4/-3): log the passed-in pSegment instead, and raise the segment minimum to 64 MB. Verified on Win10 LTSC / QEMU 10.2.4 (virgl+venus): before, a 4K EDID boot-loops; after, the guest boots and holds 3840×2160.

PR against the feature branch: max8rr8#1

@davispuh

Copy link
Copy Markdown
Contributor

I think this PR is dead and everyone should move on. Probably currently most work went into osy's fork https://github.com/osy/kvm-guest-drivers-windows/tree/neptune so I suggest trying out that instead. But you'll need other code aswell (mesa etc).

See https://blog.getutm.app/2026/introducing-triton-directx-11-driver-for-qemu/

@alpytron

Copy link
Copy Markdown

I think this PR is dead and everyone should move on. Probably currently most work went into osy's fork https://github.com/osy/kvm-guest-drivers-windows/tree/neptune so I suggest trying out that instead. But you'll need other code aswell (mesa etc).

See https://blog.getutm.app/2026/introducing-triton-directx-11-driver-for-qemu/

Thanks, I was not aware of that. Eventually, osy's fork has the same bugs I fixed here. :)
So I guess it worth submitting the same PR there too.

@anonymix007

Copy link
Copy Markdown

I think this PR is dead and everyone should move on

It is, yes. That's what I did and here's a little peek at the results:
Screenshot from 2026-07-03 19-57-30_1

Speaking of neptune, I'd argue that the most useful part is the DDI-to-API translation layer - triton. Neptune itself is mainly useful for MacOS hosts where D3DMetal exists, and some design choices are less than ideal because of that (DXMT might help though). Triton+DXVK+ANV/RADV/... all running in the guest should perform better on Linux hosts thanks to DRM native contexts. And there's always the possibility that d3d10umd would be usable with Iris/RadeonSI/... for potentially even more performance, though what actually performs better is yet to be benchmarked.

@SyntheticBird45

Copy link
Copy Markdown

I think this PR is dead and everyone should move on

It is, yes. That's what I did and here's a little peek at the results: Screenshot from 2026-07-03 19-57-30_1

Speaking of neptune, I'd argue that the most useful part is the DDI-to-API translation layer - triton. Neptune itself is mainly useful for MacOS hosts where D3DMetal exists, and some design choices are less than ideal because of that (DXMT might help though). Triton+DXVK+ANV/RADV/... all running in the guest should perform better on Linux hosts thanks to DRM native contexts. And there's always the possibility that d3d10umd would be usable with Iris/RadeonSI/... for potentially even more performance, though what actually performs better is yet to be benchmarked.

Very impressive work. Truly happy you committed to this and got free of this horrendous upstream effort that will never lead to anything.

@Mungr3ss

Mungr3ss commented Aug 23, 2026 •

Copy link
Copy Markdown

what i'd love see is direct3d / opengl acceleration working on qemu on a windows host in a windows guest.
would be cool to have a virtual machine with working 3d acceleration that doesn't rely on linux / kvm.

imagine a virtual machine on qemu for windows running windows to play old games on or whatever.

i found this https://github.com/templarsco/pvgpu which seemed interesting...
but i couldn't get the driver to build in vs 2022.

@Hi-Angel

Copy link
Copy Markdown

@Mungr3ss but you'd get better performance with Linux host + Windows guest (there are many reasons for that: starting with better memory and CPU management, and ending with Linux being well optimized for hosting VMs and containers because it's an industry standard for that). Given that and Linux being completely free, I don't see what your suggestion would improve.

Besides, on Linux you don't even need virtualization to run old Windows games — WINE for older apps/games, barring some exception, usually works well.

@SyntheticBird45

Copy link
Copy Markdown

@Mungr3ss but you'd get better performance with Linux host + Windows guest (there are many reasons for that: starting with better memory and CPU management, and ending with Linux being well optimized for hosting VMs and containers because it's an industry standard for that). Given that and Linux being completely free, I don't see what your suggestion would improve.

Besides, on Linux you don't even need virtualization to run old Windows games — WINE for older apps/games, barring some exception, usually works well.

pull info out of my ass and giving a non-answer award 🏆

@CE1CECL

CE1CECL commented Sep 12, 2026

Copy link
Copy Markdown

To be honest, I think that a working accelerated driver would be useful even if it was a closed-source commercial product.

https://github.com/CE1CECL/qemu-vmvga is a thing, by the way. Its just a drop in replacement to the QEMU source code, and you use VMware's SVGA driver (from VMware Tools) and thats it. I chose VMware over Parallels & VBoxVGA because

* Linux kernel Framebuffer support (Parallels lacks it, though it may have a out of tree module, not sure though)

* Down to Windows 95 support, Up to Windows 11 (VBoxVGA lacks 9x Support)

* Mac OS X Kext with acceleration (OpenGL only/Non-Metal, but only VMware SVGA has a implementation/Kext for it)

* OpenGL 4.3 and Direct3D 11 (Parallels only has OpenGL 4.1 and Direct3D 11, and VBoxVGA only has Direct3D 9Ex)

Though it is still in need of help/in development for 3D. Basic 2D works but the point of the full rewrite was mainly Windows Aero to work in software with QEMU.

Someone made a fork of my qemu-vmvga project and got Aero to work, see: CE1CECL/qemu-vmvga#3 for more info

@kroese

kroese commented Oct 5, 2026

Copy link
Copy Markdown

I developed a SVGA3D implementation for QEMU, that allows for GPU acceleration (DirectX 9 and 11).

You can try it out by downloading the binary from: https://github.com/qemus/qemu-vmvga

The main advantage is that it uses the existing VMware drivers, that means working (and signed) drivers already exist for Windows 11 till 7, Vista, XP, 2000 and even Win9x. So basically any Windows version ever released.

It works fine for desktop compositing, and most games. In heavy 3D benchmarks the scores are nowhere near bare metal, so there is some room left for future optimizations. But for accelerated desktop usage it is more than sufficient.

Feel free to play around with it, or to report issues to the repo.

@stuaxo

stuaxo commented Oct 5, 2026

Copy link
Copy Markdown

Really nice work from all the contributors on VMSVGA2 - could this end up upstreamed so it comes with qemu by default ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.