summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-14 12:52:42 +0100
committerskal <pascal.massimino@gmail.com>2026-02-14 12:52:42 +0100
commit197a03c24baba3acc35327e0e126ec49754f9945 (patch)
tree58d1b267f35baf8013a928edfd85b51fe69c21df /doc
parent5e33097e4649f1c886275db18dc532930487457b (diff)
Docs: WGPU helper functions reference
Comprehensive documentation for project-specific WGPU helpers (not wgpu-native wrappers). **Covers:** - Buffer management (gpu_create_buffer) - Texture creation (gpu_create_texture_2d, storage textures, mip views) - Pipeline helpers (compute/render pass creation) - Cross-platform utilities (gpu_init_color_attachment) - Test helpers (init_wgpu_with_surface) **Usage patterns:** - Effect uniforms setup - Compute shader dispatch - Multi-pass rendering Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/WGPU_HELPERS.md408
1 files changed, 408 insertions, 0 deletions
diff --git a/doc/WGPU_HELPERS.md b/doc/WGPU_HELPERS.md
new file mode 100644
index 0000000..5642eef
--- /dev/null
+++ b/doc/WGPU_HELPERS.md
@@ -0,0 +1,408 @@
+# WebGPU Helper Functions
+
+Project-specific WGPU helper functions (not wgpu-native wrapper calls).
+
+**Scope:** High-level convenience functions built on top of wgpu-native API.
+
+---
+
+## Core Helpers (`src/gpu/gpu.h`)
+
+### Buffer Management
+
+#### `gpu_create_buffer`
+```cpp
+GpuBuffer gpu_create_buffer(WGPUDevice device, size_t size,
+ uint32_t usage, const void* data = nullptr);
+```
+
+**Purpose:** Create and optionally initialize a WGPU buffer.
+
+**Parameters:**
+- `device` - WGPU device handle
+- `size` - Buffer size in bytes
+- `usage` - Usage flags (e.g., `WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst`)
+- `data` - Optional initial data (if `nullptr`, buffer is uninitialized)
+
+**Returns:** `GpuBuffer` struct containing:
+- `buffer` - WGPU buffer handle
+- `size` - Buffer size (for validation/debugging)
+
+**Common Usage Flags:**
+- `WGPUBufferUsage_Uniform` - Uniform buffer (read-only in shaders)
+- `WGPUBufferUsage_Storage` - Storage buffer (read/write in compute shaders)
+- `WGPUBufferUsage_Vertex` - Vertex buffer
+- `WGPUBufferUsage_Index` - Index buffer
+- `WGPUBufferUsage_CopyDst` - Can be written to via queue
+- `WGPUBufferUsage_CopySrc` - Can be read from (for readback)
+
+**Example:**
+```cpp
+// Create uniform buffer with initial data
+CommonPostProcessUniforms uniforms = {...};
+GpuBuffer uniform_buf = gpu_create_buffer(
+ device, sizeof(uniforms),
+ WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst,
+ &uniforms);
+
+// Create empty storage buffer
+GpuBuffer storage_buf = gpu_create_buffer(
+ device, 1024 * sizeof(float),
+ WGPUBufferUsage_Storage | WGPUBufferUsage_CopyDst);
+```
+
+**Implementation:** `src/gpu/gpu.cc`
+
+---
+
+### Texture Management
+
+#### `gpu_create_texture_2d`
+```cpp
+TextureWithView gpu_create_texture_2d(
+ WGPUDevice device, uint32_t width, uint32_t height,
+ WGPUTextureFormat format, WGPUTextureUsage usage,
+ uint32_t mip_levels = 1);
+```
+
+**Purpose:** Create 2D texture with view.
+
+**Parameters:**
+- `device` - WGPU device handle
+- `width`, `height` - Texture dimensions
+- `format` - Pixel format (e.g., `WGPUTextureFormat_RGBA8Unorm`)
+- `usage` - Usage flags (see below)
+- `mip_levels` - Mipmap count (default: 1)
+
+**Returns:** `TextureWithView` struct:
+- `texture` - WGPU texture handle
+- `view` - Default texture view (all mip levels)
+
+**Common Usage Flags:**
+- `WGPUTextureUsage_TextureBinding` - Readable in shaders
+- `WGPUTextureUsage_RenderAttachment` - Render target
+- `WGPUTextureUsage_CopyDst` - Can be written via queue
+- `WGPUTextureUsage_CopySrc` - Can be read (for download)
+
+**Example:**
+```cpp
+// Create render target texture
+TextureWithView target = gpu_create_texture_2d(
+ device, 1920, 1080,
+ WGPUTextureFormat_RGBA8Unorm,
+ WGPUTextureUsage_RenderAttachment | WGPUTextureUsage_TextureBinding);
+
+// Create mipmapped texture
+TextureWithView mipmapped = gpu_create_texture_2d(
+ device, 256, 256,
+ WGPUTextureFormat_RGBA8Unorm,
+ WGPUTextureUsage_TextureBinding | WGPUTextureUsage_RenderAttachment,
+ 4); // 256→128→64→32 mip chain
+```
+
+---
+
+#### `gpu_create_storage_texture_2d`
+```cpp
+TextureWithView gpu_create_storage_texture_2d(
+ WGPUDevice device, uint32_t width, uint32_t height,
+ WGPUTextureFormat format);
+```
+
+**Purpose:** Create read/write storage texture (for compute shaders).
+
+**Parameters:**
+- `device` - WGPU device handle
+- `width`, `height` - Texture dimensions
+- `format` - Pixel format (must support storage usage)
+
+**Returns:** `TextureWithView` with storage usage flags.
+
+**Valid Formats:**
+- `WGPUTextureFormat_RGBA8Unorm`
+- `WGPUTextureFormat_RGBA16Float`
+- `WGPUTextureFormat_RGBA32Float`
+- `WGPUTextureFormat_R32Float`, `WGPUTextureFormat_RG32Float`
+
+**Example:**
+```cpp
+// Compute shader output texture
+TextureWithView output = gpu_create_storage_texture_2d(
+ device, 512, 512, WGPUTextureFormat_RGBA8Unorm);
+```
+
+---
+
+#### `gpu_create_mip_view`
+```cpp
+WGPUTextureView gpu_create_mip_view(WGPUTexture texture,
+ WGPUTextureFormat format,
+ uint32_t mip_level);
+```
+
+**Purpose:** Create view for specific mipmap level (for rendering to individual mips).
+
+**Example:**
+```cpp
+// Render to mip level 2 (quarter resolution)
+WGPUTextureView mip2_view = gpu_create_mip_view(
+ texture, WGPUTextureFormat_RGBA8Unorm, 2);
+```
+
+---
+
+### Pipeline Helpers
+
+#### `gpu_create_compute_pass`
+```cpp
+ComputePass gpu_create_compute_pass(
+ WGPUDevice device, const char* shader_code,
+ ResourceBinding* bindings, int num_bindings);
+```
+
+**Purpose:** Create compute pipeline + bind group from WGSL shader.
+
+**Parameters:**
+- `device` - WGPU device handle
+- `shader_code` - WGSL compute shader source
+- `bindings` - Array of resource bindings (buffers/textures)
+- `num_bindings` - Binding count
+
+**Returns:** `ComputePass` struct:
+- `pipeline` - Compute pipeline
+- `bind_group` - Bind group (pre-bound resources)
+- `workgroup_size_{x,y,z}` - Workgroup dimensions
+
+**ResourceBinding Structure:**
+```cpp
+struct ResourceBinding {
+ GpuBuffer buffer;
+ WGPUBufferBindingType type; // Uniform, Storage, etc.
+};
+```
+
+**Example:**
+```cpp
+// Setup bindings
+ResourceBinding bindings[2] = {
+ {uniform_buf, WGPUBufferBindingType_Uniform},
+ {storage_buf, WGPUBufferBindingType_Storage}
+};
+
+// Create compute pass
+ComputePass pass = gpu_create_compute_pass(
+ device, shader_wgsl, bindings, 2);
+
+// Dispatch
+WGPUComputePassEncoder encoder = ...;
+wgpuComputePassEncoderSetPipeline(encoder, pass.pipeline);
+wgpuComputePassEncoderSetBindGroup(encoder, 0, pass.bind_group, 0, nullptr);
+wgpuComputePassEncoderDispatchWorkgroups(encoder,
+ workgroups_x, workgroups_y, 1);
+```
+
+---
+
+#### `gpu_create_render_pass`
+```cpp
+RenderPass gpu_create_render_pass(
+ WGPUDevice device, WGPUTextureFormat format,
+ const char* shader_code,
+ ResourceBinding* bindings, int num_bindings);
+```
+
+**Purpose:** Create render pipeline + bind group from WGSL shader.
+
+**Parameters:**
+- `device` - WGPU device handle
+- `format` - Target texture format (for pipeline compatibility)
+- `shader_code` - WGSL shader with vertex + fragment stages
+- `bindings` - Resource bindings array
+- `num_bindings` - Binding count
+
+**Returns:** `RenderPass` struct:
+- `pipeline` - Render pipeline
+- `bind_group` - Pre-bound resources
+- `vertex_count`, `instance_count` - Draw parameters
+
+**Example:**
+```cpp
+RenderPass pass = gpu_create_render_pass(
+ device, WGPUTextureFormat_BGRA8Unorm,
+ fullscreen_quad_wgsl, bindings, 1);
+
+WGPURenderPassEncoder encoder = ...;
+wgpuRenderPassEncoderSetPipeline(encoder, pass.pipeline);
+wgpuRenderPassEncoderSetBindGroup(encoder, 0, pass.bind_group, 0, nullptr);
+wgpuRenderPassEncoderDraw(encoder, pass.vertex_count, pass.instance_count, 0, 0);
+```
+
+---
+
+### Render Pass Setup
+
+#### `gpu_init_color_attachment`
+```cpp
+inline void gpu_init_color_attachment(
+ WGPURenderPassColorAttachment& attachment,
+ WGPUTextureView view);
+```
+
+**Purpose:** Initialize color attachment with cross-platform defaults.
+
+**Sets:**
+- `view` - Target texture view
+- `loadOp` = `Clear` (clear to black)
+- `storeOp` = `Store` (preserve results)
+- `clearValue` = `{0, 0, 0, 1}` (opaque black)
+- `depthSlice` = `UNDEFINED` (native only, handles Win32 compat)
+
+**Example:**
+```cpp
+WGPURenderPassColorAttachment color_attach = {};
+gpu_init_color_attachment(color_attach, target_view);
+
+WGPURenderPassDescriptor pass_desc = {};
+pass_desc.colorAttachmentCount = 1;
+pass_desc.colorAttachments = &color_attach;
+```
+
+**Cross-Platform Notes:**
+- Handles `depthSlice` field differences between native/Win32 builds
+- Always clears to black; modify `clearValue` if different color needed
+
+---
+
+## Test Helpers (`src/tests/common/test_3d_helpers.h`)
+
+### `init_wgpu_with_surface`
+```cpp
+WgpuSurfaceContext init_wgpu_with_surface(PlatformState* platform_state);
+```
+
+**Purpose:** Initialize WGPU device/queue/surface for visual tests (test_3d_render, test_3d_physics, test_mesh).
+
+**Parameters:**
+- `platform_state` - Platform window state (from `platform_init`)
+
+**Returns:** `WgpuSurfaceContext` struct:
+- `device` - WGPU device
+- `queue` - Command queue
+- `surface` - Window surface (pre-configured)
+- `adapter` - WGPU adapter
+- `format` - Surface texture format
+
+**Example:**
+```cpp
+PlatformState platform_state = platform_init(false, 1280, 720);
+WgpuSurfaceContext ctx = init_wgpu_with_surface(&platform_state);
+
+g_device = ctx.device;
+g_queue = ctx.queue;
+g_surface = ctx.surface;
+g_format = ctx.format;
+```
+
+**Implementation Details:**
+- Handles cross-platform adapter/device request callbacks (Win32 vs native)
+- Configures surface for `WGPUPresentMode_Fifo` (vsync)
+- Chooses high-performance adapter
+- Blocks until adapter/device ready
+
+**Usage:** Test executables only (not production code).
+
+---
+
+## Usage Patterns
+
+### Creating Effect Uniforms
+```cpp
+// 1. Define uniform struct (must match WGSL)
+struct MyEffectUniforms {
+ float time;
+ float param;
+ float _pad[2];
+};
+static_assert(sizeof(MyEffectUniforms) == 16);
+
+// 2. Create buffer
+MyEffectUniforms data = {time, 1.0f};
+uniform_buf_ = gpu_create_buffer(
+ device, sizeof(data),
+ WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst,
+ &data);
+
+// 3. Update each frame
+wgpuQueueWriteBuffer(queue, uniform_buf_.buffer, 0, &data, sizeof(data));
+```
+
+### Compute Shader Dispatch
+```cpp
+// 1. Create storage buffers
+GpuBuffer input = gpu_create_buffer(..., WGPUBufferUsage_Storage, input_data);
+GpuBuffer output = gpu_create_buffer(..., WGPUBufferUsage_Storage);
+
+// 2. Setup bindings
+ResourceBinding bindings[] = {
+ {input, WGPUBufferBindingType_ReadOnlyStorage},
+ {output, WGPUBufferBindingType_Storage}
+};
+
+// 3. Create compute pass
+ComputePass pass = gpu_create_compute_pass(device, shader, bindings, 2);
+
+// 4. Dispatch
+WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
+WGPUComputePassEncoder compute = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
+wgpuComputePassEncoderSetPipeline(compute, pass.pipeline);
+wgpuComputePassEncoderSetBindGroup(compute, 0, pass.bind_group, 0, nullptr);
+wgpuComputePassEncoderDispatchWorkgroups(compute, num_workgroups, 1, 1);
+wgpuComputePassEncoderEnd(compute);
+```
+
+### Multi-Pass Rendering
+```cpp
+// Pass 1: Render to texture
+TextureWithView intermediate = gpu_create_texture_2d(...);
+WGPURenderPassColorAttachment attach1 = {};
+gpu_init_color_attachment(attach1, intermediate.view);
+// ... render pass 1 ...
+
+// Pass 2: Post-process
+RenderPass post_process = gpu_create_render_pass(...);
+WGPURenderPassColorAttachment attach2 = {};
+gpu_init_color_attachment(attach2, final_view);
+// ... render pass 2 using intermediate as input ...
+```
+
+---
+
+## Related Documentation
+
+- **WGSL Shaders:** `doc/SEQUENCE.md` - Shader parameterization
+- **Effect Creation:** `doc/EFFECT_WORKFLOW.md` - Visual effect setup
+- **Uniforms:** `doc/UNIFORM_BUFFER_GUIDELINES.md` - Alignment rules
+- **3D Rendering:** `doc/3D.md` - Renderer3D architecture
+- **CNN Post-Process:** `doc/CNN_V2.md` - Storage buffer weights
+
+---
+
+## Implementation Files
+
+- `src/gpu/gpu.h` - Header with declarations
+- `src/gpu/gpu.cc` - Core implementations
+- `src/tests/common/test_3d_helpers.{h,cc}` - Test-specific helpers
+
+---
+
+## Size Considerations
+
+**Production Builds:**
+- Helpers are **not** stripped in final build (needed for effect init)
+- Validation checks controlled by `STRIP_ALL` / `FINAL_STRIP`
+- Total overhead: ~2-3 KB (amortized across all effects)
+
+**Design Tradeoffs:**
+- **Convenience vs Size:** Trade ~1 KB for 10× less boilerplate per effect
+- **Type Safety:** GpuBuffer struct prevents size mismatch bugs
+- **Cross-Platform:** Single helper handles Win32/native callback differences