From dc0e2379a832c901778c9767dd949d0e45b0b860 Mon Sep 17 00:00:00 2001 From: Krishna Ayyalasomayajula Date: Sat, 30 May 2026 17:56:38 -0500 Subject: [PATCH] docs: append S9-S11, add README and TROUBLESHOOTING --- docs/01-rainbow-triangle.md | 93 +++++++++++++++++++++++++ docs/README.md | 28 ++++++++ docs/TROUBLESHOOTING.md | 133 ++++++++++++++++++++++++++++++++++++ 3 files changed, 254 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/TROUBLESHOOTING.md diff --git a/docs/01-rainbow-triangle.md b/docs/01-rainbow-triangle.md index 9923071..8777ecc 100644 --- a/docs/01-rainbow-triangle.md +++ b/docs/01-rainbow-triangle.md @@ -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. diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..aa282ea --- /dev/null +++ b/docs/README.md @@ -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`) diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000..3bddece --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -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` 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` + +## 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 { + return vec4(input.vertex_color, 1.0); +} +``` + +Not this (which returns a solid color): +```wgsl +return vec4(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