Skip to content

Commit d045c4f

Browse files
fix(windows): revert editor to RGBA output and fix DX12 adapter selection
Two issues discovered during testing on Windows with NVIDIA RTX 2000: 1. The NV12 render pipeline (RgbaToNv12Converter compute shader + buffer readback) hangs on the Vulkan backend, causing BufferAsyncError and preventing any frame from being delivered to the editor. Reverted the editor renderer back to the proven render_immediate() RGBA path which works reliably on all backends. The NV12 path remains available for export where it has been battle-tested. 2. The DX12 | Vulkan backend specification allowed wgpu to pick Vulkan over DX12 (seen in logs: adapter_backend=Vulkan despite DX12 being listed). This prevents D3D11 shared handle zero-copy since that requires a D3D12 device. Fixed by creating a DX12-only instance first to probe for DX12 availability, then falling back to all backends only if DX12 isn't available. This ensures DX12 is used when present. Co-authored-by: Richie McIlroy <richiemcilroy@users.noreply.github.com>
1 parent e53808a commit d045c4f

File tree

3 files changed

+55
-47
lines changed

3 files changed

+55
-47
lines changed

apps/desktop/src-tauri/src/gpu_context.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,32 @@ pub struct SharedGpuContext {
4949
static GPU: OnceCell<Option<SharedGpuContext>> = OnceCell::const_new();
5050

5151
async fn init_gpu_inner() -> Option<SharedGpuContext> {
52-
#[cfg(target_os = "windows")]
53-
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
54-
backends: wgpu::Backends::DX12 | wgpu::Backends::VULKAN,
55-
..Default::default()
56-
});
5752
#[cfg(not(target_os = "windows"))]
5853
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
5954

55+
#[cfg(target_os = "windows")]
56+
let instance = {
57+
let dx12_instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
58+
backends: wgpu::Backends::DX12,
59+
..Default::default()
60+
});
61+
let has_dx12 = dx12_instance
62+
.request_adapter(&wgpu::RequestAdapterOptions {
63+
power_preference: wgpu::PowerPreference::HighPerformance,
64+
force_fallback_adapter: false,
65+
compatible_surface: None,
66+
})
67+
.await
68+
.is_ok();
69+
if has_dx12 {
70+
tracing::info!("Using DX12 backend for shared GPU context");
71+
dx12_instance
72+
} else {
73+
tracing::info!("DX12 not available for shared context, falling back to all backends");
74+
wgpu::Instance::new(&wgpu::InstanceDescriptor::default())
75+
}
76+
};
77+
6078
let hardware_adapter = instance
6179
.request_adapter(&wgpu::RequestAdapterOptions {
6280
power_preference: wgpu::PowerPreference::HighPerformance,

crates/editor/src/editor.rs

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -147,48 +147,20 @@ impl Renderer {
147147
break;
148148
}
149149
}
150-
let nv12_result = frame_renderer
151-
.render_nv12(
152-
current.segment_frames.clone(),
153-
current.uniforms.clone(),
150+
match frame_renderer
151+
.render_immediate(
152+
current.segment_frames,
153+
current.uniforms,
154154
&current.cursor,
155155
&mut layers,
156156
)
157-
.await;
158-
159-
match nv12_result {
160-
Ok(pipeline_frame) => {
161-
if let Some(prev) = pipeline_frame {
162-
(self.frame_cb)(EditorFrameOutput::Nv12(prev));
163-
}
164-
match frame_renderer.flush_pipeline_nv12().await {
165-
Some(Ok(current_frame)) => {
166-
(self.frame_cb)(EditorFrameOutput::Nv12(current_frame));
167-
}
168-
Some(Err(e)) => {
169-
tracing::warn!(error = %e, "Failed to flush NV12 pipeline frame");
170-
}
171-
None => {}
172-
}
157+
.await
158+
{
159+
Ok(frame) => {
160+
(self.frame_cb)(EditorFrameOutput::Rgba(frame));
173161
}
174162
Err(e) => {
175-
tracing::warn!(error = %e, "NV12 render failed, falling back to RGBA");
176-
match frame_renderer
177-
.render_immediate(
178-
current.segment_frames,
179-
current.uniforms,
180-
&current.cursor,
181-
&mut layers,
182-
)
183-
.await
184-
{
185-
Ok(frame) => {
186-
(self.frame_cb)(EditorFrameOutput::Rgba(frame));
187-
}
188-
Err(e) => {
189-
tracing::error!(error = %e, "Failed to render frame in editor");
190-
}
191-
}
163+
tracing::error!(error = %e, "Failed to render frame in editor");
192164
}
193165
}
194166

crates/rendering/src/lib.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -979,14 +979,32 @@ impl RenderVideoConstants {
979979
.map(|c| XY::new(c.width, c.height)),
980980
};
981981

982-
#[cfg(target_os = "windows")]
983-
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
984-
backends: wgpu::Backends::DX12 | wgpu::Backends::VULKAN,
985-
..Default::default()
986-
});
987982
#[cfg(not(target_os = "windows"))]
988983
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor::default());
989984

985+
#[cfg(target_os = "windows")]
986+
let instance = {
987+
let dx12_instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
988+
backends: wgpu::Backends::DX12,
989+
..Default::default()
990+
});
991+
let has_dx12 = dx12_instance
992+
.request_adapter(&wgpu::RequestAdapterOptions {
993+
power_preference: wgpu::PowerPreference::HighPerformance,
994+
force_fallback_adapter: false,
995+
compatible_surface: None,
996+
})
997+
.await
998+
.is_ok();
999+
if has_dx12 {
1000+
tracing::info!("Using DX12 backend for optimal D3D11 interop");
1001+
dx12_instance
1002+
} else {
1003+
tracing::info!("DX12 not available, falling back to all backends");
1004+
wgpu::Instance::new(&wgpu::InstanceDescriptor::default())
1005+
}
1006+
};
1007+
9901008
let hardware_adapter = instance
9911009
.request_adapter(&wgpu::RequestAdapterOptions {
9921010
power_preference: wgpu::PowerPreference::HighPerformance,

0 commit comments

Comments
 (0)