stride3d/stride · error · InvalidOperationException

Vulkan: no memory type satisfies the IOSurface…

Error message

Vulkan: no memory type satisfies the IOSurface memoryTypeBits mask.

What it means

During IOSurface import, Stride queries IOSurface memory requirements via vkGetMetalIOSurfaceCreateInfoEXT/vkBindMetalIOSurface flow and picks a Vulkan memory type from the returned memoryTypeBits mask. FindMemoryTypeIndex throws InvalidOperationException when no physical-device memory type intersects that mask, meaning the driver cannot back this IOSurface import with any available memory.

Solutions

  1. Recreate the IOSurface with GPU-capable storage/usage (kIOSurfaceStorageModeShared or GPU-friendly pixel format such as BGRA8/RGBA8).
  2. Verify the IOSurface pixel format is one the Vulkan/MoltenVK implementation can import (e.g. MTLPixelFormat-compatible formats like BGRA8Unorm).
  3. Update MoltenVK to a newer release with complete metal_objects support, then rebuild the device with VK_EXT_metal_objects enabled.
  4. Fall back to reading the IOSurface pixels on CPU and uploading through Texture.Load/regular staging upload instead of direct import.

Example fix

// before: CPU-only IOSurface
var ioSurface = IOSurface.Create(width, height, kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange, kIOSurfaceStorageModePrivate);

// after: GPU-shareable format/storage
var ioSurface = IOSurface.Create(width, height, kCVPixelFormatType_32BGRA, kIOSurfaceStorageModeShared);
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    texture = Texture.NewFromIOSurface(device, ioSurface, width, height);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("memoryTypeBits"))
{
    log.Error("IOSurface has no compatible Vulkan memory type; falling back to CPU upload.");
    texture = UploadSurfaceData(device, ioSurface, width, height);
}

Prevention

When it happens

Trigger: Calling NewFromIOSurface where vkGetIOSurfaceProperties/Metal-objects property query yields a memoryTypeBits mask of 0 or disjoint from all device memory types; importing an IOSurface with pixel format/usage not supported by the GPU; MoltenVK reporting incomplete memory requirements for the surface.

Common situations: Importing IOSurfaces with exotic pixel formats or non-GPU-compatible usages; old MoltenVK builds with incomplete VK_EXT_metal_objects implementations; surfaces created by another subsystem (camera, video decode) without GPU-readable storage modes; mismatched storage mode (CPU-only) IOSurfaces.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Vulkan/Texture.Apple.Vulkan.cs:154

            texture.NativeImage = image;
            texture.NativeMemory = memory;
            texture.NativeImageView = imageView;
            texture.NativeFormat = VkFormat.B8G8R8A8Srgb;
            texture.ioSurfaceRef = ioSurface;
            texture.isImportedImage = true;
            texture.InitializeFrom(description);
            return texture;
        }

        private static unsafe uint FindMemoryTypeIndex(GraphicsDevice device, uint memoryTypeBits)
        {
            device.NativeInstanceApi.vkGetPhysicalDeviceMemoryProperties(device.NativePhysicalDevice, out var memoryProperties);
            for (uint i = 0; i < memoryProperties.memoryTypeCount; i++)
            {
                if ((memoryTypeBits & (1u << (int)i)) != 0)
                    return i;
            }
            throw new InvalidOperationException("Vulkan: no memory type satisfies the IOSurface memoryTypeBits mask.");
        }

        [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
        private static extern IntPtr CFRetain(IntPtr cf);

        [DllImport("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")]
        private static extern void CFRelease(IntPtr cf);
    }
}
#endif

View on GitHub (pinned to 96fad776d2)