fix(image): scope sampled-image upload barriers to the real consumer stage (#54) #86

Merged
catbot merged 1 commit from claude/issue-54 into master 2026-06-16 18:01:51 +02:00
Member

Summary

ImageVulkan<T> hardcoded VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR as the consuming pipeline stage in every layout transition (Create, Update, UpdateRegion, and the compressed-asset Update). The UI font atlas, however, is sampled by a compute shader (drawText is a GraphicsComputeShader), so the upload barrier's dst scope never actually covered its real consumer — a correctness gap (relying on an incidental submit/barrier boundary elsewhere), not merely lost overlap.

Fix

Parameterize the consuming stage per image:

  • Add a consumerStage member, set once at Create (default VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR — preserves existing RT callers like Sponza albedo and the Decompression example checkerImage).
  • Every transition in Update / UpdateRegion / compressed Update now uses the stored consumerStage for both the entry-barrier src scope and the exit-barrier dst scope.
  • FontAtlas::Initialize passes VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, so the atlas's hot dirty-rect uploads (UpdateRegion) now barrier against the actual compute consumer.

No layouts or lifetimes change — this only narrows/corrects the stage scope.

Testing

crafter-build test — 6 passed (incl. FontAtlasDirtyRect).

Resolves #54

## Summary `ImageVulkan<T>` hardcoded `VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR` as the consuming pipeline stage in every layout transition (Create, Update, UpdateRegion, and the compressed-asset Update). The UI font atlas, however, is sampled by a **compute** shader (`drawText` is a `GraphicsComputeShader`), so the upload barrier's dst scope never actually covered its real consumer — a correctness gap (relying on an incidental submit/barrier boundary elsewhere), not merely lost overlap. ## Fix Parameterize the consuming stage per image: - Add a `consumerStage` member, set once at `Create` (default `VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR` — preserves existing RT callers like Sponza `albedo` and the Decompression example `checkerImage`). - Every transition in `Update` / `UpdateRegion` / compressed `Update` now uses the stored `consumerStage` for both the entry-barrier src scope and the exit-barrier dst scope. - `FontAtlas::Initialize` passes `VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT`, so the atlas's hot dirty-rect uploads (`UpdateRegion`) now barrier against the actual compute consumer. No layouts or lifetimes change — this only narrows/corrects the stage scope. ## Testing `crafter-build test` — 6 passed (incl. `FontAtlasDirtyRect`). Resolves #54
ImageVulkan hardcoded VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR as the
consuming stage in every layout transition. The UI font atlas is sampled by
a *compute* shader, so the upload barrier's dst scope never covered the real
consumer — a correctness gap, not just lost overlap.

Parameterize the consuming stage per image: store it once at Create
(defaulting to RT, preserving existing RT/example callers) and reuse it in
every Update / UpdateRegion / compressed-Update transition. FontAtlas passes
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
catbot merged commit bbbfacba48 into master 2026-06-16 18:01:51 +02:00
catbot deleted branch claude/issue-54 2026-06-16 18:01:51 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Catcrafts/Crafter.Graphics!86
No description provided.