gpui_wgpu: Guard against device feature mismatch (#52820)

Oleksiy Syvokon created

This should prevent the "wgpu-hal invariant was violated (usage error):
Requested feature is not available on this device" panic, although I'm
not 100% sure (there's a possibility that a device reports the feature
but fails to use it). At the very least, we get more logging

I've tested this fix by patching code to emulate a situation where
device features change after the creation, but that may be not
representative of the real world failure.


Addresses ZED-5G1

Release Notes:

- N/A

Change summary

crates/gpui_wgpu/src/wgpu_renderer.rs | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

Detailed changes

crates/gpui_wgpu/src/wgpu_renderer.rs 🔗

@@ -615,6 +615,28 @@ impl WgpuRenderer {
         path_sample_count: u32,
         dual_source_blending: bool,
     ) -> WgpuPipelines {
+        // Diagnostic guard: verify the device actually has
+        // DUAL_SOURCE_BLENDING. We have a crash report (ZED-5G1) where a
+        // feature mismatch caused a wgpu-hal abort, but we haven't
+        // identified the code path that produces the mismatch. This
+        // guard prevents the crash and logs more evidence.
+        // Remove this check once:
+        // a) We find and fix the root cause, or
+        // b) There are no reports of this warning appearing for some time.
+        let device_has_feature = device
+            .features()
+            .contains(wgpu::Features::DUAL_SOURCE_BLENDING);
+        if dual_source_blending && !device_has_feature {
+            log::error!(
+                "BUG: dual_source_blending flag is true but device does not \
+                 have DUAL_SOURCE_BLENDING enabled (device features: {:?}). \
+                 Falling back to mono text rendering. Please report this at \
+                 https://github.com/zed-industries/zed/issues",
+                device.features(),
+            );
+        }
+        let dual_source_blending = dual_source_blending && device_has_feature;
+
         let base_shader_source = include_str!("shaders.wgsl");
         let shader_module = device.create_shader_module(wgpu::ShaderModuleDescriptor {
             label: Some("gpui_shaders"),