docs: append S9-S11, add README and TROUBLESHOOTING

This commit is contained in:
2026-05-30 17:56:38 -05:00
parent 7a7191c17d
commit dc0e2379a8
3 changed files with 254 additions and 0 deletions

View File

@@ -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 S2S8, 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
View 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
View 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