gfx-rs / wgpu

A cross-platform, safe, pure-Rust graphics API.
https://wgpu.rs
Apache License 2.0
11.65k stars 863 forks source link

Support DX12 in WSL #1443

Open slymon99 opened 3 years ago

slymon99 commented 3 years ago

Microsoft recently released WSLG support for GUI linux applications on windows subsystem for linux. I've enabled all the steps for WSLG and am able to successfully run applications using it (VLC for example) but run into errors when trying to run wgpu examples.

$ cargo run --example cube
[2021-04-22T18:52:22Z ERROR smithay_client_toolkit::window::concept_frame] No font could be found
[2021-04-22T18:52:22Z ERROR gfx_backend_vulkan]
    GENERAL [Loader Message (0x0)] : setupLoaderTermPhysDevs:  Failed to detect any valid GPUs in the current config
    object info: (type: INSTANCE, hndl: 0x563df2c1bfd0)

[2021-04-22T18:52:22Z ERROR gfx_backend_vulkan]
    GENERAL [Loader Message (0x0)] : setupLoaderTrampPhysDevs:  Failed during dispatch call of 'vkEnumeratePhysicalDevices' to lower layers or loader to get count.
    object info: (type: INSTANCE, hndl: 0x563df2c1bfd0)

[2021-04-22T18:52:22Z ERROR gfx_backend_vulkan] Could not enumerate physical devices! Initialization of a object has failed
thread 'main' panicked at 'No suitable GPU adapters found on the system!', examples/cube/../framework.rs:143:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Segmentation fault

I'm currently trying to figure out how to make this work myself and would love any pointers as I'm new to this area. WSLG works through a fairly complex set of abstractions, so I'm not exactly sure where to start. However, it seems like this might not require a huge amount of effort if we can use those abstractions, as WSLG is intended to support linux applications out of the box.

kvark commented 3 years ago

I don't think you can get any Vulkan under WSLG. It only supports OpenGL.

slymon99 commented 3 years ago

Ah, if I export WGPU_BACKEND=gl I get

[2021-04-22T19:12:58Z ERROR smithay_client_toolkit::window::concept_frame] No font could be found
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: DlSym { desc: "/lib/x86_64-linux-gnu/libX11.so: undefined symbol: wl_egl_window_create" }', /home/sclark/.cargo/git/checkouts/gfx-e86e7f3ebdbc4218/6999171/src/backend/gl/src/window/egl.rs:403:22

which seems more fixable?

looking into the line that errors

let wl_egl_window_create: libloading::Symbol<WlEglWindowCreateFun> = self
    .wsi_library
    .as_ref()
    .expect("unsupported window")
    .get(b"wl_egl_window_create")
    .unwrap();

It looks like libloading can't find the wayland egl? I tried installing libwayland-egl-backend-dev but this did not fix it. Again, just looking for pointers for areas to keep looking as this is a new area for me, let me know if you need more information

kvark commented 3 years ago

Would be good to first see if other EGL-based apps work. Could be that WSLG is only for desktop GL?

slymon99 commented 3 years ago

Also looking into the top level origination of this error comes from smithay_client_toolkit::window::concept_frame, which was replaced recently and "Dependency on andrew and fontconfig is dropped in the process." I'm going to try to see if upgrading smithay client toolkit might fix this error

slymon99 commented 3 years ago

Would be good to first see if other EGL-based apps work. Could be that WSLG is only for desktop GL?

The WSLG docs say "enable support for running Linux GUI applications (X11 and Wayland)", and the list of applications has some fairly sophisticated examples (browsers) that I believe use EGL? Chrome uses angle for example

kvark commented 3 years ago

Ok, in this case we need to find out why they are able to locate libEGL but we aren't.

niklaskorz commented 3 years ago

So this is the edgiest of edge cases, but WSL also supports DX12 (Direct3D 12) through libd3d12.so.

https://devblogs.microsoft.com/directx/directx-heart-linux/

This is the real and full D3D12 API, no imitations, pretender or reimplementation here… this is the real deal. libd3d12.so is compiled from the same source code as d3d12.dll on Windows but for a Linux target. It offers the same level of functionality and performance (minus virtualization overhead). The only exception is Present(). There is currently no presentation integration with WSL as WSL is a console only experience today. The D3D12 API can be used for offscreen rendering and compute, but there is no swapchain support to copy pixels directly to the screen (yet 😊).

If use of compute shaders through wgpu-rs for acceleration of Rust programs and libraries becomes more widespread (e.g., for machine learning?), I could imagine this to be pretty useful.

kvark commented 3 years ago

ah, so you are asking about D3D12 support on Linux, I see.

Dispersia commented 2 years ago

works

got the d3d12/gl extensions to work (mostly).

Things that I had to change to get it to work:

  1. Update winit to master, smithay toolkit updated that's required to fix the wayland client
  2. under wgpu-hal/src/gles/egl.rs, the test_wayland_display looks for "libwayland-client.so", and "libwayland-egl.so", however I only have these: "libwayland-client.so.0", and "libwayland-egl.so.1" and just changing it to that worked. (whatever installed libwayland didn't create symlinks, i guess?)
  3. Apparently the mesa drivers that ship with any OS is super old, so you need to install kisak-mesa (or any other bleeding edge version of mesa) to get working extensions.

Otherwise, most things seem to run fine besides winit/wayland-client issues, and storage buffers for some reason aren't allowed (not currently implemented in the opengl implementation?), I get limit 'max_storage_buffer_binding_size' value 134217728 is better than allowed 0 but haven't looked more into that one yet, might be a me issue, but this seems to get it all working

Dispersia commented 2 years ago

a little more digging:

  1. apparently linux at some point auto creates a symlink of versioned shared objects, or that's what it looks like because the original libwayland-client.so now exists for me, but I didn't create it.
  2. kisak-mesa doesn't support opengl es 3.1, only 3.0, so things like storage/compute shaders don't work, unfortunately. HOWEVER, kisak-mesa 21.1 introduced lavapipe, which is a vulkan 1.1 software implementation. It says it's not conformant, and it's definitely a bit slower... but it all works, and it's pretty amazing. Just pass LIBGL_ALWAYS_SOFTWARE with WSLg and everything seems to run fine, and the development experience is bareable, at least to me.

So ya, either use directx -> opengl es 3.0, or vulkan 1.1 software. That seems to be the two current options.

boids

parasyte commented 2 years ago

2. under wgpu-hal/src/gles/egl.rs, the test_wayland_display looks for "libwayland-client.so", and "libwayland-egl.so", however I only have these: "libwayland-client.so.0", and "libwayland-egl.so.1" and just changing it to that worked. (whatever installed libwayland didn't create symlinks, i guess?)

That was fixed in #2336 👍