198 lines
8.9 KiB
Markdown
198 lines
8.9 KiB
Markdown
# Troubleshooting
|
|
|
|
## 1. `cargo build` fails with "no matching package"
|
|
|
|
**Symptom:** Build fails with `could not find package` for wgpu or winit.
|
|
|
|
**Cause:** Version typo in `Cargo.toml`. wgpu and winit have specific major versions.
|
|
|
|
**Fix:** Verify your dependency versions:
|
|
```toml
|
|
wgpu = "29"
|
|
winit = "0.30"
|
|
pollster = "0.4"
|
|
bytemuck = { version = "1", features = ["derive"] }
|
|
log = "0.4"
|
|
simple_logger = "5"
|
|
```
|
|
|
|
## 2. Window opens but shows black screen
|
|
|
|
**Symptom:** Window appears but is entirely black. No triangle visible.
|
|
|
|
**Cause:** One (or more) of several common rendering misconfigurations:
|
|
- Pipeline not set: `pass.set_pipeline()` not called
|
|
- Vertex buffer not bound: `pass.set_vertex_buffer()` not called
|
|
- Draw call wrong: `draw()` arguments incorrect (must be `draw(0..3, 0..1)` — two ranges)
|
|
- Triangle wound clockwise: `FrontFace::Ccw` requires counter-clockwise vertex order
|
|
- Format mismatch: `ColorTargetState::format` must match `SurfaceConfiguration::format`
|
|
- Present omitted: `surface_texture.present()` must be called to show rendered frame
|
|
|
|
**Fix:** Check each item above. Verify the pipeline is set, buffer is bound, draw uses two `Range<u32>` arguments, vertices are CCW, formats match, and `present()` is called.
|
|
|
|
## 3. Washed-out or wrong colors
|
|
|
|
**Symptom:** Triangle renders but colors look dull or incorrect.
|
|
|
|
**Cause:** `SurfaceConfiguration::view_formats` missing `add_srgb_suffix()`. Without sRGB gamma correction, colors appear washed out.
|
|
|
|
**Fix:** Ensure `view_formats` includes the sRGB variant:
|
|
```rust
|
|
view_formats: vec![format.add_srgb_suffix()],
|
|
```
|
|
|
|
## 4. "No adapter found"
|
|
|
|
**Symptom:** Program crashes or logs "No GPU adapter found" during startup.
|
|
|
|
**Cause:** wgpu cannot find a compatible graphics adapter. This can happen
|
|
across all platforms for different reasons.
|
|
|
|
**Fix:**
|
|
|
|
- **Windows:** Ensure your GPU supports DirectX 12 (WDDM 2.0+). Update GPU
|
|
drivers from the manufacturer's website (NVIDIA, AMD, or Intel). Some
|
|
integrated GPUs may require a Windows 10+ build. If DX12 is unavailable,
|
|
install the LunarG Vulkan Runtime.
|
|
- **macOS:** Metal is required. Ensure your GPU supports Metal (all Macs
|
|
from 2012 onward). Update macOS to the latest version. If you're on
|
|
Apple Silicon, wgpu will automatically use the Metal backend.
|
|
- **Linux:** Install Vulkan drivers and tools:
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt install vulkan-tools mesa-vulkan-drivers
|
|
# Arch
|
|
sudo pacman -S vulkan-tools vulkan-radeon # or vulkan-intel / nvidia-utils
|
|
vulkaninfo # verify installation
|
|
```
|
|
|
|
## 5. "Adapter not compatible" (macOS / Metal)
|
|
|
|
**Symptom:** wgpu reports that no adapter is compatible with the surface.
|
|
|
|
**Cause:** On macOS, wgpu uses Metal exclusively. If the GPU does not support
|
|
Metal (e.g., very old Mac hardware or a GPU below Metal 2.0), no adapter will
|
|
be found.
|
|
|
|
**Fix:** Verify your Mac supports Metal. Check `System Information > Graphics`
|
|
in macOS. If Metal is not supported, the GPU cannot be used with wgpu.
|
|
|
|
## 6. "Surface lost"
|
|
|
|
**Symptom:** Program crashes with a surface lost error during rendering, or the
|
|
window renders blanks after being minimized/restored.
|
|
|
|
**Cause:** The display server or GPU context was reset. The
|
|
[Surface](concepts/GLOSSARY.md#surface) is permanently invalidated. Common
|
|
triggers include:
|
|
- Window minimized and restored (some display servers)
|
|
- Display configuration changed (hotplug, external monitor connected/disconnected)
|
|
- GPU driver reset
|
|
- Compositor restart (Linux/Wayland)
|
|
|
|
**Fix:** Handle the `CurrentSurfaceTexture::Lost` variant gracefully. In the
|
|
tutorial, this means the window may need to be reopened. In production code,
|
|
set `self.state = None`, then on the next redraw event, re-run the full
|
|
`State::new()` initialization chain to recreate all GPU resources.
|
|
|
|
## 7. Wayland surface crashes or doesn't render (Linux only)
|
|
|
|
**Symptom:** Program crashes or shows blank window on Wayland compositors
|
|
(Sway, GNOME Shell, KDE Plasma, etc.).
|
|
|
|
**Cause:** winit's Wayland backend may have compatibility issues with certain
|
|
compositors or Vulkan/Wayland interop layers.
|
|
|
|
**Fix:** Temporarily force the X11 backend:
|
|
```bash
|
|
WINIT_UNIX_BACKEND=x11 cargo run
|
|
```
|
|
|
|
If X11 works but Wayland does not, check your compositor version and winit
|
|
version. This is a Linux-specific issue and does not affect Windows or macOS.
|
|
|
|
## 8. Window won't close
|
|
|
|
**Symptom:** Clicking the X button or pressing Escape doesn't close the window.
|
|
|
|
**Cause:** `ApplicationHandler::exiting()` not implemented, or `event_loop_ctl.exit()` not called.
|
|
|
|
**Fix:** Ensure `exiting()` (note: NOT `closing()`) is implemented:
|
|
```rust
|
|
fn exiting(&mut self, event_loop_ctl: &ActiveEventLoop) {
|
|
event_loop_ctl.exit();
|
|
}
|
|
```
|
|
|
|
## 9. CPU at 100%
|
|
|
|
**Symptom:** One CPU core at 100% usage.
|
|
|
|
**Cause:** `ControlFlow::Poll` drives `RedrawRequested` events continuously. Every frame renders and queues another redraw. This is the expected behavior for a `ControlFlow::Poll` render loop.
|
|
|
|
**Fix:** No fix needed — this is expected for a continuous redraw demo. For production, switch to `ControlFlow::Wait` and call `request_redraw()` only when state changes.
|
|
|
|
## 10. Shader compilation or pipeline creation error
|
|
|
|
**Symptom:** Program panics during `create_render_pipeline` with a shader validation error.
|
|
|
|
**Cause:** `@location` numbers in WGSL don't match `shader_location` numbers in Rust's `VertexAttribute`, or `@builtin(position)` is missing from vertex shader output.
|
|
|
|
**Fix:** Check the log output for validation messages. Verify:
|
|
- WGSL `@location(0)` matches Rust `shader_location: 0`
|
|
- WGSL `@location(1)` matches Rust `shader_location: 1`
|
|
- Vertex shader outputs `@builtin(position) clip_position: vec4<f32>`
|
|
|
|
## 11. Triangle shows one solid color instead of gradient
|
|
|
|
**Symptom:** Triangle renders but is a single uniform color instead of smoothly blending.
|
|
|
|
**Cause:** Fragment shader returns a constant color instead of passing through `input.vertex_color`. The [rasterizer](concepts/GLOSSARY.md#rasterizer) interpolates vertex colors automatically, but only if the fragment shader uses them.
|
|
|
|
**Fix:** Ensure fragment shader returns the interpolated vertex color:
|
|
```wgsl
|
|
@fragment
|
|
fn fs_main(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
return vec4<f32>(input.vertex_color, 1.0);
|
|
}
|
|
```
|
|
|
|
Not this (which returns a solid color):
|
|
```wgsl
|
|
return vec4<f32>(1.0, 1.0, 1.0, 1.0); // wrong: solid white
|
|
```
|
|
|
|
## 12. WGSL shader compilation errors
|
|
|
|
**Symptom:** Program panics or logs errors during `device.create_shader_module()` or `create_render_pipeline()` with messages referencing WGSL validation failures.
|
|
|
|
**Cause:** wgpu validates WGSL shaders at pipeline creation time, not at runtime. Errors surface immediately when the shader module is created or when the render pipeline references it. Common causes include:
|
|
- Syntax errors: typos in WGSL (missing semicolons, mismatched braces, incorrect keywords)
|
|
- Type mismatches: passing `vec2<f32>` where `vec4<f32>` is expected, or mixing signed/unsigned types
|
|
- Missing `@location` or `@builtin` attributes: vertex/fragment shader I/O without proper decoration
|
|
- Entry point not found: the `@vertex` or `@fragment` function name doesn't match the pipeline descriptor's `entry_point` field
|
|
|
|
**Fix:** Read wgpu's error messages carefully — they include the shader source line and column where the issue was detected. Follow this checklist:
|
|
- Check the reported line/column in your WGSL source for syntax issues
|
|
- Verify all type signatures match between vertex shader output and fragment shader input
|
|
- Ensure every varying uses `@location(N)` and position output uses `@builtin(position)`
|
|
- Confirm the function name in your `@vertex`/`@fragment` declaration matches the string you pass to `ProgrammableStage::entry_point`
|
|
- If the error message is unclear, try compiling the shader in isolation to isolate syntax vs. pipeline-binding issues
|
|
|
|
## 13. GPU debugging with RenderDoc
|
|
|
|
**Symptom:** Rendering issues that are difficult to diagnose (artifacts, wrong output, silent failures).
|
|
|
|
**Cause:** GPU debugging is hard with standard tools. Graphics pipeline state, shader execution, and buffer contents are not easily inspectable at runtime.
|
|
|
|
**Fix:** Use [RenderDoc](https://renderdoc.org/) — a standalone GPU debugging tool supporting frame capture, pipeline state inspection, and shader debugging. It works with Vulkan (Linux), DX12/DX11 (Windows), and Metal (macOS). Launch RenderDoc, attach to your wgpu process, and capture frames to inspect the full graphics pipeline step by step. On macOS, RenderDoc supports Metal 2.0+ devices.
|
|
|
|
## Additional Resources
|
|
|
|
- [Glossary](concepts/GLOSSARY.md) — Every term defined
|
|
- [Graphics Pipeline](concepts/graphics-pipeline.md) — Pipeline stage overview
|
|
- [Coordinate Systems](concepts/coordinate-systems.md) — NDC and transformation spaces
|
|
- [Shader Basics](concepts/shader-basics.md) — WGSL and shader concepts
|
|
- [wgpu documentation](https://docs.rs/wgpu/29.0.0/) — Official wgpu 29 API docs
|
|
- [wgpu repository](https://github.com/gfx-rs/wgpu) — Examples and issue tracker
|