Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c1b0265
Fix stale bind group reuse after renderer/stage switch
dw218192 Apr 8, 2026
6826513
Refactor BindGroupEntry to variant + add regression tests
dw218192 Apr 8, 2026
4d6737e
Screen-space contact shadows + light iteration module
dw218192 Apr 9, 2026
4ce2c48
Descriptor API: OutputSlot-driven layouts, fluent builder, FallbackPool
dw218192 Apr 9, 2026
0cffbdf
Inline GBuffer slots + migrate PathTracer descriptor fills
dw218192 Apr 9, 2026
db85191
FrameGraph owns all GPU objects — integer handles, implicit liveness
dw218192 Apr 12, 2026
86b2e8f
FrameGraph: flat_map caches, pipeline fast-path, Tracy scopes [fg-fas…
dw218192 Apr 12, 2026
caca4dd
Interim Hack
dw218192 Apr 12, 2026
f5f6679
Rendering-next: DepTrackedCache + IShaderCompiler + Slang backend + c…
dw218192 Apr 13, 2026
8b3a147
tmp_plan: stash pending tickets for resumption
dw218192 Apr 13, 2026
91912a1
Shader subsystem centralization: core::shaderc + pts_shaderc
dw218192 Apr 14, 2026
4de591f
Shader-driven bind group layouts; delete OutputSlot DSL
dw218192 Apr 14, 2026
8c3cb55
Replace Unicode characters with ASCII equivalents; add ASCII-only rule
dw218192 Apr 14, 2026
086d2cd
Unified SlotMap: replace DepTrackedCache + SlotVector with SlotMap / …
dw218192 Apr 15, 2026
da34244
Pin repokit submodule to v0.7.29
dw218192 Apr 15, 2026
d890679
Standardize on "descriptor" over "bind group" in project-level code
dw218192 Apr 15, 2026
6b9d965
Fix contact shadow
dw218192 Apr 15, 2026
78910ea
Update claude.md
dw218192 Apr 15, 2026
ff7ab0e
Fix CI: make slangc's conanrun env_script optional
dw218192 Apr 15, 2026
eb8f729
Fix CI: skip host-tool-dependent prebuild steps in Emscripten main build
dw218192 Apr 15, 2026
d10181a
Revert "Fix CI: skip host-tool-dependent prebuild steps in Emscripten…
dw218192 Apr 15, 2026
117940b
Revert "Fix CI: make slangc's conanrun env_script optional"
dw218192 Apr 15, 2026
0fdbdfd
Fix CI: cross-platform host-tool conanrun staging + sibling build-dir…
dw218192 Apr 15, 2026
21c9e16
Stage conanrun next to host-tool binary in native Phase 1 too
dw218192 Apr 15, 2026
c1d9b33
Defer SyncScope::mutate_* definitions until after RenderWorld is comp…
dw218192 Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .claude/skills/address-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: address-review
description: Fetch CodeRabbit (or other bot) review comments from the current PR and address each one with code changes.
argument-hint: "[PR number] defaults to the PR for the current branch"
argument-hint: "[PR number] -- defaults to the PR for the current branch"
---

Address review comments on a GitHub PR. Fetches comments, applies fixes, commits.
Expand Down Expand Up @@ -35,29 +35,29 @@ Also fetch the PR review body (walkthrough / summary) but only act on
### 3. Triage comments

**Default: fix everything.** Trivial fixes (add an attribute, remove an
unused import, rename a file) are still valid they improve the codebase.
unused import, rename a file) are still valid -- they improve the codebase.
Do not skip a comment because it's "just a nit." The whole point of this
skill is to handle the tedious stuff.

For each comment, classify as one of:
- **FIX**: the comment requests a concrete change. This is the default.
Includes: add attribute, rename, remove dead code, fix a race condition,
add a test case, quote a path, catch an exception, improve an error
message no matter how small.
message -- no matter how small.
- **REJECT**: the suggestion is wrong or conflicts with project conventions
(CLAUDE.md). You must state *why* it's wrong "not important" is not a
(CLAUDE.md). You must state *why* it's wrong -- "not important" is not a
valid reason. Examples: suggesting a pattern the codebase explicitly
avoids, proposing a change that breaks ABI, misunderstanding the code.
- **STALE**: the file/line no longer exists in the current code (already
fixed or code was deleted).

Present the triage to the user:
```
PR #27 10 comments found
1. [FIX] renderWorld.h:346 add [[nodiscard]]
2. [FIX] worker.h:114 remove default-constructibility requirement
3. [REJECT] editorApplication.cpp:500 suggests X but CLAUDE.md says Y
4. [STALE] oldFile.cpp:30 file no longer exists
PR #27 -- 10 comments found
1. [FIX] renderWorld.h:346 -- add [[nodiscard]]
2. [FIX] worker.h:114 -- remove default-constructibility requirement
3. [REJECT] editorApplication.cpp:500 -- suggests X but CLAUDE.md says Y
4. [STALE] oldFile.cpp:30 -- file no longer exists
...
Proceed with 8 fixes? (y/n)
```
Expand All @@ -68,7 +68,7 @@ Wait for user confirmation before making changes.

For each actionable comment:
1. Read the file at the referenced path
2. Locate the relevant code (line number is a hint, not exact find by context)
2. Locate the relevant code (line number is a hint, not exact -- find by context)
3. Apply the fix using the Edit tool
4. If the comment contains a diff suggestion (```suggestion block), apply it
directly
Expand Down Expand Up @@ -102,7 +102,7 @@ gh api repos/{owner}/{repo}/pulls/{number}/comments/{comment_id}/replies \

## Notes

- Never blindly apply suggestions without reading the surrounding code
- Never blindly apply suggestions without reading the surrounding code --
the suggestion may be based on stale context
- If a suggestion conflicts with project conventions (CLAUDE.md), skip it
and explain why
Expand Down
12 changes: 6 additions & 6 deletions .claude/skills/contribute-framework/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cd tools/framework
git stash
git checkout main
git pull --ff-only origin main
git stash pop # conflict stop, ask user
git stash pop # conflict -> stop, ask user
```

### 2. Bootstrap test driver & run tests
Expand All @@ -31,8 +31,8 @@ bash test_driver/tools/framework/bootstrap.sh test_driver
cd test_driver && ./repo test
```

**Fail fix the issue and re-run tests. Do NOT bump version or proceed until
tests pass.** Loop fix test until green.
**Fail -> fix the issue and re-run tests. Do NOT bump version or proceed until
tests pass.** Loop fix -> test until green.

### 3. Clean up test driver

Expand All @@ -48,7 +48,7 @@ rm -rf test_driver

### 4. Bump version & changelog

- Patch-increment `version` in `pyproject.toml` (e.g. `0.7.26` `0.7.27`)
- Patch-increment `version` in `pyproject.toml` (e.g. `0.7.26` -> `0.7.27`)
- Prepend to `CHANGELOG.md`:

```markdown
Expand All @@ -68,7 +68,7 @@ git push origin main

### 6. Wait for CI tag

CI auto-tags `v<version>` on green. Poll `git fetch origin --tags && git tag -l "v<new-version>"` every ~30s, up to 3 min. Timeout print manual finish instructions and stop.
CI auto-tags `v<version>` on green. Poll `git fetch origin --tags && git tag -l "v<new-version>"` every ~30s, up to 3 min. Timeout -> print manual finish instructions and stop.

### 7. Pin in parent repo

Expand All @@ -77,4 +77,4 @@ cd tools/framework && git checkout v<new-version>
cd ../.. && git add tools/framework && git commit -m "Pin repokit submodule to v<new-version>"
```

Print: old version new version, changelog entry, pin commit hash.
Print: old version -> new version, changelog entry, pin commit hash.
2 changes: 1 addition & 1 deletion .claude/skills/rotate-branch/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: rotate-branch
description: After a PR is merged, prune the old dev branch and start a fresh one off develop.
argument-hint: "[branch name] defaults to dev/rendering-next"
argument-hint: "[branch name] -- defaults to dev/rendering-next"
---

Rotate a dev branch after its PR has been merged into develop.
Expand Down
30 changes: 15 additions & 15 deletions .claude/skills/triage-ci/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: triage-ci
description: Wait for CI pipeline to finish, then triage and fix any failures. Loops until CI is green or the turn limit is reached. Use this after pushing code, opening a PR, or whenever the user says "check CI", "wait for CI", "triage CI", "fix CI", or asks about build/test failures on the current branch.
argument-hint: "[max turns] [PR number] defaults to 3 turns, current branch's PR"
argument-hint: "[max turns] [PR number] -- defaults to 3 turns, current branch's PR"
---

Wait for the CI pipeline to complete, then diagnose and fix failures.
Expand All @@ -11,8 +11,8 @@ limit is reached.
## Arguments

Parse the argument string for:
- A small integer (1-10) max turns (default: 3)
- A larger integer or `#N` PR number (default: current branch's PR)
- A small integer (1-10) -> max turns (default: 3)
- A larger integer or `#N` -> PR number (default: current branch's PR)

Examples: `/triage-ci` (3 turns, auto PR), `/triage-ci 5` (5 turns),
`/triage-ci 29` (PR #29, 3 turns), `/triage-ci 5 29` (5 turns, PR #29).
Expand All @@ -21,8 +21,8 @@ Examples: `/triage-ci` (3 turns, auto PR), `/triage-ci 5` (5 turns),

```
for turn in 1..max_turns:
1. Wait for CI (background user can work while waiting)
2. Check results if green, report success and stop
1. Wait for CI (background -- user can work while waiting)
2. Check results -- if green, report success and stop
3. Triage failures
4. Apply fixes, build and test locally
5. Push and go to next turn
Expand Down Expand Up @@ -55,8 +55,8 @@ gh run watch <run-id> --exit-status
```

This lets the user continue working. When the background task completes,
a notification arrives pick up from step 2 at that point. Tell the
user: "CI run <id> is in progress. I'm watching in the background
a notification arrives -- pick up from step 2 at that point. Tell the
user: "CI run <id> is in progress. I'm watching in the background --
you'll be notified when it finishes. Feel free to keep working."

### 2. Check results
Expand All @@ -75,18 +75,18 @@ gh run view <run-id> --job <job-id> --log-failed
```

Classify as:
- **COMPILE** build error. Read the error, find the file/line, fix it.
- **TEST** test failure. Check if it's a real regression or stale test.
- **INFRA** CI infrastructure (missing artifacts, timeouts, network).
- **COMPILE** -- build error. Read the error, find the file/line, fix it.
- **TEST** -- test failure. Check if it's a real regression or stale test.
- **INFRA** -- CI infrastructure (missing artifacts, timeouts, network).
Check if caused by a code change or transient.
- **FLAKY** passes locally, fails in CI with no code cause.
- **FLAKY** -- passes locally, fails in CI with no code cause.

Present the triage:
```
Turn 1/3 CI run <id> 2 checks failed
Turn 1/3 -- CI run <id> -- 2 checks failed

1. [COMPILE] Build (windows-x64, Release)
error at file.cpp:42 description
error at file.cpp:42 -- description
Fix: ...

2. [INFRA] Build (emscripten, Release)
Expand Down Expand Up @@ -115,12 +115,12 @@ Then loop back to step 1 for the next turn.

- Cascade failures are common: one build failure causes downstream jobs
to fail (e.g. missing artifacts). Identify the root cause first.
- `max-parallel: 1` in the CI matrix means jobs run sequentially
- `max-parallel: 1` in the CI matrix means jobs run sequentially --
if the first matrix entry fails, later entries may fail for dependent
reasons.
- Always build and test locally before pushing a fix to avoid churn.
- INFRA failures that are purely transient (network blip, runner OOM)
can be retried without code changes: `gh run rerun <run-id> --failed`.
- Do NOT use `sleep` for polling the hook blocks it. Use
- Do NOT use `sleep` for polling -- the hook blocks it. Use
`run_in_background: true` on `gh run watch` and wait for the
notification instead.
44 changes: 22 additions & 22 deletions .claude/skills/usd/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ Organize prims under `/Root`:

```
/Root
/Materials Scope containing all materials
/Materials <- Scope containing all materials
/MatName
/Shader UsdPreviewSurface shader node
/Geometry Xform grouping geometry (optional, flat layout OK for small scenes)
/Shader <- UsdPreviewSurface shader node
/Geometry <- Xform grouping geometry (optional, flat layout OK for small scenes)
/MeshName
/Lights
/LightName
Expand All @@ -47,26 +47,26 @@ For simple scenes with few prims, flat layout under `/Root` is fine (no `/Geomet

## Supported Prim Types

PTStudio adapters support these types. Only use these anything else is silently ignored.
PTStudio adapters support these types. Only use these -- anything else is silently ignored.

### Geometry
- `Cube` `double size`
- `Sphere` `double radius`
- `Cylinder` `token axis`, `double height`, `double radius`
- `Cone` `token axis`, `double height`, `double radius`
- `Capsule` `token axis`, `double height`, `double radius`
- `Mesh` `point3f[] points`, `int[] faceVertexCounts`, `int[] faceVertexIndices`, `normal3f[] normals` (optional)
- `Cube` -- `double size`
- `Sphere` -- `double radius`
- `Cylinder` -- `token axis`, `double height`, `double radius`
- `Cone` -- `token axis`, `double height`, `double radius`
- `Capsule` -- `token axis`, `double height`, `double radius`
- `Mesh` -- `point3f[] points`, `int[] faceVertexCounts`, `int[] faceVertexIndices`, `normal3f[] normals` (optional)

### Lights

All directional area lights (RectLight, DiskLight, DistantLight) are centered
in the XY plane and **emit along -Z** by default. Rotate to aim them.

- `DistantLight` `float inputs:intensity`, `color3f inputs:color`, `float inputs:angle`. Emits along -Z.
- `SphereLight` `float inputs:intensity`, `color3f inputs:color`, `float inputs:radius`. Omnidirectional.
- `RectLight` `float inputs:intensity`, `color3f inputs:color`, `float inputs:width`, `float inputs:height`. Emits along -Z.
- `DiskLight` `float inputs:intensity`, `color3f inputs:color`, `float inputs:radius`. Emits along -Z.
- `DomeLight` `float inputs:intensity`, `color3f inputs:color`, `asset inputs:texture:file`. Emits inward.
- `DistantLight` -- `float inputs:intensity`, `color3f inputs:color`, `float inputs:angle`. Emits along -Z.
- `SphereLight` -- `float inputs:intensity`, `color3f inputs:color`, `float inputs:radius`. Omnidirectional.
- `RectLight` -- `float inputs:intensity`, `color3f inputs:color`, `float inputs:width`, `float inputs:height`. Emits along -Z.
- `DiskLight` -- `float inputs:intensity`, `color3f inputs:color`, `float inputs:radius`. Emits along -Z.
- `DomeLight` -- `float inputs:intensity`, `color3f inputs:color`, `asset inputs:texture:file`. Emits inward.

### Materials (UsdPreviewSurface only)

Expand Down Expand Up @@ -131,7 +131,7 @@ uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
Always set `orientation = "rightHanded"` on custom meshes. In USD's `rightHanded`
convention, vertices go **clockwise** when viewed from the front face. This
matches how the renderer's projection and culling work together (glm right-handed
projection flips Z CW world becomes CCW clip `WGPUFrontFace_CCW` matches).
projection flips Z -> CW world becomes CCW clip -> `WGPUFrontFace_CCW` matches).

For a +Y-facing ground plane, wind vertices **CW when viewed from above**:

Expand Down Expand Up @@ -174,8 +174,8 @@ over "Root"

- Always include at least one light so the scene is visible.
- For general-purpose scenes: a `DistantLight` rotated ~(-45, 30, 0) at intensity 1.0 works well as a sun.
- For area-light testing: use `RectLight` or `DiskLight` with higher intensity (100500+) since they are physically-sized emitters.
- `DomeLight` at low intensity (0.51.0) provides ambient fill.
- For area-light testing: use `RectLight` or `DiskLight` with higher intensity (100-500+) since they are physically-sized emitters.
- `DomeLight` at low intensity (0.5-1.0) provides ambient fill.

## Verification

Expand All @@ -192,8 +192,8 @@ For specific debug output:

## What NOT to do

- Do not use schema types not listed above (e.g. UsdGeomBasisCurves, UsdSkelRoot) they are not supported.
- Do not use texture file references the editor has no texture loading pipeline yet.
- Do not use `class` prims or inherits composition keep scenes self-contained.
- Do not use schema types not listed above (e.g. UsdGeomBasisCurves, UsdSkelRoot) -- they are not supported.
- Do not use texture file references -- the editor has no texture loading pipeline yet.
- Do not use `class` prims or inherits composition -- keep scenes self-contained.
- Do not use animation / time samples unless explicitly asked.
- Do not omit `xformOpOrder` when using any xformOp USD requires it.
- Do not omit `xformOpOrder` when using any xformOp -- USD requires it.
26 changes: 6 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
# Windows must finish before Emscripten starts (USDZ scene dependency).
# max-parallel: 1 ensures sequential execution in platform order.
max-parallel: 1
matrix:
platform: [windows-x64, emscripten]
build_type: [Release]
Expand Down Expand Up @@ -108,30 +105,19 @@ jobs:
restore-keys: |
${{ matrix.platform }}-conan-${{ hashFiles('conanfile.py') }}

# Windows prebuild generates USDZ scenes; upload them so the
# Emscripten build can embed them in WASM via --embed-file.
# usdz_pack is a native host tool that cannot cross-compile to WASM.
- name: Download USDZ scenes
# usdz_pack is a native host tool that can't cross-compile to WASM.
# Emscripten CI builds it natively first (via its own Conan package,
# isolated from the root project's Conan graph), then the main build
# picks up the generated .usdz scenes from assets/scenes/.
- name: Build host tools (native Linux)
if: matrix.platform == 'emscripten'
uses: actions/download-artifact@v4
with:
name: usdz-scenes
path: assets/scenes/
run: ./repo build --platform linux-x64 --build-type ${{ matrix.build_type }} --host-tools-only

- name: Build project
run: ${{ matrix.repo }} build --platform ${{ matrix.platform }} --build-type ${{ matrix.build_type }}
env:
PTSTUDIO_GPU_BACKEND: ${{ matrix.platform == 'windows-x64' && 'D3D12' || '' }}

- name: Upload USDZ scenes
if: matrix.platform == 'windows-x64'
uses: actions/upload-artifact@v4
with:
name: usdz-scenes
path: assets/scenes/*.usdz
if-no-files-found: error
retention-days: 3

- name: Package build artifacts
run: ${{ matrix.repo }} package --platform ${{ matrix.platform }} --build-type ${{ matrix.build_type }}

Expand Down
Loading
Loading