Skip to content

KosmicKrisp 0065: sparse depth/stencil images without shader write usage (#51) - #52

Draft
jayvee6 wants to merge 1 commit into
fxgl:mainfrom
jayvee6:fix/51-kk-sparse-depth-shader-write
Draft

jayvee6 wants to merge 1 commit into
fxgl:mainfrom
jayvee6:fix/51-kk-sparse-depth-shader-write

Conversation

@jayvee6

@jayvee6 jayvee6 commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #51.

Cause

KosmicKrisp gives images with TRANSFER_DST usage MTLTextureUsageShaderWrite. On Apple10 (M5 Pro, macOS 27.2), a placement sparse depth texture with that usage drops render pass stores to its mapped tiles: the depth clear (load clear + store) and draw depth writes never reach the heap, while blits read the heap. The bound tile of sparse.c's D32 cases therefore read 0, like an unbound one.

A plain Metal 4 probe (no Vulkan): 256x256 placement sparse texture, 64 KiB pages, tile (0,0) mapped to a placement heap shaped like KosmicKrisp's, render pass clearing it, blit to a buffer:

texture usage RT+Read usage RT+Read+Write
sparse Depth32Float mapped tile 0.5 ✅ 0 (private heap) / heap's raw fill 0x77777777 (shared heap with a CPU buffer, as KosmicKrisp's) ❌
sparse Depth16Unorm (256x128 tiles) 32767 ✅ 0 / raw fill ❌
sparse R32Float 0.5 ✅ 0.5 ✅
dense Depth32Float / Depth16Unorm ✅ ✅

PixelFormatView usage instead of ShaderWrite, the heap's storage mode, a CPU buffer over the heap and the heap size make no difference.

Fix

Patch 0065: sparse images with a depth or stencil format are created without MTLTextureUsageShaderWrite. Nothing in KosmicKrisp writes depth/stencil images from shaders (depth formats have no storage image feature; clears render, copies blit). The patch applies on 0001-0063 and on 0001-0064 (#47) alike; its build.sh entry will need a one-line rebase against #47's 0064 entry, whichever merges second.

Testing (Mac17,16, M5 Pro, macOS 27.2)

  • Before: sparse — FAIL D32 sparse depth test/write in one and in two render passes (16384 wrong colours and depths: the bound tile), also with the depth case run alone and with only the clear and the copy.
  • After: both cases OK, sparse: 0 failure(s); REPRO_DRIVER=kosmickrisp host/moltenvk/repro/run.sh exits 0 with no failures.
  • Not covered: D32S8 (Metal fails to create a sparse Depth32Float_Stencil8 texture with ShaderWrite in the probe; sparse.c tests D32 only).

Draft: the Mesa patch's commit message is still a placeholder; I'll replace it before marking this ready.

Investigated and written with the help of Claude (AI).

🤖 Generated with Claude Code

…age (fxgl#51)

On Apple10 (M5 Pro, macOS 27.2) a placement sparse depth texture with MTLTextureUsageShaderWrite drops render pass stores to its mapped tiles, so sparse.c's two D32 sparse depth cases read the bound tile as unbound and run.sh stopped build.sh before installing. KosmicKrisp only set the usage for TRANSFER_DST, and nothing writes depth/stencil images from shaders. Full KosmicKrisp repro suite green on an M5 Pro.

The patch's commit message is a placeholder for Joey to write. Investigated and drafted with the help of Claude (AI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@fxgl fxgl left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the thorough probe. The fix itself is right. I traced every path in the patched tree (main's 0001-0074 plus #47's 0064), and nothing in KosmicKrisp writes a depth image from a shader:

  • depth formats have no storage feature in kk_format.c;
  • clears render with STORE;
  • all kk_cmd_copy.c paths are blit commands;
  • vk_meta blit and resolve are graphics;
  • host image copy runs on the CPU.

So dropping MTLTextureUsageShaderWrite for sparse depth is safe on every GPU, and only sparse images are affected.

Before it can land:

  1. Number. main now has 0065-0069 and 0071-0074, and #47 takes 0064. Please rename the patch to 0075-…, move the build.sh entry after 0074 and update the subject. It applies cleanly as 0075 on top of everything.
  2. Commit message. The patch subject and body are still the TODO(Joey) placeholder, and the steamac commit says so too. Mesa's AGENTS.md asks for published text to be written by a person, so please write the subject (kk: …, no em dash) and the body yourself: the cause (Apple10 drops render-pass stores to mapped tiles of placement-sparse depth textures with ShaderWrite), why it's safe, and the repro. Pick the trailer that matches how it was written (Assisted-by: vs Generated-by:, see main's 0065/0069).
  3. A code comment in kk_image_layout.c where the flag is cleared: 2-3 lines on why. Otherwise it looks accidental on the next rebase; the neighbouring steamac workarounds are all commented.
  4. The KOSMICKRISP.txt line in build.sh, like 0065-0074: echo " 0075 = steamac: sparse depth images without MTLTextureUsageShaderWrite (Apple10 drops render-pass stores)".

Could you also check on the M5:

  • Sparse D32 with VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT. kk_image_layout.c:68-69 adds PixelFormatView there. Your table says using PixelFormatView instead of ShaderWrite "made no difference". If that means stores are lost with RT+Read+PixelFormatView too, sparse depth-only images should drop PixelFormatView as well; a depth view's format always equals the image's.
  • A vkCmdCopyBufferToImage into a bound tile of the sparse D32 image, with read-back, ideally under MTL_DEBUG_LAYER=1. The sparse.c D32 case never writes by copy, and that is what TRANSFER_DST is for.

Nits:

  • Sparse stencil formats are rejected by kk_sparse.c, so the entry could say "sparse depth images (D16/D32)".
  • Repro: host/moltenvk/repro sparse.c is missing a /.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants