Dioxusの入門者向けのexamples集の中でバグのあるものを修正する。
VS codeにGeminiCodeAssistantを入れて、修正してもらってます。
今回のお題は "wgpu_child_window.rs"
cargo run --example wgpu_child_window --features="gpu"
で以下のエラーが出ます:
thread 'main' panicked at D:\Rust\cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-0.20.1\src\backend\wgpu_core.rs:751:18:
Error in Surface::configure: Validation Error
Caused by: Requested alpha mode PreMultiplied is not in the list of supported alpha modes: [Opaque]
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace error: process didn't exit successfully: target\debug\examples\wgpu_child_window.exe (exit code: 101)
Gemini:This tells us that you're trying to configure the wgpu surface with the PreMultiplied alpha mode, but the current graphics driver/hardware combination only supports the Opaque alpha mode. This can happen on different systems, and robust graphics code should handle it by querying for supported modes instead of hardcoding one.
The fix is to determine the supported alpha modes from the surface capabilities and use one of those, typically the first one available.
Here are the changes for
height: size.height,
present_mode: wgpu::PresentMode::Fifo,
desired_maximum_frame_latency: 2,
- alpha_mode: wgpu::CompositeAlphaMode::PreMultiplied,
+ alpha_mode: swapchain_capabilities.alpha_modes[0],
view_formats: vec![],
};
Explanation:
In the GraphicsResources::new function, the wgpu::SurfaceConfiguration was hardcoded to use wgpu::CompositeAlphaMode::PreMultiplied. While this works on many systems for transparency, it's not universally supported.
The fix involves using the swapchain_capabilities that were already being queried from the adapter. This struct contains a list of supported alpha_modes. By changing alpha_mode to swapchain_capabilities.alpha_modes[0], we ensure that we're always using a valid alpha mode supported by the user's machine, making the example more robust.
上記のアダプタでクエリ済みとは:
// d:\tmp\examples\wgpu_child_window.rs の一部
impl<'a> GraphicsResources<'a> {
async fn new(context: &'a DesktopContext) -> Self {
// ... (インスタンス、サーフェス、アダプターの取得) ...
// ... (デバイスとキューの取得) ...
// ... (シェーダーとパイプラインレイアウトの作成) ...
// ↓↓↓ ここです! ↓↓↓
let swapchain_capabilities = surface.get_capabilities(&adapter);
let swapchain_format = swapchain_capabilities.formats[0];
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
// ...
fragment: Some(wgpu::FragmentState {
// ...
targets: &[Some(swapchain_format.into())], // ここで capabilities の format が使われます
// ...
}),
// ...
});
let config = wgpu::SurfaceConfiguration {
// ...
format: swapchain_format, // ここでも format が使われます
// ...
alpha_mode: swapchain_capabilities.alpha_modes[0], // ここで capabilities の alpha_mode が使われます
// ...
};
surface.configure(&device, &config);
// ...
}
// ...
}
Geminiの解説:
let surface: wgpu::Surface<'a> = instance.create_surface(window).unwrap(); でウィンドウに描画するためのサーフェスが作成されます。
let adapter = instance.request_adapter(...) で、このサーフェスに描画できる物理的なグラフィックスデバイス(アダプター)が選択されます。
そして、ご質問の箇所である let swapchain_capabilities = surface.get_capabilities(&adapter); が実行されます。
surface.get_capabilities(&adapter) メソッドは、そのサーフェスとアダプターの組み合わせでサポートされている機能の一覧を wgpu::SurfaceCapabilities という構造体で返します。
この構造体には、サポートされているテクスチャフォーマットのリスト (formats) や、サポートされているアルファ合成モードのリスト (alpha_modes) などが含まれています。
今回の修正では、この swapchain_capabilities からサポートされているアルファモードのリストを取得し、その最初の要素 (swapchain_capabilities.alpha_modes[0]) を使うように変更した、というわけです。👌
参照先のTauri版
https://github.com/tauri-apps/wry/blob/dev/examples/wgpu.rs
をチェックしたい。