Skip to content

gpui: Remove blade, reimplement linux renderer with wgpu#46758

Merged
reflectronic merged 27 commits intozed-industries:mainfrom
zortax:wgpu
Feb 13, 2026
Merged

gpui: Remove blade, reimplement linux renderer with wgpu#46758
reflectronic merged 27 commits intozed-industries:mainfrom
zortax:wgpu

Conversation

@zortax
Copy link
Contributor

@zortax zortax commented Jan 14, 2026

The blade graphics library is a mess and causes several issues for both Zed users as well as other 3rd party apps using GPUI. This PR removes blade and implements the linux platform using wgpu which is the de-facto standard in the rust UI and graphics ecosystem. This will not just fix issues that Zed users have today, but also profit from wgpu improvements in the futures, from other projects contributing (such as the bevy game engine, Iced, or pretty much every other relevant project).

This will close several related issues on the zed repo as well. See https://github.com/zed-industries/zed/issues?q=frozen%20nvidia%20linux (probably not all of them, have only tested the freeze on nvidia and Smithay-based wayland compositors).

Some related issues:
#44814
#40481
niri-wm/niri#2335
zortax/zlaunch#15

Would appreciate feedback if this is something the zed maintainers would be interested in.

Release Notes:

  • N/A

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Jan 14, 2026
@zed-community-bot zed-community-bot bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label Jan 14, 2026
@maxdeviant maxdeviant changed the title remove blade, reimplement linux renderer with wgpu gpui: Remove blade, reimplement linux renderer with wgpu Jan 14, 2026
@zed-industries-bot
Copy link
Contributor

zed-industries-bot commented Jan 14, 2026

Messages
📖

This PR includes links to the following GitHub Issues: #niri-wm/niri#2335, #44814, #40481, #zortax/zlaunch#15
If this PR aims to close an issue, please include a Closes #ISSUE line at the top of the PR body.

Generated by 🚫 dangerJS against f988a34

@reflectronic
Copy link
Member

Thank you for the pull request. Yes, we are interested in this approach. From a brief look at the patch, things look good at a high level. I will make time for a deeper review soon.

use metal_renderer as renderer;

#[cfg(feature = "macos-blade")]
use crate::platform::blade as renderer;

Choose a reason for hiding this comment

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

Since WGPU is a cross-platform API, I think it would be nice to be able to use it on Mac and Windows builds via a feature flag, similar to how macos-blade previously enabled the Blade renderer on Mac.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, but I can't test that, don't have the necessary hardware

Choose a reason for hiding this comment

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

Since WGPU is a cross-platform API, I think it would be nice to be able to use it on Mac and Windows builds via a feature flag, similar to how macos-blade previously enabled the Blade renderer on Mac.

With Zed moving to wgpu (WebGPU), does this mean a web-based client is now technically possible, similar to Flutter Web?

Choose a reason for hiding this comment

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

@bamboo512 There is significant work beyond the renderer that would need to happen to run Zed in a browser - notably background tasks and filesystem/input APIs would need web/wasm-compatible implementations.

Copy link

@TimTheBig TimTheBig Mar 2, 2026

Choose a reason for hiding this comment

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

True, I do think that WASI as a minimum feature-set would ease that work

// Safety: The caller guarantees that the window handle is valid for the
// lifetime of this renderer. In practice, the RawWindow struct is created
// from the native window handles and the surface is dropped before the window.
let surface = unsafe {

Choose a reason for hiding this comment

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

Is it worth using SurfaceTargetUnsafe::from_window?

        let surface = unsafe {
            context
                .instance
                .create_surface_unsafe(
                    wgpu::SurfaceTargetUnsafe::from_window(window)
                        .map_err(|e| anyhow::anyhow!("Failed to create surface target: {e}"))?,
                )
                .map_err(|e| anyhow::anyhow!("Failed to create surface: {e}"))?
        };

Copy link
Contributor Author

@zortax zortax Jan 15, 2026

Choose a reason for hiding this comment

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

To be honest I think this is "unnecessary complexity", since, as far as I understand, in the current implementation we would still wrap the underlying error. The only difference with this is the separate wrapper message, but the underlying error should make it very clear which error path was hit anyway, but please correct me if I'm wrong.

Choose a reason for hiding this comment

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

We wouldn't gain much by using their function over manually doing it ourselves, and it's a fair argument that the error messages in the more manual case are less layered. It's probably not important in practice to see directly in the error that we failed to get a window or display handle while creating a surface target, because you are going to see that context by virtue of where the error occurs (in the creation of the renderer).

@zortax
Copy link
Contributor Author

zortax commented Jan 17, 2026

I believe this PR closes the following issues:
#39097
#44814
#45836
#40481
#38497

There are some other issues this might close, but haven't tested/reproduced:
#40361
#44252

@bowenxuuu
Copy link
Contributor

Will there be plans to use wgpu for the Windows and macOS platforms in the future?

@reflectronic
Copy link
Member

I don't think we plan to replace the Windows or macOS renderers at this time. Our native renderers on those platforms probably have better performance and wider compatibility than WGPU.

@zortax
Copy link
Contributor Author

zortax commented Jan 23, 2026

wider compatibility than WGPU

Not super familiar with CF, metal and the macos ecosystem, but why do you think using metal directly results in wider compatibility? Does it not just use metal on macos anyway? Just curious, not trying to push that change. I know there are also people relying on CF stuff for e.g. hardware accelerated video decoding etc.

@reflectronic
Copy link
Member

Well, I'm not sure if it's true on macOS, sorry. On Windows, I believe we support some GPUs that don't have DirectX 12.

@zortax
Copy link
Contributor Author

zortax commented Jan 23, 2026

Again, not trying to push anything, but wouldn't wgpu not increase the range of supported devices, specifically on windows, given the different backends it supports? On windows it supports vulkan, DirectX12 directly, and also has a ANGLE based backend, that, if I understand correctly, would support OpenGL ES and DirectX9 and up. Please correct me if I'm wrong, again, not super familiar with any platforms other than linux, but I'd assume that using wgpu would pretty much maximize device compatibility with minimum effort, with even WebGPU or WebGL becoming a possibility...

@bowenxuuu
Copy link
Contributor

WGPU consumes more memory than gpui's custom renderer. On my Windows 11 machine, launching an empty window with WGPU uses around 100MB of memory (I used the official WGPU example), while an identical empty window with gpui only takes up about 10MB.

@zortax
Copy link
Contributor Author

zortax commented Jan 23, 2026

WGPU consumes more memory than gpui's custom renderer. On my Windows 11 machine, launching an empty window with WGPU uses around 100MB of memory (I used the official WGPU example), while an identical empty window with gpui only takes up about 10MB.

Probably a fair argument, but would be interesting to see how big the difference is once you actually render anything significant. There are also some ways to reduce initial memory usage with wgpu (see e.g. MemoryHints), I believe by default wgpu pre-allocates relatively big buffers. Probably will still use more than a manual DX12 implementation..

@reflectronic
Copy link
Member

Hm, right, I suppose OpenGL ES will have broad compatibility (likely even broader than what we target for D3D11). I'm not sure if WGPU is using ANGLE or native OpenGL drivers for that. In general, the native drivers for Khronos APIs are somewhat buggier and have higher latency (DirectX has special presentation paths through the composition engine) than D3D. ANGLE might be OK, but our workload is simple enough that, in my opinion, it's worth having a DirectX 11 renderer that avoids the need for multiple translation layers.

@zeux
Copy link
Contributor

zeux commented Jan 29, 2026

This PR causes a significant regression in VRAM usage for me.

Here's nvtop comparing current production builds vs a local build off this branch; I verified that a local debug build off the commit on this branch before blade removal has the same VRAM requirement as the production build. The window sizes of two Zed instances are the same (2540x2076). This is running on a 4K screen (3840x2160), with DPI scaling 1.5x, using niri compositor on Ubuntu 25.10.

image

Here's nvtop with both windows maximized:

image

@zortax
Copy link
Contributor Author

zortax commented Jan 30, 2026

@zeux Wouldn't call 30MiB "significant regression", but anyway, I can't reproduce this. On my system, zed built from commit this branch is based on sits at 542M, latest commit on this PR settles at 537M, slightly better (4k resolution, same window size, project, open files etc.). This is also similar for my zlaunch launcher using gpui, which also actually seems to sit at slightly less memory usage with the wgpu implementation. We could set Memory hints to prefer smaller buffers over performance, but I don't think that will make much difference in practice. The wgpu renderer is essentially a port of the blade implementation, so except some differences in wgpu's buffer allocation I don't expect any significant difference.

@zeux
Copy link
Contributor

zeux commented Jan 30, 2026

@zortax Re: 30 MB difference - you are looking at the wrong column in my screenshots; the rightmost column is "host memory" which I'm not interested in; the 6th column accounts for GPU memory allocation and that is where the difference is significant for me.

@Akiyamka
Copy link

How to disable this? after update editor constantly freezes on Radeon 780M Graphic (Framework Laptop)

@jlucaso1
Copy link

How to disable this? after update editor constantly freezes on Radeon 780M Graphic (Framework Laptop)

Can you provide some debug logs? I've tested here in a rx 6600 and it's running fine. Also check if you are using the latest mesa version

@Akiyamka
Copy link

Akiyamka commented Feb 26, 2026

@jlucaso1 Could you please advice me how to collect them? There's nothing interesting in `~/.local/share/zed/logs/Zed.log`, and regarding profiling, the documentation only mentions macOS. https://zed.dev/docs/troubleshooting#performance-issues-profiling

Mesa version on my host

$ rpm -q mesa-libGL  
mesa-libGL-25.1.9-1.fc42.x86\_64  
mesa-libGL-25.1.9-1.fc42.i686  

@Akiyamka
Copy link

@jlucaso1 i collect related info in this issue.
#50229

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

Labels

cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zed Editor is broken in Niri