NVIDIA-RTX / NVIDIA-RTX/Streamline

Streamline DLSS-G (Vulkan) — pacer reuses its present-semaphore -> VUID-vkQueueSubmit-pSignalSemaphores-00067

Open
#112 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ack bug
Dominant language
C
Stars
1.2k
Forks
159
PR merge metrics
No merged PRs in 30d

Description

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

  1. Initialize Streamline in interposer mode; load DLSS-G.
  2. Render + present normally through the interposed swapchain.
  3. 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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the DLSS-G Vulkan pacer path around vkQueueSubmit and vkQueuePresentKHR, then trace creation and reuse of nv.sl.dlss_g.cmdCtx.pacer.present-semaphore. Compare the pacer's synchronization with the per-swapchain-image and VK_KHR_swapchain_maintenance1 alternatives described in the issue. Done means the supplied reproduction no longer reports VUID-vkQueueSubmit-pSignalSemaphores-00067.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.