Skip to content

Instance.kt

src/jvmMain/kotlin/afield/graphics/vulkan/device/Instance.kt · 941 lines

package afield.graphics.vulkan.device

import afield.graphics.vulkan.util.OS
import afield.graphics.vulkan.util.OSType
import afield.graphics.vulkan.util.Options
import afield.graphics.vulkan.util.vkCheck
import afield.app.diagnostics.logging.lprint
import afield.app.diagnostics.logging.lprintln
import org.lwjgl.PointerBuffer
import org.lwjgl.glfw.GLFWVulkan
import org.lwjgl.openxr.*
import org.lwjgl.openxr.KHRVulkanEnable2.xrGetVulkanGraphicsRequirements2KHR
import org.lwjgl.system.MemoryStack
import org.lwjgl.system.MemoryUtil
import org.lwjgl.vulkan.*
import org.lwjgl.vulkan.EXTDebugUtils
import org.lwjgl.vulkan.EXTLayerSettings.VK_LAYER_SETTING_TYPE_BOOL32_EXT
import org.lwjgl.vulkan.EXTLayerSettings.VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT
import org.lwjgl.vulkan.KHRPortabilityEnumeration.VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR
import org.lwjgl.vulkan.VK10.VK_INCOMPLETE
import org.lwjgl.vulkan.VK10.VK_SUCCESS
import java.nio.ByteBuffer
import java.nio.IntBuffer
import java.nio.charset.CodingErrorAction
import java.nio.charset.StandardCharsets
import java.util.concurrent.atomic.AtomicBoolean

The Vulkan instance: SDK and driver selection, layers, extensions and the debug messenger.

Instance calls Options.doVulkanSDK before anything else, so the loader and driver it gets are the ones Field chose (KosmicKrisp or MoltenVK on macOS). It enables the validation layer when validation or shader debugPrintf is requested and a layer is installed, adds VK_KHR_portability_enumeration on macOS when the loader offers it, and records what it actually enabled in enabledExtensions. With VR enabled and an OpenXR runtime bootstrapped, the instance is created through OpenXR's xrCreateVulkanInstanceKHR, so the runtime can add the extensions it needs.

class Instance(private val validate: Boolean)

class Instance(private val validate: Boolean) {

var vkInstance: VkInstance

    var vkInstance: VkInstance
        private set

val enabledExtensions: Set<String>

Vulkan instance extensions actually enabled at creation time.

    private var debugUtilsCreateInfo: VkDebugUtilsMessengerCreateInfoEXT? = null
    private var vkDebugHandle: Long = 0

internal val validationActive: Boolean get() = validate && vkDebugHandle != VK10.VK_NULL_HANDLE

init

body — 163 lines, from line 51
    init {
        Options.doVulkanSDK()
        if (Options.enableVR) {
            prepareOpenXRBootstrap()
        }
        MemoryStack.stackPush().use { stack ->
            // --- Application info
            val appShortName = stack.UTF8("VulkanBook")
            val appInfo = VkApplicationInfo.calloc(stack)
                .sType(VK10.VK_STRUCTURE_TYPE_APPLICATION_INFO)
                .pApplicationName(appShortName)
                .applicationVersion(1)
                .pEngineName(appShortName)
                .engineVersion(0)
                .apiVersion(VK13.VK_API_VERSION_1_3)

            // --- Layers
            val validationLayers = supportedValidationLayers
            val wantsValidationLayer = validate || Options.shaderDebugPrintf
            val wantsDebugPrintf = validate || Options.shaderDebugPrintf
            val supportsValidation = wantsValidationLayer && validationLayers.isNotEmpty()
            if (wantsValidationLayer && !supportsValidation) {
                lprintln("warning,vulkan", "Requested validation layer features, but no supported layers found")
            }

            var requiredLayers: PointerBuffer? = null
            if (supportsValidation) {
                requiredLayers = stack.mallocPointer(validationLayers.size)
                validationLayers.forEachIndexed { i, name -> requiredLayers.put(i, stack.ASCII(name)) }
            }

            // --- Discover supported instance extensions
            val supportedExts = instanceExtensions

            // --- GLFW-required instance extensions
            val glfwExts = GLFWVulkan.glfwGetRequiredInstanceExtensions()
                ?: throw RuntimeException(
                    "Failed to find GLFW platform surface extensions. " +
                            "Either Vulkan is not set up or this platform configuration is unsupported."
                )

            val hasPortabilityEnumeration = PORTABILITY_EXTENSION in supportedExts
            val usePortability = (OS == OSType.MACOS) && hasPortabilityEnumeration
            val hasDebugUtils = EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME in supportedExts
            val hasLayerSettings = "VK_EXT_layer_settings" in supportedExts
            val hasValidationFeatures =
                EXTValidationFeatures.VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME in supportedExts

            // --- Build extension list
            val extNames = ArrayList<String>(glfwExts.remaining() + 6).apply {
                while (glfwExts.hasRemaining()) add(MemoryUtil.memUTF8(glfwExts.get()))
                if (supportsValidation && hasDebugUtils) add(EXTDebugUtils.VK_EXT_DEBUG_UTILS_EXTENSION_NAME)
                if (supportsValidation && hasValidationFeatures) add(EXTValidationFeatures.VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)
                if (supportsValidation && hasLayerSettings) add("VK_EXT_layer_settings")
                if (usePortability && PORTABILITY_EXTENSION !in this) add(PORTABILITY_EXTENSION) // VK_KHR_portability_enumeration
                if (Options.enableVR) addAll(getOpenXRRequiredInstanceExts())
                // Required instance-side dependency of VK_EXT_present_timing. Device decides
                // whether the complete device-side dependency bundle is available.
                if (KHRGetSurfaceCapabilities2.VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME in supportedExts) {
                    add(KHRGetSurfaceCapabilities2.VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)
                }
                // VK_EXT_swapchain_colorspace enables HDR surface format enumeration (scRGB, HDR10, etc.)
                if (Options.enableHDR && SWAPCHAIN_COLORSPACE_EXTENSION in supportedExts) add(SWAPCHAIN_COLORSPACE_EXTENSION)
            }
            extNames.addAll(afield.media.reconstruction.NgxSupport.instanceExtensions(supportedExts))
            val dedupedExtNames = extNames.distinct()
            enabledExtensions = dedupedExtNames.toSet()

            val requiredExtensions = stack.mallocPointer(dedupedExtNames.size).apply {
                dedupedExtNames.forEach { put(stack.ASCII(it)) }
                flip()
            }

            // --- Optional pNext chain
            var pNextHead: Long = MemoryUtil.NULL

            // Debug utils callback create-info
            if (supportsValidation && hasDebugUtils) {
                debugUtilsCreateInfo = createDebugCallBack()
                pNextHead = debugUtilsCreateInfo!!.address()
            }

            // Validation features. Shader printf is implemented by the validation layer; when
            // full validation is off, keep the layer loaded but disable core checks.
            if (supportsValidation && hasValidationFeatures) {
                val enables = if (wantsDebugPrintf) {
                    stack.ints(EXTValidationFeatures.VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT)
                } else {
                    null
                }
                val disables = if (!validate && wantsDebugPrintf) {
                    stack.ints(EXTValidationFeatures.VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT)
                } else {
                    null
                }
                val vfeat = VkValidationFeaturesEXT.calloc(stack)
                    .sType(EXTValidationFeatures.VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT)
                    .pEnabledValidationFeatures(enables)
                    .pDisabledValidationFeatures(disables)
                    .pNext(pNextHead)
                pNextHead = vfeat.address()
            }

            // Layer settings (optional)
            if (supportsValidation && hasLayerSettings) {
                val settings = VkLayerSettingEXT.calloc(1, stack)
                settings[0]
                    .pLayerName(stack.UTF8("VK_LAYER_KHRONOS_validation"))
                    .pSettingName(stack.UTF8("enable_message_limit"))
                    .type(VK_LAYER_SETTING_TYPE_BOOL32_EXT)
                    .valueCount(1)
                    .pValues(stack.bytes(0, 0, 0, 0))

                val layerSettings = VkLayerSettingsCreateInfoEXT.calloc(stack)
                    .sType(VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT)
                    .pSettings(settings)
                    .pNext(pNextHead)

                pNextHead = layerSettings.address()
            }

            // --- Instance create info
            val instanceInfo = VkInstanceCreateInfo.calloc(stack)
                .sType(VK10.VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO)
                .pNext(pNextHead)
                .pApplicationInfo(appInfo)
                .ppEnabledLayerNames(requiredLayers)
                .ppEnabledExtensionNames(requiredExtensions)

            if (usePortability) {
                instanceInfo.flags(instanceInfo.flags() or VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR)
            } else if (OS == OSType.MACOS && !hasPortabilityEnumeration) {
                lprintln("warning,vulkan", "VK_KHR_portability_enumeration not available; continuing without portability enumeration")
            }

            if (Options.enableVR && xrBootstrap != null) {
                lprint("openxr", "using xrBootstrap")
                vkInstance = createVkInstanceViaXR(instanceInfo)
            } else {
                lprint("openxr", "not using xrBootstrap")
                val pInstance = stack.mallocPointer(1)
                vkCheck(VK10.vkCreateInstance(instanceInfo, null, pInstance), "Error creating instance")
                vkInstance = VkInstance(pInstance[0], instanceInfo)
            }

            if (Options.enableVR) {
                updateOpenXRBootstrapPhys(vkInstance)
            }

            // --- Debug messenger (if validation on)
            vkDebugHandle = VK10.VK_NULL_HANDLE
            if (supportsValidation && hasDebugUtils) {
                val p = stack.mallocLong(1)
                vkCheck(
                    EXTDebugUtils.vkCreateDebugUtilsMessengerEXT(
                        vkInstance, debugUtilsCreateInfo!!, null, p
                    ),
                    "Error creating debug utils messenger"
                )
                vkDebugHandle = p[0]
            }
        }
    }

fun cleanup()

    fun cleanup() {
        if (vkDebugHandle != VK10.VK_NULL_HANDLE) {
            EXTDebugUtils.vkDestroyDebugUtilsMessengerEXT(vkInstance, vkDebugHandle, null)
        }
        VK10.vkDestroyInstance(vkInstance, null)
        debugUtilsCreateInfo?.pfnUserCallback()?.free()
        debugUtilsCreateInfo?.free()
    }

Helpers

    private val instanceExtensions: Set<String>
        get() {
            val out = HashSet<String>()
            MemoryStack.stackPush().use { stack ->
                val count = stack.callocInt(1)
                VK10.vkEnumerateInstanceExtensionProperties(null as String?, count, null)
                val props = VkExtensionProperties.calloc(count[0], stack)
                VK10.vkEnumerateInstanceExtensionProperties(null as String?, count, props)
                repeat(props.capacity()) { i -> out += props[i].extensionNameString() }
            }
            return out
        }

    private val supportedValidationLayers: List<String>
        get() {
            MemoryStack.stackPush().use { stack ->
                val count = stack.callocInt(1)
                VK10.vkEnumerateInstanceLayerProperties(count, null)
                val props = VkLayerProperties.calloc(count[0], stack)
                VK10.vkEnumerateInstanceLayerProperties(count, props)
                val supported =
                    buildList(props.capacity()) { repeat(props.capacity()) { i -> add(props[i].layerNameString()) } }

                return when {
                    "VK_LAYER_KHRONOS_validation" in supported -> listOf("VK_LAYER_KHRONOS_validation")
                    "VK_LAYER_LUNARG_standard_validation" in supported -> listOf("VK_LAYER_LUNARG_standard_validation")
                    else -> listOf(
                        "VK_LAYER_GOOGLE_threading",
                        "VK_LAYER_LUNARG_parameter_validation",
                        "VK_LAYER_LUNARG_object_tracker",
                        "VK_LAYER_LUNARG_core_validation",
                        "VK_LAYER_GOOGLE_unique_objects"
                    ).filter { it in supported }
                }
            }
        }

companion object

    companion object {
        private const val PORTABILITY_EXTENSION = "VK_KHR_portability_enumeration"

internal const val SWAPCHAIN_COLORSPACE_EXTENSION = "VK_EXT_swapchain_colorspace"

Instance extension that exposes extended colorspaces (scRGB, HDR10, Display-P3, …)

data class OpenXRBootstrap

        data class OpenXRBootstrap(
            val xrInstance: XrInstance,
            val systemId: Long,
            var xrPhys: Long?,
            val minApi: Int,
            val maxApi: Int,
            var consumed: Boolean = false
        )

var globalAsyncDebugHandler: ((String) -> Unit)? = null

        private val reportedSteamVrBlankEyeValidationNoise = AtomicBoolean(false)

        private val openXRVulkanExtensions = listOf(
            KHRVulkanEnable2.XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME
        ) + if (OS == OSType.LINUX) emptyList() else listOf(
            KHRVulkanEnable.XR_KHR_VULKAN_ENABLE_EXTENSION_NAME
        )

        private val openXRValidationLayerCandidates = listOf(
            "XR_APILAYER_LUNARG_core_validation",
            "XR_APILAYER_KHRONOS_validation"
        )

fun getOpenXRRequiredInstanceExts(): List<String>

        fun getOpenXRRequiredInstanceExts(): List<String> {
            if (!Options.enableVR) return emptyList()
            // XR_KHR_vulkan_enable2 lets the runtime amend VkInstanceCreateInfo itself.
            // Do not mix in the legacy XR_KHR_vulkan_enable extension-query path on Linux.
            if (OS == OSType.LINUX) return emptyList()
            ensureOpenXRExtensions()
            return xrCachedInstanceExts
        }

fun getOpenXRRequiredDeviceExts(@Suppress("unused_parameter") physicalDeviceAddr: Long): List<String>

        fun getOpenXRRequiredDeviceExts(@Suppress("unused_parameter") physicalDeviceAddr: Long): List<String> {
            if (!Options.enableVR) return emptyList()
            if (OS == OSType.LINUX) return emptyList()
            ensureOpenXRExtensions()
            return xrCachedDeviceExts
        }

fun prepareOpenXRBootstrap()

Create and cache an OpenXR instance/system before VkInstance/VkDevice creation (spec requires ordering).

body — 78 lines, from line 308
        fun prepareOpenXRBootstrap() {
            if (!Options.enableVR) return
            if (xrBootstrap != null) return
            MemoryStack.stackPush().use { stack ->
                val extNames = requiredOpenXRExtensions() ?: return
                val apiLayers = enabledOpenXRApiLayers()
                val appInfo = XrApplicationInfo.calloc(stack)
                appInfo.applicationName(stack.UTF8("afield"))
                appInfo.applicationVersion(1)
                appInfo.engineName(stack.UTF8("afield"))
                appInfo.engineVersion(1)
                appInfo.apiVersion(XR10.XR_API_VERSION_1_0)

                val createInfo = XrInstanceCreateInfo.calloc(stack)
                    .type(XR10.XR_TYPE_INSTANCE_CREATE_INFO)
                    .applicationInfo(appInfo)
                    .enabledExtensionNames(pointerBuffer(stack, extNames))
                    .enabledApiLayerNames(pointerBuffer(stack, apiLayers))

                val pInstance = stack.mallocPointer(1)
                val createdRes = XR10.xrCreateInstance(createInfo, pInstance)
                if (createdRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrCreateInstance (bootstrap) returned ${createdRes}")
                    return
                }

                val xrInstance = XrInstance(pInstance[0], createInfo)
                try {
                    val sysInfo = XrSystemGetInfo.calloc(stack)
                        .type(XR10.XR_TYPE_SYSTEM_GET_INFO)
                        .formFactor(XR10.XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY)
                    val pSys = stack.mallocLong(1)
                    val sysRes = XR10.xrGetSystem(xrInstance, sysInfo, pSys)
                    if (sysRes != XR10.XR_SUCCESS) {
                        lprint("error,openxr", "xrGetSystem (bootstrap) returned ${sysRes}")
                        XR10.xrDestroyInstance(xrInstance)
                        return
                    }
                    val systemId = pSys[0]

                    val gfxReq = XrGraphicsRequirementsVulkan2KHR.calloc(stack)
                        // LWJGL exposes Vulkan2 as an alias struct, but its Vulkan2 type constant
                        // is not the alias value accepted by current OpenXR validation/runtime.
                        .type(KHRVulkanEnable.XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR)
                    val gfxReqRes = xrGetVulkanGraphicsRequirements2KHR(xrInstance, systemId, gfxReq)
                    check(gfxReqRes == XR10.XR_SUCCESS) {
                        "xrGetVulkanGraphicsRequirements2KHR failed: $gfxReqRes"
                    }

                    val physInfo = XrVulkanGraphicsDeviceGetInfoKHR.calloc(stack)
                    if (OS != OSType.LINUX) {
                        // Legacy compatibility path retained for the existing Windows setup.
                        xrCachedInstanceExts = queryExts(stack) { cap, buf ->
                            org.lwjgl.openxr.KHRVulkanEnable.xrGetVulkanInstanceExtensionsKHR(xrInstance, systemId, cap, buf)
                        }
                        xrCachedDeviceExts = queryExts(stack) { cap, buf ->
                            org.lwjgl.openxr.KHRVulkanEnable.xrGetVulkanDeviceExtensionsKHR(xrInstance, systemId, cap, buf)
                        }
                    }

                    xrInitialized = true
                    xrBootstrap = OpenXRBootstrap(
                        xrInstance = xrInstance,
                        systemId = systemId,
                        xrPhys = null,
                        minApi = gfxReq.minApiVersionSupported().toInt(),
                        maxApi = gfxReq.maxApiVersionSupported().toInt()
                    )
                    lprintln(
                        "info,openxr",
                        "XR bootstrap ready: minApi=${VK10.VK_API_VERSION_MAJOR(gfxReq.minApiVersionSupported().toInt())}.${VK10.VK_API_VERSION_MINOR(gfxReq.minApiVersionSupported().toInt())} maxApi=${VK10.VK_API_VERSION_MAJOR(gfxReq.maxApiVersionSupported().toInt())}.${VK10.VK_API_VERSION_MINOR(gfxReq.maxApiVersionSupported().toInt())}"
                    )
                } catch (t: Throwable) {
                    XR10.xrDestroyInstance(xrInstance)
                    throw t
                }
            }
        }

fun updateOpenXRBootstrapPhys(vkInstance: VkInstance): Long?

After creating VkInstance via XR, query and cache the runtime-selected VkPhysicalDevice.

        fun updateOpenXRBootstrapPhys(vkInstance: VkInstance): Long? {
            if (!Options.enableVR) return null
            val b = xrBootstrap ?: return null
            MemoryStack.stackPush().use { stack ->
                val physInfo = XrVulkanGraphicsDeviceGetInfoKHR.calloc(stack)
                    .type(KHRVulkanEnable2.XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR)
                    .systemId(b.systemId)
                    .vulkanInstance(vkInstance)
                val pPhys = stack.mallocPointer(1)
                val physRes = KHRVulkanEnable2.xrGetVulkanGraphicsDevice2KHR(b.xrInstance, physInfo, pPhys)
                if (physRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrGetVulkanGraphicsDevice2KHR (phys update) returned ${physRes}")
                    return null
                }
                b.xrPhys = pPhys[0]
                return b.xrPhys
            }
        }

fun createVkInstanceViaXR(ci: VkInstanceCreateInfo): VkInstance

Create VkInstance through XR_KHR_vulkan_enable2 for VR path.

        fun createVkInstanceViaXR(ci: VkInstanceCreateInfo): VkInstance {
            val b = xrBootstrap ?: throw IllegalStateException("XR bootstrap missing for xrCreateVulkanInstanceKHR")
            MemoryStack.stackPush().use { stack ->
                val pfnGetInstanceProcAddr = VK.getFunctionProvider().getFunctionAddress("vkGetInstanceProcAddr")
                val xrCi = XrVulkanInstanceCreateInfoKHR.calloc(stack)
                    .type(KHRVulkanEnable2.XR_TYPE_VULKAN_INSTANCE_CREATE_INFO_KHR)
                    .systemId(b.systemId)
                    .createFlags(0)
                    .pfnGetInstanceProcAddr(pfnGetInstanceProcAddr)
                    .vulkanCreateInfo(ci)
                    .vulkanAllocator(null)

                val pOut = stack.mallocPointer(1)
                val pRes = stack.mallocInt(1)
                val res = KHRVulkanEnable2.xrCreateVulkanInstanceKHR(b.xrInstance, xrCi, pOut, pRes)
                if (res != XR10.XR_SUCCESS) {
                    throw RuntimeException("xrCreateVulkanInstanceKHR failed: ${res} (vkResult=${pRes[0]})")
                }
                return VkInstance(pOut[0], ci)
            }
        }

fun createVkDeviceViaXR(ci: VkDeviceCreateInfo, vkInstance: VkInstance, vkPhysicalDevice: VkPhysicalDevice): VkDevice

Create VkDevice through XR_KHR_vulkan_enable2 for VR path.

        fun createVkDeviceViaXR(ci: VkDeviceCreateInfo, vkInstance: VkInstance, vkPhysicalDevice: VkPhysicalDevice): VkDevice {
            val b = xrBootstrap ?: throw IllegalStateException("XR bootstrap missing for xrCreateVulkanDeviceKHR")
            MemoryStack.stackPush().use { stack ->
                val pfnGetInstanceProcAddr = VK.getFunctionProvider().getFunctionAddress("vkGetInstanceProcAddr")
                val xrCi = XrVulkanDeviceCreateInfoKHR.calloc(stack)
                    .type(KHRVulkanEnable2.XR_TYPE_VULKAN_DEVICE_CREATE_INFO_KHR)
                    .systemId(b.systemId)
                    .createFlags(0)
                    .pfnGetInstanceProcAddr(pfnGetInstanceProcAddr)
                    .vulkanPhysicalDevice(vkPhysicalDevice)
                    .vulkanCreateInfo(ci)
                    .vulkanAllocator(null)

                val pOut = stack.mallocPointer(1)
                val pRes = stack.mallocInt(1)
                val res = KHRVulkanEnable2.xrCreateVulkanDeviceKHR(b.xrInstance, xrCi, pOut, pRes)
                if (res != XR10.XR_SUCCESS) {
                    throw RuntimeException("xrCreateVulkanDeviceKHR failed: ${res} (vkResult=${pRes[0]})")
                }
                return VkDevice(pOut[0], vkPhysicalDevice, ci)
            }
        }

fun consumeOpenXRBootstrap(): OpenXRBootstrap?

Consume the bootstrap (ownership of xrInstance transfers to caller).

        fun consumeOpenXRBootstrap(): OpenXRBootstrap? {
            val b = xrBootstrap ?: return null
            xrBootstrap = null
            b.consumed = true
            return b
        }

fun peekOpenXRBootstrapPhys(): Long? = xrBootstrap?.xrPhys

Peek the XR-selected physical device if bootstrap already prepared.

fun cleanupOpenXRBootstrap()

        fun cleanupOpenXRBootstrap() {
            xrBootstrap?.let { XR10.xrDestroyInstance(it.xrInstance) }
            xrBootstrap = null
        }

fun hasOpenXRBootstrap(): Boolean = xrBootstrap != null

fun getOpenXRRuntimePhysicalDevice(vkInstance: VkInstance): Long?

Query the runtime-selected VkPhysicalDevice for this system (via XR_KHR_vulkan_enable2).

body — 60 lines, from line 473
        fun getOpenXRRuntimePhysicalDevice(vkInstance: VkInstance): Long? {
            if (!Options.enableVR) return null
            peekOpenXRBootstrapPhys()?.let { return it }
            MemoryStack.stackPush().use { stack ->
                val extNames = requiredOpenXRExtensions() ?: return null
                val apiLayers = enabledOpenXRApiLayers()
                val appInfo = XrApplicationInfo.calloc(stack)
                appInfo.applicationName(stack.UTF8("afield"))
                appInfo.applicationVersion(1)
                appInfo.engineName(stack.UTF8("afield"))
                appInfo.engineVersion(1)
                appInfo.apiVersion(XR10.XR_API_VERSION_1_0)

                val createInfo = XrInstanceCreateInfo.calloc(stack)
                    .type(XR10.XR_TYPE_INSTANCE_CREATE_INFO)
                    .applicationInfo(appInfo)
                    .enabledExtensionNames(pointerBuffer(stack, extNames))
                    .enabledApiLayerNames(pointerBuffer(stack, apiLayers))

                val pInstance = stack.mallocPointer(1)
                val createdRes = XR10.xrCreateInstance(createInfo, pInstance)
                if (createdRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrCreateInstance (phys query) returned ${createdRes}")
                    return null
                }

                val xrInstance = XrInstance(pInstance[0], createInfo)
                try {
                    val sysInfo = XrSystemGetInfo.calloc(stack)
                        .type(XR10.XR_TYPE_SYSTEM_GET_INFO)
                        .formFactor(XR10.XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY)
                    val pSys = stack.mallocLong(1)
                    val sysRes = XR10.xrGetSystem(xrInstance, sysInfo, pSys)
                    if (sysRes != XR10.XR_SUCCESS) {
                        lprint("error,openxr", "xrGetSystem (phys query) returned ${sysRes}")
                        return null
                    }
                    val systemId = pSys[0]

                    val physInfo = XrVulkanGraphicsDeviceGetInfoKHR.calloc(stack)
                        .type(KHRVulkanEnable2.XR_TYPE_VULKAN_GRAPHICS_DEVICE_GET_INFO_KHR)
                        .systemId(systemId)
                        .vulkanInstance(vkInstance)
                    val pPhys = stack.mallocPointer(1)
                    val physRes = KHRVulkanEnable2.xrGetVulkanGraphicsDevice2KHR(xrInstance, physInfo, pPhys)
                    if (physRes != XR10.XR_SUCCESS) {
                        lprint("error,openxr", "xrGetVulkanGraphicsDevice2KHR returned ${physRes}")
                        return null
                    }
                    return pPhys[0]
                } finally {
                    XR10.xrDestroyInstance(xrInstance)
                }
            }
        }

        private var xrCachedInstanceExts: List<String> = emptyList()
        private var xrCachedDeviceExts: List<String> = emptyList()
        private var xrInitialized = false
        private var xrBootstrap: OpenXRBootstrap? = null

var enabledOpenXRInstanceExtensions: Set<String>

The OpenXR instance extensions we actually enabled. The optional ones are only present when the runtime advertised them, so consumers that build on them (hand tracking, body tracking, eye tracking) check here rather than guessing.

body — 338 lines, from line 539
        var enabledOpenXRInstanceExtensions: Set<String> = emptySet()
            private set

        private fun pointerBuffer(stack: MemoryStack, names: List<String>): PointerBuffer? {
            if (names.isEmpty()) return null
            return stack.mallocPointer(names.size).apply {
                names.forEach { put(stack.UTF8(it)) }
                flip()
            }
        }

        private fun requiredOpenXRExtensions(): List<String>? {
            val supported = enumerateOpenXRInstanceExtensions()
            val missing = openXRVulkanExtensions.filter { it !in supported }
            if (missing.isNotEmpty()) {
                lprint("error,openxr", "missing required OpenXR extensions: $missing; supported=$supported")
                return null
            }
            val optional = listOf(
                EXTHandTracking.XR_EXT_HAND_TRACKING_EXTENSION_NAME,
                EXTHandInteraction.XR_EXT_HAND_INTERACTION_EXTENSION_NAME,
                EXTEyeGazeInteraction.XR_EXT_EYE_GAZE_INTERACTION_EXTENSION_NAME,
                afield.graphics.vulkan.targets.HtcEyeTracker.EXTENSION_NAME,
                // Monado vendor extension; the only route to WiVRn's body trackers.
                afield.graphics.vulkan.targets.MndxXDevSpace.EXTENSION_NAME,
            ).filter { it in supported }
            val enabled = (openXRVulkanExtensions + optional).distinct()
            enabledOpenXRInstanceExtensions = enabled.toSet()
            return enabled
        }

        private fun enabledOpenXRApiLayers(): List<String> {
            if (!Options.validateOpenXR) return emptyList()
            val supported = enumerateOpenXRApiLayers()
            val selected = openXRValidationLayerCandidates.firstOrNull { it in supported }
            if (selected == null) {
                lprintln(
                    "warning,openxr",
                    "OpenXR validation requested but no known validation layer was found; supported layers=$supported"
                )
                return emptyList()
            }
            lprintln("info,openxr", "OpenXR validation layer enabled: $selected")
            return listOf(selected)
        }

        private fun enumerateOpenXRInstanceExtensions(): Set<String> {
            val out = linkedSetOf<String>()
            MemoryStack.stackPush().use { stack ->
                val count = stack.callocInt(1)
                val countRes = XR10.xrEnumerateInstanceExtensionProperties(null as String?, count, null)
                if (countRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrEnumerateInstanceExtensionProperties(count) returned $countRes")
                    return emptySet()
                }
                val props = XrExtensionProperties.calloc(count[0], stack)
                for (i in 0 until props.capacity()) {
                    props[i].type(XR10.XR_TYPE_EXTENSION_PROPERTIES)
                }
                val propsRes = XR10.xrEnumerateInstanceExtensionProperties(null as String?, count, props)
                if (propsRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrEnumerateInstanceExtensionProperties returned $propsRes")
                    return emptySet()
                }
                repeat(props.capacity()) { i -> out += props[i].extensionNameString() }
            }
            return out
        }

        private fun enumerateOpenXRApiLayers(): Set<String> {
            val out = linkedSetOf<String>()
            MemoryStack.stackPush().use { stack ->
                val count = stack.callocInt(1)
                val countRes = XR10.xrEnumerateApiLayerProperties(count, null)
                if (countRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrEnumerateApiLayerProperties(count) returned $countRes")
                    return emptySet()
                }
                val props = XrApiLayerProperties.calloc(count[0], stack)
                for (i in 0 until props.capacity()) {
                    props[i].type(XR10.XR_TYPE_API_LAYER_PROPERTIES)
                }
                val propsRes = XR10.xrEnumerateApiLayerProperties(count, props)
                if (propsRes != XR10.XR_SUCCESS) {
                    lprint("error,openxr", "xrEnumerateApiLayerProperties returned $propsRes")
                    return emptySet()
                }
                repeat(props.capacity()) { i -> out += props[i].layerNameString() }
            }
            return out
        }

        private fun ensureOpenXRExtensions() {
            if (xrInitialized) return
            xrInitialized = true
            MemoryStack.stackPush().use { stack ->
                val extNames = requiredOpenXRExtensions()
                if (extNames == null) {
                    xrCachedInstanceExts = emptyList()
                    xrCachedDeviceExts = emptyList()
                    return
                }
                val apiLayers = enabledOpenXRApiLayers()
                // Build minimal OpenXR instance with Vulkan enable2 so we can query required Vulkan extensions
                val appInfo = XrApplicationInfo.calloc(stack)
                appInfo.applicationName(stack.UTF8("afield"))
                appInfo.applicationVersion(1)
                appInfo.engineName(stack.UTF8("afield"))
                appInfo.engineVersion(1)
                appInfo.apiVersion(XR10.XR_API_VERSION_1_0)

                val createInfo = XrInstanceCreateInfo.calloc(stack)
                    .type(XR10.XR_TYPE_INSTANCE_CREATE_INFO)
                    .applicationInfo(appInfo)
                    .enabledExtensionNames(pointerBuffer(stack, extNames))
                    .enabledApiLayerNames(pointerBuffer(stack, apiLayers))

                val pInstance = stack.mallocPointer(1)
                val createdError = XR10.xrCreateInstance(createInfo, pInstance)
                val created = createdError == XR10.XR_SUCCESS
                if (!created) {
                    lprint("error,openxr", "xrCreateInstance returned ${createdError}")
                    xrCachedInstanceExts = emptyList()
                    xrCachedDeviceExts = emptyList()
                    return
                }

                val xrInstance = XrInstance(pInstance[0], createInfo)
                try {
                    val sysInfo = XrSystemGetInfo.calloc(stack)
                        .type(XR10.XR_TYPE_SYSTEM_GET_INFO)
                        .formFactor(XR10.XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY)
                    val pSys = stack.mallocLong(1)
                    val sysRes = XR10.xrGetSystem(xrInstance, sysInfo, pSys)
                    if (sysRes != XR10.XR_SUCCESS) {
                        xrCachedInstanceExts = emptyList()
                        xrCachedDeviceExts = emptyList()
                        return
                    }
                    val systemId = pSys[0]

                    // Per spec: must be called before creating VkDevice for this system.
                    val gfxReq = XrGraphicsRequirementsVulkan2KHR.calloc(stack)
                        .type(KHRVulkanEnable.XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR)
                    val gfxReqRes = xrGetVulkanGraphicsRequirements2KHR(xrInstance, systemId, gfxReq)
                    check(gfxReqRes == XR10.XR_SUCCESS) {
                        "xrGetVulkanGraphicsRequirements2KHR failed: $gfxReqRes"
                    }

                    lprintln(
                        "info,openxr",
                        "XR gfx requirements: minApi=${VK10.VK_API_VERSION_MAJOR(gfxReq.minApiVersionSupported().toInt())}.${VK10.VK_API_VERSION_MINOR(gfxReq.minApiVersionSupported().toInt())} maxApi=${VK10.VK_API_VERSION_MAJOR(gfxReq.maxApiVersionSupported().toInt())}.${VK10.VK_API_VERSION_MINOR(gfxReq.maxApiVersionSupported().toInt())}"
                    )

                    xrCachedInstanceExts = queryExts(stack) { cap, buf ->
                        org.lwjgl.openxr.KHRVulkanEnable.xrGetVulkanInstanceExtensionsKHR(xrInstance, systemId, cap, buf)
                    }
                    xrCachedDeviceExts = queryExts(stack) { cap, buf ->
                        org.lwjgl.openxr.KHRVulkanEnable.xrGetVulkanDeviceExtensionsKHR(xrInstance, systemId, cap, buf)
                    }
                } finally {
                    XR10.xrDestroyInstance(xrInstance)
                }
            }
        }

        private fun queryExts(
            stack: MemoryStack,
            call: (IntBuffer, ByteBuffer?) -> Int
        ): List<String> {
            val size = stack.mallocInt(1)

            // Start with a small buffer; if XR reports size insufficient, reallocate using the reported size.
            var capacity = 256
            var buf = stack.malloc(capacity)
            size.put(0, capacity)

            var res = call(size, buf)
            if (res == XR10.XR_ERROR_SIZE_INSUFFICIENT) {
                capacity = size[0]
                if (capacity <= 0) return emptyList()
                buf = stack.malloc(capacity)
                size.put(0, capacity)
                res = call(size, buf)
            }

            if (res != XR10.XR_SUCCESS) {
                lprint("error,openxr", "xrGetVulkan*ExtensionsKHR returned ${res}")
                return emptyList()
            }

            val byteCount = size[0]
            if (byteCount <= 1) return emptyList()

            val s = MemoryUtil.memUTF8(buf, byteCount - 1)
            return s.split(' ').filter { it.isNotBlank() }
        }

        private fun createDebugCallBack(): VkDebugUtilsMessengerCreateInfoEXT {
            fun objectTypeName(t: Int) = when (t) {
                VK10.VK_OBJECT_TYPE_INSTANCE -> "Instance"
                VK10.VK_OBJECT_TYPE_DEVICE -> "Device"
                VK10.VK_OBJECT_TYPE_QUEUE -> "Queue"
                VK10.VK_OBJECT_TYPE_COMMAND_BUFFER -> "CmdBuf"
                VK10.VK_OBJECT_TYPE_IMAGE -> "Image"
                VK10.VK_OBJECT_TYPE_IMAGE_VIEW -> "ImageView"
                VK10.VK_OBJECT_TYPE_BUFFER -> "Buffer"
                VK10.VK_OBJECT_TYPE_BUFFER_VIEW -> "BufferView"
                VK10.VK_OBJECT_TYPE_SHADER_MODULE -> "ShaderModule"
                VK10.VK_OBJECT_TYPE_PIPELINE_LAYOUT -> "PipelineLayout"
                VK10.VK_OBJECT_TYPE_PIPELINE -> "Pipeline"
                VK10.VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT -> "DSL"
                VK10.VK_OBJECT_TYPE_DESCRIPTOR_SET -> "DS"
                else -> "Object($t)"
            }

            return VkDebugUtilsMessengerCreateInfoEXT
                .calloc()
                .sType(EXTDebugUtils.VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT)
                .messageSeverity(
                    EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT // optional: nice during bring-up
                )
                .messageType(
                    EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT
                )
                .pfnUserCallback callback@{ severity: Int, _: Int, pCallbackData: Long, _: Long ->
                    val cb = VkDebugUtilsMessengerCallbackDataEXT.create(pCallbackData)

                    val msg = cb.pMessageString() ?: ""
                    // SteamVR records internal commands against an image it names
                    // "BlankEyeBuffer" with inconsistent transfer/source layout tracking. This is
                    // a long-standing runtime validation defect which also reproduces in minimal
                    // OpenXR Vulkan applications. Keep validation enabled for Field objects, but
                    // suppress only this runtime-owned, object-specific flood.
                    val isSteamVrBlankEyeNoise =
                        OS == OSType.LINUX && Options.enableVR &&
                                msg.contains("BlankEyeBuffer") &&
                                msg.contains("VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL") &&
                                msg.contains("current layout")
                    if (isSteamVrBlankEyeNoise) {
                        if (reportedSteamVrBlankEyeValidationNoise.compareAndSet(false, true)) {
                            lprintln(
                                "info,openxr",
                                "Suppressing known SteamVR BlankEyeBuffer Vulkan validation noise"
                            )
                        }
                        return@callback VK10.VK_FALSE
                    }
                    val idName = cb.pMessageIdNameString() ?: ""
                    val isPrintf = idName.contains("DEBUG-PRINTF") ||
                            msg.contains("DEBUG-PRINTF") ||  // some layers put it only in the text
                            idName.contains("DebugPrintf", ignoreCase = true)


                    // Active label stacks (outer..inner)

                    val queueLabels: List<String> = buildList {
                        val buf = cb.pQueueLabels()
                        val n = cb.queueLabelCount()
                        for (i in 0 until n) add(buf?.get(i)?.pLabelNameString() ?: "")
                    }

                    val cmdLabels: List<String> = buildList {
                        val buf = cb.pCmdBufLabels()
                        val n = cb.cmdBufLabelCount()
                        for (i in 0 until n) add(buf?.get(i)?.pLabelNameString() ?: "")
                    }

// attached objects (if any)

                    // It’s handy to render as “outer > inner”
                    val labelTrail = (queueLabels + cmdLabels).filter { it.isNotEmpty() }.joinToString(" > ")

                    // Mention any named objects the layer attached to this message
                    val objectsStr: String = buildList {
                        val buf = cb.pObjects()
                        if (buf != null) {
                            val n = cb.objectCount()
                            for (i in 0 until n) {
                                val o = buf.get(i)
                                val name = o.pObjectNameString()
                                val handle = java.lang.Long.toUnsignedString(o.objectHandle())
                                add("${objectTypeName(o.objectType())}:${name ?: "0x$handle"}")
                            }
                        }
                    }.joinToString(", ")

                    val where = buildString {
                        if (labelTrail.isNotEmpty()) append(" | labels: $labelTrail")
                        if (objectsStr.isNotEmpty()) append(" | objects: $objectsStr")
                    }

                    // A Metal compile failure (macOS, through MoltenVK) says what happened in the translated
                    // source's terms; a name collision with Metal's standard library is said plainly, first.
                    val said = afield.graphics.shader.MetalShaderErrors.note(msg)?.let { "$it\n$msg" } ?: msg
                    // The loader reports, as a warning, each system layer it drops in favour of the
                    // SDK copy that Options.addMacSdkLayers put first. That is the intended outcome,
                    // seven times per instance; logged, at info, and never sent to a box.
                    val isLoaderDuplicateLayer = msg.contains("Removing layer") && msg.contains("because it is a duplicate of")
                    when {
                        isPrintf -> lprintln("debug,vulkan", "PRINTF$where: $said")
                        isLoaderDuplicateLayer -> lprintln("info,vulkan", "INFO$where: $said")
                        (severity and EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0 ->
                            lprintln("error,vulkan", "ERROR$where: $said")

                        (severity and EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0 ->
                            lprintln("warning,vulkan", "WARNING$where: $said")

                        else -> lprintln("info,vulkan", "INFO$where: $said")
                    }

                    // Only what a person must act on reaches a box. INFO and VERBOSE messages — the
                    // loader's layer-configuration dump among them — land on whichever box built a
                    // module last, as errors, so every relaunch of a window reported a failed run.
                    val forBox = isPrintf || (severity and (EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT or
                            EXTDebugUtils.VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)) != 0
                    if (!forBox || isLoaderDuplicateLayer || msg.contains(
                            "VK_ERROR_FEATURE_NOT_PRESENT: Metal does not support disabling primitive restart",
                            ignoreCase = true
                        )
                    ) {
                    } else {
                        globalAsyncDebugHandler?.invoke((if (isPrintf) "PRINTF" else "VK") + where + ": " + said)
                    }


                    VK10.VK_FALSE
                }
        }



    }

Tooling info dump (optional)

fun dumpToolingInfo(instance: VkInstance, phys: VkPhysicalDevice)

body — 61 lines, from line 880
    fun dumpToolingInfo(instance: VkInstance, phys: VkPhysicalDevice) {
        MemoryStack.stackPush().use { stack ->
            fun purposes(bits: Int): String {
                val out = ArrayList<String>(7)
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_VALIDATION_BIT_EXT) != 0) out += "validation"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_PROFILING_BIT_EXT) != 0) out += "profiling"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_TRACING_BIT_EXT) != 0) out += "tracing"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT) != 0) out += "adds_features"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT) != 0) out += "modifies_features"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT) != 0) out += "debug_reporting"
                if ((bits and EXTToolingInfo.VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT) != 0) out += "debug_markers"
                return if (out.isEmpty()) "none" else out.joinToString("|")
            }

            fun boundedUtf8(buf: ByteBuffer): String {
                val view = buf.duplicate()
                val start = view.position()
                val end = (start until view.limit()).firstOrNull { view.get(it).toInt() == 0 } ?: view.limit()
                view.limit(end)
                val bytes = view.slice()
                return StandardCharsets.UTF_8.newDecoder()
                    .onMalformedInput(CodingErrorAction.REPLACE)
                    .onUnmappableCharacter(CodingErrorAction.REPLACE)
                    .decode(bytes)
                    .toString()
            }

            if (instance.capabilities.vkGetPhysicalDeviceToolPropertiesEXT != 0L) {
                val capacity = 64
                val pCount = stack.mallocInt(1)
                pCount.put(0, capacity)
                // Allocate a little extra space without advertising it to the driver/layers.
                // This keeps a minor overrun by a broken tool from immediately corrupting
                // the surrounding stack frame while still preserving the Vulkan contract.
                val props = VkPhysicalDeviceToolPropertiesEXT.calloc(capacity + 4, stack)
                for (i in 0 until capacity) {
                    props[i]
                        .sType(EXTToolingInfo.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT)
                        .pNext(MemoryUtil.NULL)
                }
                val res = EXTToolingInfo.vkGetPhysicalDeviceToolPropertiesEXT(phys, pCount, props)
                if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
                    val written = pCount[0].coerceIn(0, capacity)
                    lprintln("info,vulkan", "== Tooling (physical device) ==")
                    if (res == VK_INCOMPLETE) {
                        lprintln("warning,vulkan", "Tooling query returned VK_INCOMPLETE; showing first $written tools")
                    }
                    for (i in 0 until written) {
                        val t = props[i]
                        lprintln("info,vulkan", " - ${boundedUtf8(t.name())} ${boundedUtf8(t.version())}")
                        lprintln("info,vulkan", "    layer='${boundedUtf8(t.layer())}'")
                        lprintln("info,vulkan", "    desc='${boundedUtf8(t.description())}'")
                        lprintln("info,vulkan", "    purposes=${purposes(t.purposes())}")
                    }
                } else {
                    lprintln("warning,vulkan", "Tooling query failed with VkResult $res")
                }
            }
        }
    }
}