Environment:
-
NVIDIA RTX A6000
-
Driver 596.46 (also reproduced on 595.97)
-
Windows 11, Vulkan 1.3
-
Extensions:
VK_EXT_descriptor_heap,VK_EXT_shader_object,VK_KHR_maintenance5
Description:
textureLod (SPIR-V OpImageSampleExplicitLod with Lod operand) always samples from mip 0 regardless of the LOD argument when the sampled image is bound through VK_EXT_descriptor_heap with VK_DESCRIPTOR_MAPPING_SOURCE_HEAP_WITH_PUSH_INDEX_EXT.
texelFetch (OpImageFetch with Lod) works correctly through the same descriptor heap path, returning the correct per-mip value for every level. This confirms the mip data is uploaded correctly and the descriptor heap binding is functional — the issue is specific to OpImageSampleExplicitLod.
The bug reproduces with both GLSL (glslc) and Slang (slangc) compiled SPIR-V, ruling out a compiler issue.
Reproducer:
A minimal standalone compute-only reproducer is available at: https://github.com/foijord/vk-textureLod-repro
It creates a 16x16 R8_UNORM image with 5 mip levels, each filled with a distinct constant value, then dispatches a compute shader that samples at LODs 0–4 using both textureLod and texelFetch.
Output (bug present):
Texture2D textureLod with VK_EXT_descriptor_heap:
textureLod(sampler2D(tex, samp), uv, lod):
LOD 0: expected=1.000 actual=1.000 OK
LOD 1: expected=0.749 actual=1.000 FAIL
LOD 2: expected=0.502 actual=1.000 FAIL
LOD 3: expected=0.251 actual=1.000 FAIL
LOD 4: expected=0.000 actual=1.000 FAIL
texelFetch(sampler2D(tex, samp), texel, lod):
LOD 0: expected=1.000 actual=1.000 OK
LOD 1: expected=0.749 actual=0.749 OK
LOD 2: expected=0.502 actual=0.502 OK
LOD 3: expected=0.251 actual=0.251 OK
LOD 4: expected=0.000 actual=0.000 OK
All textureLod calls return the mip 0 value (1.000). texelFetch returns the correct value at every level.