[Fix] (DirectVulkan): submit a generated mip chain before a later upload can overtake it

Texture uploads go out on a command buffer of their own the moment they happen, while
glGenerateMipmap records its blit chain into the frame's command buffer, which is not
submitted until the frame ends. So a glTexSubImage2D into a level that was just
generated reached the GPU FIRST and the blits then wrote over it.

KHR-GL40.texture_gather.base-level does exactly that - generates the chain, then writes
the texels it is going to sample into level 1 and points TEXTURE_BASE_LEVEL at it - and
read back the generated content instead of what it had written. The image view, the mip
range and the upload itself were all correct; only their order on the GPU was not.

This is the same hazard the mip-chain-growth recreate above already flushes for, from
the other side: there the recorded work had to reach the GPU before an out-of-band copy
read the image, here before an out-of-band copy writes it. Submitting at the end of the
generation orders every upload that can follow.
This commit is contained in:
BZLZHH
2026-08-04 19:18:03 -04:00
parent 9dcda82d71
commit a50b2c422b
@@ -8013,6 +8013,18 @@ void main() {
}
resource->layout = finalLayout;
// The chain above is GPU work recorded into this frame's command buffer, which is not
// submitted until the frame ends - but a texture upload goes out on a command buffer of
// its own the moment it happens. A glTexSubImage2D into a level this just generated
// would therefore reach the GPU FIRST and be overwritten by these blits, which is how
// KHR-GL40.texture_gather.base-level lost the texels it wrote into level 1 right after
// generating the chain. Submitting here is what orders the two.
if (HasPendingRecordedWork() && FlushPendingCommands()) {
// Fresh command buffer: the sampled-descriptor-set memo describes bindings that
// only existed in the retired one.
m_lastSampledSetValid = false;
}
}
Uint32 VulkanRenderer::CurrentXfbCounterSlot() {