|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**td-rs** is an experimental Rust framework for creating TouchDesigner plugins. It provides Rust bindings for TouchDesigner's C++ plugin API, enabling development of CHOPs, TOPs, SOPs, and DATs in Rust instead of C++. |
| 8 | + |
| 9 | +## Architecture |
| 10 | + |
| 11 | +### Workspace Structure |
| 12 | +- **`td-rs-base/`** - Core traits, types, and shared functionality for all plugin types |
| 13 | +- **`td-rs-chop/`**, **`td-rs-dat/`**, **`td-rs-sop/`**, **`td-rs-top/`** - Operator-specific frameworks |
| 14 | +- **`td-rs-derive/`** - Procedural macros for parameter generation |
| 15 | +- **`td-rs-xtask/`** - Build system and plugin management tools |
| 16 | +- **`plugins/`** - Example plugins organized by operator type |
| 17 | + |
| 18 | +### Plugin Development Pattern |
| 19 | +Each plugin follows this structure: |
| 20 | +1. Define parameter struct with `#[derive(Params)]` |
| 21 | +2. Implement required traits: `OpNew`, `OpInfo`, `Op`, and operator-specific trait (`Chop`, `Top`, etc.) |
| 22 | +3. Use `chop_plugin!()`, `top_plugin!()`, etc. macro to register |
| 23 | +4. Configure `Cargo.toml` with `crate-type = ["staticlib"]` and `package.metadata.td-rs.type` |
| 24 | + |
| 25 | +### Key Traits |
| 26 | +- **`OpInfo`** - Plugin metadata (name, version, inputs/outputs) |
| 27 | +- **`OpNew`** - Constructor |
| 28 | +- **`Op`** - Base functionality (parameters, pulse handling) |
| 29 | +- **`Chop`/`Top`/`Sop`/`Dat`** - Operator-specific execution logic |
| 30 | + |
| 31 | +## Development Commands |
| 32 | + |
| 33 | +Use `just` (justfile) for all build operations: |
| 34 | + |
| 35 | +```bash |
| 36 | +# Build a specific plugin |
| 37 | +just build <plugin-name> |
| 38 | + |
| 39 | +# Install plugin to TouchDesigner plugins directory |
| 40 | +just install <plugin-name> |
| 41 | + |
| 42 | +# Watch mode development (requires bacon) |
| 43 | +just dev <plugin-name> |
| 44 | + |
| 45 | +# List all available plugins |
| 46 | +just list-plugins |
| 47 | +``` |
| 48 | + |
| 49 | +### Plugin locations: |
| 50 | +- **Windows**: `$HOME\OneDrive\Documents\Derivative\Plugins\` |
| 51 | +- **macOS**: `$HOME/Library/Application Support/Derivative/TouchDesigner099/Plugins` |
| 52 | + |
| 53 | +## Testing |
| 54 | + |
| 55 | +No centralized test suite - each plugin can have individual tests. Use standard `cargo test` in plugin directories. |
| 56 | + |
| 57 | +## Platform Requirements |
| 58 | + |
| 59 | +### Windows |
| 60 | +- MSVC toolchain with Clang support |
| 61 | +- May require setting `LIBCLANG_PATH` environment variable |
| 62 | +- Target: `x86_64-pc-windows-msvc` |
| 63 | + |
| 64 | +### macOS |
| 65 | +- Xcode with command line tools |
| 66 | +- Target: `aarch64-apple-darwin` (Apple Silicon) |
| 67 | + |
| 68 | +## Current Development Status - Bevy TOP Plugin |
| 69 | + |
| 70 | +### 🚧 Active Issues (December 2024) |
| 71 | + |
| 72 | +**PRIMARY FOCUS**: Debugging bevy-top plugin CUDA-Vulkan-Bevy interop pipeline |
| 73 | + |
| 74 | +**CRITICAL FIXES COMPLETED** ✅: |
| 75 | +1. **Format Pipeline Overhaul**: Fixed sRGB vs linear format mismatches |
| 76 | + - `BGRA8Fixed` → `Bgra8Unorm` (linear) for base textures |
| 77 | + - `Bgra8UnormSrgb` views for Bevy camera compatibility |
| 78 | + - Dynamic format detection instead of hardcoded `Bgra8UnormSrgb` |
| 79 | + |
| 80 | +2. **API Call Ordering**: Fixed "input before output" crash |
| 81 | + - Get input CUDA arrays BEFORE `beginCUDAOperations()` (matches C++ sample) |
| 82 | + - Proper CUDA array validation timing |
| 83 | + |
| 84 | +3. **Bytes-per-pixel Calculations**: Fixed hardcoded assumptions |
| 85 | + - `get_bytes_per_pixel()` function for all TouchDesigner formats |
| 86 | + - Dynamic width calculations instead of `width * 4` |
| 87 | + |
| 88 | +**CURRENT DETECTIVE WORK** 🕵️♀️: |
| 89 | +4. **Row Pitch Alignment Issues**: `cudaErrorInvalidPitchValue` |
| 90 | + - **Problem**: Vulkan external memory row pitch ≠ CUDA alignment requirements |
| 91 | + - **Root Cause**: GPU drivers align texture rows (256/512-byte boundaries) |
| 92 | + - **Solution**: Query actual Vulkan row pitch via `get_image_subresource_layout()` |
| 93 | + - **Status**: Mega debug logging added, testing alignment fixes |
| 94 | + |
| 95 | +5. **Pending Investigation**: Segfault when input connected before output |
| 96 | + - May be related to row pitch/external memory lifecycle issues |
| 97 | + |
| 98 | +### 🧬 Technical Deep Dive - CUDA-Vulkan Pipeline |
| 99 | + |
| 100 | +**Architecture**: TouchDesigner → CUDA → Vulkan External Memory → Bevy → Back to CUDA → TouchDesigner |
| 101 | + |
| 102 | +**The Problem**: Hardware-level memory layout assumptions |
| 103 | +- **TouchDesigner**: Provides CUDA arrays with unknown pitch |
| 104 | +- **Vulkan**: Creates external memory with driver-aligned row pitch |
| 105 | +- **CUDA**: Strict alignment requirements for `cudaMemcpy2D` operations |
| 106 | +- **Mismatch**: `width * bytes_per_pixel` ≠ actual driver row pitch |
| 107 | + |
| 108 | +**Detective Evidence**: |
| 109 | +```rust |
| 110 | +// What we calculate: 512 * 4 = 2048 bytes |
| 111 | +// What Vulkan actually uses: 2304 bytes (512-byte aligned) |
| 112 | +// What CUDA needs: Aligned pitch values |
| 113 | +``` |
| 114 | + |
| 115 | +**Current Fix Strategy**: |
| 116 | +- Query real Vulkan row pitch via `vk::get_image_subresource_layout()` |
| 117 | +- Align pitch to CUDA requirements (512-byte boundaries) |
| 118 | +- Use actual pitch in `cudaMemcpy2DFromArray`/`cudaMemcpy2DToArray` |
| 119 | + |
| 120 | +## Important Implementation Details |
| 121 | + |
| 122 | +1. **FFI Safety**: Uses autocxx for C++ bridge generation and careful Pin<> usage |
| 123 | +2. **Parameter System**: Derive macros generate TouchDesigner-compatible parameters automatically |
| 124 | +3. **Memory Management**: Rust structs are managed via opaque pointers in C++ layer |
| 125 | +4. **Optional Features**: `python` (PyO3 integration), `tracing` (logging), `tokio` (async support) |
| 126 | +5. **Alpha Status**: Experimental - expect breaking changes and potential instability |
| 127 | + |
| 128 | +## Working with Plugins |
| 129 | + |
| 130 | +When creating new plugins: |
| 131 | +1. Copy existing plugin structure from `/plugins/` examples |
| 132 | +2. Update `Cargo.toml` metadata for operator type |
| 133 | +3. Implement required traits following established patterns |
| 134 | +4. Use parameter derive macros for TouchDesigner integration |
| 135 | +5. Test with `just dev <plugin-name>` for rapid iteration |
0 commit comments