stride3d/stride · error · InvalidOperationException

Vulkan: Timeline semaphores are not supported by this…

Error message

Vulkan: Timeline semaphores are not supported by this device, but are required by Stride.

What it means

Timeline semaphores (Vulkan 1.2 core feature) are mandatory for Stride's synchronization model. During device creation Stride queries vkGetPhysicalDeviceFeatures2 and throws InvalidOperationException if supportedVulkan12Features.timelineSemaphore is false.

Solutions

  1. Update the GPU driver to one that supports timeline semaphores
  2. Choose a different physical device via GraphicsAdapterFactory
  3. For MoltenVK, update to a recent MoltenVK version with timeline semaphore support
  4. Avoid virtual/para-virtual GPUs that mask this feature
Defensive patterns

Strategy: validation

Validate before calling

var features = adapter.QueryVulkan12Features();
if (!features.timelineSemaphore)
    Logger.Error("Adapter lacks timeline semaphores; cannot use Stride Vulkan backend.");

Type guard

static bool SupportsTimelineSemaphores(GraphicsAdapter a) =>
    a.QueryVulkan12Features().timelineSemaphore;

Try / catch

try
{
    var device = new GraphicsDevice(adapter, ...);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Timeline semaphores"))
{
    Logger.Error(ex, "Selecting another adapter.");
    TryNextAdapter();
}

Prevention

When it happens

Trigger: Creating a GraphicsDevice on a device/driver whose physical device features report timelineSemaphore == VK_FALSE, even if the device claims Vulkan 1.2+.

Common situations: Drivers that advertise Vulkan 1.2 but disable timeline semaphores (some older mobile/Android drivers); MoltenVK or portability layers with incomplete feature sets; virtualized GPUs (VM GPU drivers) lacking the feature.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/dc00d67becbb1d51. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs:571

                sType = VkStructureType.PhysicalDeviceVulkan11Features,
                pNext = &supportedVulkan12Features,
            };
            // Portability subset features (MoltenVK only) — queried so we can forward the device-reported
            // capabilities verbatim to vkCreateDevice, which is what the portability spec requires.
            var portabilitySubsetFeatures = new VkPhysicalDevicePortabilitySubsetFeaturesKHR
            {
                sType = VkStructureType.PhysicalDevicePortabilitySubsetFeaturesKHR,
                pNext = &supportedVulkan11Features,
            };
            var physicalDeviceFeatures2 = new VkPhysicalDeviceFeatures2
            {
                sType = VkStructureType.PhysicalDeviceFeatures2,
                pNext = isPortabilitySubsetDevice ? (void*)&portabilitySubsetFeatures : &supportedVulkan11Features,
            };
            NativeInstanceApi.vkGetPhysicalDeviceFeatures2(NativePhysicalDevice, &physicalDeviceFeatures2);

            if (!supportedVulkan12Features.timelineSemaphore)
                throw new InvalidOperationException("Vulkan: Timeline semaphores are not supported by this device, but are required by Stride.");

            // Dynamic rendering is required: the backend renders with vkCmdBeginRendering and
            // creates no render pass objects. Synchronization2 is required for vkQueueSubmit2.
            if (!supportedVulkan13Features.dynamicRendering || !supportedVulkan13Features.synchronization2)
                throw new NotSupportedException("Vulkan: Dynamic rendering and synchronization2 are not supported by this device, but are required by Stride.");

            var enabledVulkan13Features = new VkPhysicalDeviceVulkan13Features
            {
                sType = VkStructureType.PhysicalDeviceVulkan13Features,
                dynamicRendering = VkBool32.True,
                synchronization2 = VkBool32.True,
            };
            var enabledVulkan12Features = new VkPhysicalDeviceVulkan12Features
            {
                sType = VkStructureType.PhysicalDeviceVulkan12Features,
                pNext = &enabledVulkan13Features,
                timelineSemaphore = VkBool32.True,
                uniformBufferStandardLayout = VkBool32.True,

View on GitHub (pinned to 96fad776d2)