Vulkan: fix inert depth test on Intel Macs (see-through map/models)#1
Closed
Rakete175 wants to merge 19 commits into
Closed
Vulkan: fix inert depth test on Intel Macs (see-through map/models)#1Rakete175 wants to merge 19 commits into
Rakete175 wants to merge 19 commits into
Conversation
…t can't occlude the reticle
… models out of the water reflection
On Intel Macs, MoltenVK encodes the offscreen scene pass with a nil Metal
depth attachment whenever the depth texture is created as both a render
attachment and a sampled texture. Every draw in that pass then runs with
depth test/write enabled but no depth buffer, so visibility degenerates to
draw order: far geometry shows through near geometry, and models are
visible through walls. Apple Silicon tolerates the combination, which is
why the bug was Intel-only. The Metal validation layer confirms the
mechanism ("MTLDepthStencilDescriptor sets depth test but
MTLRenderPassDescriptor has a nil depthAttachment texture", once per draw).
Fix: never put SAMPLED usage on the scene depth attachment at 1x. Instead,
copy the depth into a new sampled image (sceneDepthSampleImage) right after
the offscreen pass — depth is final there, since sprites are colour-only
and water doesn't write depth — and point GetResolvedDepthImage() at the
copy. All depth-reading consumers (soft particles, water refraction, fog,
DoF, lens flare, cavity outline) already go through that accessor, so none
of them change. The MSAA path is untouched: it must sample the multisampled
attachment for the depth resolve, and already reuses the resolved image
downstream (MSAA is unavailable on the affected GPUs anyway).
Also included, both required on the same hardware:
- Depth format fallback is now depth-only D32_SFLOAT instead of
D32_SFLOAT_S8_UINT (Intel supports neither D24_UNORM_S8_UINT nor a
packed 24-bit depth); stencil is unused by this renderer.
- Disable Metal argument buffers on x86_64 alongside the existing MTLHeap
workaround. Intel Metal requires 256-byte constant-buffer offset
alignment, but MoltenVK sub-allocates its descriptor argument buffers at
16-byte offsets, so descriptors are silently read from wrong offsets
(asserts under MTL_DEBUG_LAYER=1). Descriptors are bound discretely
instead.
Verified on Intel Iris Pro (Haswell, macOS 12.7, MoltenVK 1.4.1): correct
occlusion in all view directions, no models visible through walls, and the
Metal validation flood is gone. Reverting the split (sampling the depth
attachment directly) reproduces the bug, confirming the trigger.
Owner
|
Sooo awesome ! thanks @Rakete175 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Intel Macs, MoltenVK encodes the offscreen scene pass with a nil Metal depth attachment whenever the depth texture is created as both a render attachment and a sampled texture. Every draw in that pass then runs with depth test/write enabled but no depth buffer, so visibility degenerates to draw order: far geometry shows through near geometry, and models are visible through walls. Apple Silicon tolerates the combination, which is why the bug was Intel-only. The Metal validation layer confirms the mechanism ("MTLDepthStencilDescriptor sets depth test but MTLRenderPassDescriptor has a nil depthAttachment texture", once per draw).
Fix: never put SAMPLED usage on the scene depth attachment at 1x. Instead, copy the depth into a new sampled image (sceneDepthSampleImage) right after the offscreen pass — depth is final there, since sprites are colour-only and water doesn't write depth — and point GetResolvedDepthImage() at the copy. All depth-reading consumers (soft particles, water refraction, fog, DoF, lens flare, cavity outline) already go through that accessor, so none of them change. The MSAA path is untouched: it must sample the multisampled attachment for the depth resolve, and already reuses the resolved image downstream (MSAA is unavailable on the affected GPUs anyway).
Also included, both required on the same hardware:
Depth format fallback is now depth-only D32_SFLOAT instead of D32_SFLOAT_S8_UINT (Intel supports neither D24_UNORM_S8_UINT nor a packed 24-bit depth); stencil is unused by this renderer.
Disable Metal argument buffers on x86_64 alongside the existing MTLHeap workaround. Intel Metal requires 256-byte constant-buffer offset alignment, but MoltenVK sub-allocates its descriptor argument buffers at 16-byte offsets, so descriptors are silently read from wrong offsets (asserts under MTL_DEBUG_LAYER=1). Descriptors are bound discretely instead.
Verified on Intel Iris Pro (Haswell, macOS 12.7, MoltenVK 1.4.1): correct occlusion in all view directions, no models visible through walls, and the Metal validation flood is gone. Reverting the split (sampling the depth attachment directly) reproduces the bug, confirming the trigger.