docs: append S9-S11, add README and TROUBLESHOOTING
This commit is contained in:
@@ -1255,3 +1255,96 @@ succession. `surface.configure()` is fast enough to handle this — each call
|
||||
discards old buffers and allocates new ones. The GPU continues processing
|
||||
in-flight frames with the old buffer dimensions; there is no visual glitch
|
||||
because the swapchain handles the transition seamlessly.
|
||||
|
||||
## S9: Where All the Code Goes
|
||||
|
||||
The full source is the codeblocks in sections S2–S8, assembled in order into
|
||||
`src/main.rs` and `src/shader.wgsl`.
|
||||
|
||||
### File Structure
|
||||
|
||||
```
|
||||
src/
|
||||
├── main.rs # Sections S2, S3, S5 (structs), S7 (render), S8 (resize)
|
||||
├── shader.wgsl # Section S4 (the complete WGSL shader)
|
||||
```
|
||||
|
||||
- `main.rs` combines the winit event loop (S2), the init chain and `State`
|
||||
struct (S3), the `Vertex` type and `VERTICES` constant (S5), the `render`
|
||||
method (S7), and the `resize` method (S8).
|
||||
- `shader.wgsl` is the single file from S4: vertex shader, fragment shader,
|
||||
and the `VertexOutput` struct.
|
||||
|
||||
Refer to [concepts/GLOSSARY.md](concepts/GLOSSARY.md) for term definitions used
|
||||
throughout these sections. See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for
|
||||
common issues and their fixes.
|
||||
|
||||
## S10: Running It
|
||||
|
||||
Run the project:
|
||||
|
||||
```bash
|
||||
cargo run
|
||||
```
|
||||
|
||||
**Expected console output:** wgpu adapter info (GPU model, driver name), shader
|
||||
module compilation log, pipeline creation messages, and the `simple_logger`
|
||||
debug lines from surface status and device polling.
|
||||
|
||||
**Expected visual:** A dark gray background (from `LoadOp::Clear`) with a
|
||||
rainbow triangle spanning most of the window. Red at the bottom-left corner,
|
||||
blue at the bottom-right corner, green at the top vertex. Colors blend smoothly
|
||||
across the triangle surface via hardware interpolation.
|
||||
|
||||
**Expected CPU usage:** 100% on one core due to `ControlFlow::Poll` driving a
|
||||
continuous redraw loop. This is normal for a demo that redraws every vsync.
|
||||
See [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues.
|
||||
|
||||
## S11: What You've Learned and What's Next
|
||||
|
||||
### Summary
|
||||
|
||||
You have built a complete GPU-rendered application from scratch. Here is what
|
||||
each piece does:
|
||||
|
||||
- **The 5-layer wgpu [init chain](concepts/GLOSSARY.md#instance):**
|
||||
[Instance](concepts/GLOSSARY.md#instance) →
|
||||
[Surface](concepts/GLOSSARY.md#surface) →
|
||||
[Adapter](concepts/GLOSSARY.md#adapter) →
|
||||
[Device](concepts/GLOSSARY.md#device) + [Queue](concepts/GLOSSARY.md#queue) →
|
||||
[SurfaceConfiguration](concepts/GLOSSARY.md#surface-configuration).
|
||||
Each layer adds a capability: driver connection, window binding, GPU selection,
|
||||
resource management, and swapchain allocation.
|
||||
|
||||
- **The [render pipeline](concepts/GLOSSARY.md#pipeline-render):** Shaders,
|
||||
topology, and vertex layout compiled into a GPU configuration. Created once,
|
||||
reused every frame. Expensive to create, cheap to execute.
|
||||
|
||||
- **The [command buffer](concepts/GLOSSARY.md#command-buffer) model:** Record
|
||||
instructions on the CPU, submit atomically to the queue, GPU executes
|
||||
asynchronously. No `.await` on a draw call.
|
||||
|
||||
- **The [swapchain](concepts/GLOSSARY.md#swapchain) and
|
||||
[framebuffer](concepts/GLOSSARY.md#framebuffer):** Double-buffered rendering
|
||||
through [PresentMode::Mailbox](concepts/GLOSSARY.md#present-mode). Acquire a
|
||||
back buffer, render into it, present it to the display.
|
||||
|
||||
- **GPU [interpolation](concepts/GLOSSARY.md#interpolation):** Vertex attributes
|
||||
automatically blended across triangle surfaces. You supply values at three
|
||||
points; the rasterizer computes every value in between.
|
||||
|
||||
### What's Next
|
||||
|
||||
With the render loop and pipeline foundation in place, the next steps are:
|
||||
|
||||
- **Textures and [bind groups](concepts/GLOSSARY.md#bind-group)** — loading
|
||||
images onto the GPU and sampling them in fragment shaders
|
||||
- **Uniforms and 3D transforms** — projection, view, and model matrices for
|
||||
positioning geometry in 3D space
|
||||
- **Lighting and material models** — diffuse, specular, and PBR shading
|
||||
- **Depth buffering and z-fighting** — per-pixel depth testing for correct
|
||||
overlap ordering
|
||||
- **[Compute shaders](concepts/GLOSSARY.md#compute-shader) and GPU compute
|
||||
pipelines** — general-purpose GPU computation outside the graphics pipeline
|
||||
|
||||
Keep [concepts/GLOSSARY.md](concepts/GLOSSARY.md) handy as you move forward.
|
||||
|
||||
28
docs/README.md
Normal file
28
docs/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# learn-wgpu
|
||||
|
||||
An educational book teaching Rust graphics programming with wgpu 29 + winit 0.30.
|
||||
|
||||
Built for backend/systems Rust developers who know Rust thoroughly but have zero
|
||||
graphics programming experience. Every sentence teaches GPU concepts — not Rust syntax.
|
||||
|
||||
## Required Reading Order
|
||||
|
||||
1. [The Graphics Pipeline](concepts/graphics-pipeline.md) — GPU vs CPU, the 5-stage pipeline
|
||||
2. [Coordinate Systems](concepts/coordinate-systems.md) — NDC, homogeneous coordinates, viewport
|
||||
3. [Shader Basics](concepts/shader-basics.md) — WGSL, vertex/fragment shaders, interpolation
|
||||
4. [Build a Rainbow Triangle](01-rainbow-triangle.md) — The complete step-by-step guide
|
||||
5. [Troubleshooting](TROUBLESHOOTING.md) — Common errors and fixes (reference as needed)
|
||||
6. [Glossary](concepts/GLOSSARY.md) — Every term defined (reference as needed)
|
||||
|
||||
> **Reading order matters:** Coordinate systems must be understood before shader basics,
|
||||
> because the shader walkthrough references NDC coordinates.
|
||||
|
||||
## Guides
|
||||
|
||||
- **01 — Rainbow Triangle** — The minimal complete program: one triangle, smooth color interpolation
|
||||
- More guides coming soon (textures, lighting, compute)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Rust stable (edition 2024)
|
||||
- Linux x86_64 with Vulkan drivers (`libvulkan1`)
|
||||
133
docs/TROUBLESHOOTING.md
Normal file
133
docs/TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# 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"
|
||||
tokio = { version = "1", features = ["rt", "macros"] }
|
||||
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. Panic: "No adapter found"
|
||||
|
||||
**Symptom:** Program crashes immediately with `No GPU adapter found`.
|
||||
|
||||
**Cause:** No Vulkan driver installed. wgpu on Linux requires Vulkan.
|
||||
|
||||
**Fix:**
|
||||
```bash
|
||||
sudo apt install libvulkan1 mesa-vulkan-drivers
|
||||
vulkaninfo # verify installation
|
||||
```
|
||||
|
||||
## 5. Panic: "Surface lost"
|
||||
|
||||
**Symptom:** Program crashes with a surface lost error during rendering.
|
||||
|
||||
**Cause:** Display server restarted or GPU context was reset. The [Surface](concepts/GLOSSARY.md#surface) is permanently invalidated.
|
||||
|
||||
**Fix:** In the tutorial, this means the window needs to be reopened. In production code, handle the `Lost` variant of `CurrentSurfaceTexture` by recreating the surface via `Instance::create_surface()`.
|
||||
|
||||
## 6. Wayland surface crashes or doesn't render
|
||||
|
||||
**Symptom:** Program crashes or shows blank window on Wayland.
|
||||
|
||||
**Cause:** winit's Wayland backend may have compatibility issues with certain compositors.
|
||||
|
||||
**Fix:** Force X11 backend:
|
||||
```bash
|
||||
WINIT_UNIX_BACKEND=x11 cargo run
|
||||
```
|
||||
|
||||
## 7. 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();
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 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.
|
||||
|
||||
## 9. 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>`
|
||||
|
||||
## 10. 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
|
||||
```
|
||||
|
||||
## 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
|
||||
Reference in New Issue
Block a user