ZEngine — Bindless Texture Descriptors¶
Status: Implemented current path; texture-residency eviction remains future work. Depends on: Vulkan descriptor-indexing support when available, shader reflection, and the device/resource lifetime path.
Current contract¶
ZEngine owns one global texture-handle pool in VulkanDevice. Its requested upper
capacity is MaxGlobalTexture = 8192, clamped during device initialization to the
device's maxPerStageDescriptorUpdateAfterBindSampledImages - 1 limit. The effective
capacity is device-dependent; 8192 is not a portability guarantee.
Reserved shader set 1 currently contains:
| Binding | Resource |
|---|---|
| 0 | TextureArray of sampled images |
| 1 | LinearWrapSampler |
| 2 | LinearClampSampler |
There is one reserved descriptor set for each configured swapchain buffered frame. The
same texture handle index is written into each set. Descriptor-indexing flags and the
update-after-bind descriptor-pool flag are enabled only when
PhysicalDeviceSupportSampledImageBindless is available.
Any shader that dynamically indexes TextureArray must use
GL_EXT_nonuniform_qualifier and nonuniformEXT(index). This is already the
contract in Resources/Shaders/zui_draw.frag; new shader paths must preserve it.
Update and lifetime path¶
VulkanDevice::FlushBindlessTextureUpdates() drains pending texture handles and
batches its normal descriptor writes into one vkUpdateDescriptorSets call. The
one-frame fallback path still writes fallback descriptors individually before requeuing
the real update. It also emits one 75%-capacity watermark warning per process.
Texture destruction is timeline-deferred through the device's resource-lifetime path. A valid handle index does not prove that a texture is ready for a particular frame; callers must follow the existing fallback/update flow.
Open work¶
Geometry streaming is present, but it is not texture streaming. A production texture residency design must add measured memory accounting, cancellation, reference/visibility policy, protected engine/UI slots, eviction, and fallback behavior without invalidating descriptors referenced by in-flight work. It should be planned with asset streaming rather than assumed to be a prerequisite that is already solved.