Summary
With DLSS-G enabled through Streamline's Vulkan interposer, the validation layer reports
VUID-vkQueueSubmit-pSignalSemaphores-00067 every frame. SL's own pacer queue
(nv.sl.dlss_g.cmdQ.pacer) re-signals its own present-semaphore
(nv.sl.dlss_g.cmdCtx.pacer.present-semaphore) for a new swapchain image before the previously
presented image using that semaphore has been re-acquired (or waited on with a
VK_KHR_swapchain_maintenance1 present fence). All objects in the error are SL-owned
(nv.sl.dlss_g.*); the application never submits to that queue or signals that semaphore.
Environment
- GPU: NVIDIA GeForce RTX 5090 (discrete).
- Driver: NVIDIA 610.47 (
driverVersion 610.47.0.0).
- Vulkan: instance/loader 1.4.350, device
apiVersion 1.4.341; app requests VK_API_VERSION_1_4.
- Vulkan SDK: 1.4.350.0. Validation layer:
VK_LAYER_KHRONOS_validation (1.4.350 SDK).
- OS: Windows 11 Pro 10.0.26200 (x64).
- Streamline SDK: v2.12.0 (interposer mode —
slInit → interposing vkGetInstanceProcAddr fed to
the Vulkan loader). Also reproduced on v2.11.1.
- SL features loaded:
kFeatureDLSS (Super-Res/DLAA), kFeatureDLSS_RR, kFeatureReflex,
kFeaturePCL, kFeatureDLSS_G. (The repro requires kFeatureDLSS_G; with it removed and the other
four still loaded, the run is 100% validation-clean.)
Enabled Vulkan extensions (application-requested; Streamline adds its own DLSS/Reflex instance+device extensions transparently via the interposer)
- Instance:
VK_KHR_surface, VK_KHR_win32_surface (GLFW), VK_EXT_debug_utils (debug builds).
(VK_EXT_validation_features is intentionally NOT requested when SL interposes — SL's vkCreateInstance
wrapper rejects it.)
- Device:
VK_KHR_swapchain, VK_EXT_memory_budget, VK_KHR_acceleration_structure,
VK_KHR_ray_query, VK_KHR_deferred_host_operations.
- Relevant enabled features: Vulkan 1.2 (
descriptorIndexing, timelineSemaphore, bufferDeviceAddress,
runtimeDescriptorArray, descriptorBinding*), Vulkan 1.3 (privateData, synchronization2,
dynamicRendering), extendedDynamicState, accelerationStructure, rayQuery, multiDrawIndirect,
drawIndirectFirstInstance, samplerAnisotropy, shaderDrawParameters.
Application present/sync setup (the app already follows the recommended 00067-avoiding pattern)
- UNORM swapchain (
VK_FORMAT_B8G8R8A8_UNORM, eSrgbNonlinear), imageUsage = COLOR_ATTACHMENT | TRANSFER_SRC | TRANSFER_DST, minImageCount 3 (also tried 6), present via vkQueuePresentKHR (interposed).
- The application's render-finished binary semaphores are allocated per swapchain image and indexed by
the acquired image index (approach (a) from the swapchain-semaphore-reuse guide — the recommended way
to avoid 00067); acquire (present-complete) semaphores are per-frame; single graphics+present queue;
timeline semaphore for frame pacing. So the application's own present synchronization does not trip
00067. The flagged semaphore (nv.sl.dlss_g.cmdCtx.pacer.present-semaphore) is not an application
semaphore — it is signaled on SL's own pacer queue, which does not follow either recommended approach.
Repro
- Initialize Streamline in interposer mode; load DLSS-G.
- Render + present normally through the interposed swapchain.
- The VUID fires continuously — even with DLSS-G mode =
eOff (the pacer owns present once DLSS-G is
loaded), i.e. it does not require an active frame-generation multiplier.
Exact validation message
Capture from the baseline config: minImageCount requested = 3, driver allocated exactly 3
images (confirmed via vkGetSwapchainImagesKHR), no VK_KHR_swapchain_maintenance1.
vkQueueSubmit(): pSubmits[0].pSignalSemaphores[1] (VkSemaphore 0x...[nv.sl.dlss_g.cmdCtx.pacer.present-semaphore])
is being signaled by VkQueue 0x...[nv.sl.dlss_g.cmdQ.pacer], but it may still be in use by VkSwapchainKHR 0x...[Swapchain].
Most recently acquired image indices: 0, 0, 0, 0, 0, 0, [0], 1.
(Brackets mark the last use of VkSemaphore 0x...[nv.sl.dlss_g.cmdCtx.pacer.present-semaphore] in a presentation operation.)
Swapchain image 0 was presented but was not re-acquired, so VkSemaphore 0x...[nv.sl.dlss_g.cmdCtx.pacer.present-semaphore]
may still be in use and cannot be safely reused with image index 1.
(VUID-vkQueueSubmit-pSignalSemaphores-00067)
Notes: the swapchain has 3 images (0, 1, 2); the "Most recently acquired image indices" line is
the validation layer's fixed rolling history of the last 8 vkAcquireNextImageKHR calls (not the image
count) — here the driver returned images 0/1 across those 8 acquires. With
VK_KHR_swapchain_maintenance1 enabled the wording changes to "…was neither re-acquired nor waited on
using a VK_KHR_swapchain_maintenance1 fence…" (see the verification notes below).
What was verified (application-side, all confirmed NOT the cause)
- Application does not own the offending objects. Logged every application
vkCreateImage handle —
the swapchain backbuffer SL copies/presents is not among them; the semaphore + queue are nv.sl.dlss_g.*.
--no-sl (no interposer) is 100% validation-clean — the error only exists when SL DLSS-G is active.
- Not loading
kFeatureDLSS_G (everything else SL — DLSS/DLAA/RR/Reflex/PCL — still loaded) is 100%
validation-clean. This isolates the error entirely to SL spinning up the DLSS-G pacer; it is unrelated
to the application's synchronization2/barrier usage or its own present synchronization.
- Enabling
VK_KHR/EXT_swapchain_maintenance1 does NOT help. We enabled VK_EXT_surface_maintenance1
(+ VK_KHR_get_surface_capabilities2) at instance level and VK_EXT_swapchain_maintenance1 + its feature
at device level (SL did not reject these; the device created successfully). The validation message then
updated to "…nor waited on using a VK_KHR_swapchain_maintenance1 fence…" — i.e. the capability is
present — but the pacer still does not use a present fence, so the VUID persists. The pacer's present
path does not adopt maintenance1 fences even when the device supports them.
- Increasing the requested swapchain
minImageCount does NOT help. Bumping from 3 to 6 made the
acquired-image indices cycle across all images (e.g. 2, 1, 3, 0, 4, 2, [1], 5 instead of 0, 0, …, [0], 1),
confirming more images are in flight — but the pacer still reuses a single present-semaphore across
them, so the VUID persists unchanged. The pacer does not allocate a present-semaphore per swapchain image.
Expected behavior
Per the Vulkan swapchain-semaphore-reuse guidance
(https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html), the code that calls
vkQueuePresentKHR (here, SL's pacer) must either (a) use a separate present-semaphore per swapchain
image, indexed by the acquired image index, or (b) use a VK_KHR_swapchain_maintenance1 present
fence. The pacer currently does neither, reusing a single present-semaphore across images before the
prior present completes.
Request
Have the DLSS-G Vulkan pacer either allocate per-acquired-image present-semaphores or adopt
VK_KHR_swapchain_maintenance1 present fences (when the device enables the extension) so it no longer
trips VUID-vkQueueSubmit-pSignalSemaphores-00067.
Summary
With DLSS-G enabled through Streamline's Vulkan interposer, the validation layer reports
VUID-vkQueueSubmit-pSignalSemaphores-00067every frame. SL's own pacer queue(
nv.sl.dlss_g.cmdQ.pacer) re-signals its own present-semaphore(
nv.sl.dlss_g.cmdCtx.pacer.present-semaphore) for a new swapchain image before the previouslypresented image using that semaphore has been re-acquired (or waited on with a
VK_KHR_swapchain_maintenance1present fence). All objects in the error are SL-owned(
nv.sl.dlss_g.*); the application never submits to that queue or signals that semaphore.Environment
driverVersion610.47.0.0).apiVersion1.4.341; app requestsVK_API_VERSION_1_4.VK_LAYER_KHRONOS_validation(1.4.350 SDK).slInit→ interposingvkGetInstanceProcAddrfed tothe Vulkan loader). Also reproduced on v2.11.1.
kFeatureDLSS(Super-Res/DLAA),kFeatureDLSS_RR,kFeatureReflex,kFeaturePCL,kFeatureDLSS_G. (The repro requireskFeatureDLSS_G; with it removed and the otherfour still loaded, the run is 100% validation-clean.)
Enabled Vulkan extensions (application-requested; Streamline adds its own DLSS/Reflex instance+device extensions transparently via the interposer)
VK_KHR_surface,VK_KHR_win32_surface(GLFW),VK_EXT_debug_utils(debug builds).(
VK_EXT_validation_featuresis intentionally NOT requested when SL interposes — SL'svkCreateInstancewrapper rejects it.)
VK_KHR_swapchain,VK_EXT_memory_budget,VK_KHR_acceleration_structure,VK_KHR_ray_query,VK_KHR_deferred_host_operations.descriptorIndexing,timelineSemaphore,bufferDeviceAddress,runtimeDescriptorArray,descriptorBinding*), Vulkan 1.3 (privateData,synchronization2,dynamicRendering),extendedDynamicState,accelerationStructure,rayQuery,multiDrawIndirect,drawIndirectFirstInstance,samplerAnisotropy,shaderDrawParameters.Application present/sync setup (the app already follows the recommended 00067-avoiding pattern)
VK_FORMAT_B8G8R8A8_UNORM,eSrgbNonlinear),imageUsage = COLOR_ATTACHMENT | TRANSFER_SRC | TRANSFER_DST,minImageCount3 (also tried 6), present viavkQueuePresentKHR(interposed).the acquired image index (approach (a) from the swapchain-semaphore-reuse guide — the recommended way
to avoid 00067); acquire (present-complete) semaphores are per-frame; single graphics+present queue;
timeline semaphore for frame pacing. So the application's own present synchronization does not trip
00067. The flagged semaphore (
nv.sl.dlss_g.cmdCtx.pacer.present-semaphore) is not an applicationsemaphore — it is signaled on SL's own pacer queue, which does not follow either recommended approach.
Repro
eOff(the pacer owns present once DLSS-G isloaded), i.e. it does not require an active frame-generation multiplier.
Exact validation message
Capture from the baseline config:
minImageCountrequested = 3, driver allocated exactly 3images (confirmed via
vkGetSwapchainImagesKHR), noVK_KHR_swapchain_maintenance1.Notes: the swapchain has 3 images (
0,1,2); the "Most recently acquired image indices" line isthe validation layer's fixed rolling history of the last 8
vkAcquireNextImageKHRcalls (not the imagecount) — here the driver returned images
0/1across those 8 acquires. WithVK_KHR_swapchain_maintenance1enabled the wording changes to "…was neither re-acquired nor waited onusing a VK_KHR_swapchain_maintenance1 fence…" (see the verification notes below).
What was verified (application-side, all confirmed NOT the cause)
vkCreateImagehandle —the swapchain backbuffer SL copies/presents is not among them; the semaphore + queue are
nv.sl.dlss_g.*.--no-sl(no interposer) is 100% validation-clean — the error only exists when SL DLSS-G is active.kFeatureDLSS_G(everything else SL — DLSS/DLAA/RR/Reflex/PCL — still loaded) is 100%validation-clean. This isolates the error entirely to SL spinning up the DLSS-G pacer; it is unrelated
to the application's
synchronization2/barrier usage or its own present synchronization.VK_KHR/EXT_swapchain_maintenance1does NOT help. We enabledVK_EXT_surface_maintenance1(+
VK_KHR_get_surface_capabilities2) at instance level andVK_EXT_swapchain_maintenance1+ its featureat device level (SL did not reject these; the device created successfully). The validation message then
updated to "…nor waited on using a VK_KHR_swapchain_maintenance1 fence…" — i.e. the capability is
present — but the pacer still does not use a present fence, so the VUID persists. The pacer's present
path does not adopt maintenance1 fences even when the device supports them.
minImageCountdoes NOT help. Bumping from 3 to 6 made theacquired-image indices cycle across all images (e.g.
2, 1, 3, 0, 4, 2, [1], 5instead of0, 0, …, [0], 1),confirming more images are in flight — but the pacer still reuses a single present-semaphore across
them, so the VUID persists unchanged. The pacer does not allocate a present-semaphore per swapchain image.
Expected behavior
Per the Vulkan swapchain-semaphore-reuse guidance
(https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html), the code that calls
vkQueuePresentKHR(here, SL's pacer) must either (a) use a separate present-semaphore per swapchainimage, indexed by the acquired image index, or (b) use a
VK_KHR_swapchain_maintenance1presentfence. The pacer currently does neither, reusing a single present-semaphore across images before the
prior present completes.
Request
Have the DLSS-G Vulkan pacer either allocate per-acquired-image present-semaphores or adopt
VK_KHR_swapchain_maintenance1present fences (when the device enables the extension) so it no longertrips
VUID-vkQueueSubmit-pSignalSemaphores-00067.