private unsafe void CreateInstance(IVkSurface vkSurface, string[] requestedExtensions, string[]?validationLayers, out Instance instance) { nint applicationName = Info.ApplicationName.Marshal(); nint engineName = Info.EngineName.Marshal(); ApplicationInfo applicationInfo = new ApplicationInfo { SType = StructureType.ApplicationInfo, PApplicationName = (byte *)applicationName, ApplicationVersion = Info.ApplicationVersion, PEngineName = (byte *)engineName, EngineVersion = Info.EngineVersion, ApiVersion = Info.APIVersion }; string[] requiredExtensions = VKAPI.GetRequiredExtensions(vkSurface, requestedExtensions); nint requiredExtensionsPointer = SilkMarshal.StringArrayToPtr(requiredExtensions); nint enabledLayerNames = 0x0; int enabledLayerCount = 0; InstanceCreateInfo createInfo = new InstanceCreateInfo { SType = StructureType.InstanceCreateInfo, PApplicationInfo = &applicationInfo, PpEnabledExtensionNames = (byte **)requiredExtensionsPointer, EnabledExtensionCount = (uint)requiredExtensions.Length, PpEnabledLayerNames = (byte **)null !, EnabledLayerCount = 0, PNext = (void *)null ! }; if (validationLayers is not null) { VKAPI.VerifyValidationLayerSupport(VK, validationLayers); enabledLayerNames = SilkMarshal.StringArrayToPtr(validationLayers); enabledLayerCount = validationLayers.Length; createInfo.PpEnabledLayerNames = (byte **)enabledLayerNames; createInfo.EnabledLayerCount = (uint)enabledLayerCount; } Log.Information(string.Format(FormatHelper.DEFAULT_LOGGING, nameof(VulkanInstance), "allocating instance.")); Result result = VK.CreateInstance(&createInfo, (AllocationCallbacks *)null !, out instance); if (result is not Result.Success) { throw new VulkanException(result, "Failed to create Vulkan instance."); } SilkMarshal.FreeString(applicationName); SilkMarshal.FreeString(engineName); SilkMarshal.FreeString(requiredExtensionsPointer); if (enabledLayerNames is not 0x0 && enabledLayerCount is not 0) { SilkMarshal.FreeString(enabledLayerNames); } }
public static unsafe void RunApp(IReadOnlyList <string> args, IntPtr callback) { BeginRun(); var argsPtr = SilkMarshal.StringArrayToPtr(args); CoreRunApp(args.Count, (byte **)argsPtr, callback); SilkMarshal.Free(argsPtr); EndRun(); }
public static unsafe void RunApp(IReadOnlyList <string> args, Action <string[]> callback) { BeginRun(); var argsPtr = SilkMarshal.StringArrayToPtr(args); CurrentMain = (numArgs, inArgsPtr) => callback(SilkMarshal.PtrToStringArray((IntPtr)inArgsPtr, numArgs)); CoreRunApp(args.Count, (byte **)argsPtr, GetCallMainPtr()); CurrentMain = null; SilkMarshal.Free(argsPtr); EndRun(); }
public static unsafe void RunApp(IReadOnlyList <string> args, MainFunction callback) { BeginRun(); var argsPtr = SilkMarshal.StringArrayToPtr(args); CurrentMain = callback; CoreRunApp(args.Count, (byte **)argsPtr, GetCallMainPtr()); CurrentMain = null; SilkMarshal.Free(argsPtr); EndRun(); }
public static unsafe DeviceCreateInfo DeviceCreateInfo(string[] deviceExtensions, params DeviceQueueCreateInfo[] queues) { DeviceCreateInfo deviceCreateInfo = new() { SType = StructureType.DeviceCreateInfo, EnabledLayerCount = 0, PpEnabledLayerNames = null, EnabledExtensionCount = (uint)deviceExtensions.Length, PpEnabledExtensionNames = (byte **)SilkMarshal.StringArrayToPtr(deviceExtensions), QueueCreateInfoCount = (uint)queues.Length }; fixed(DeviceQueueCreateInfo *ptr = &queues[0]) { deviceCreateInfo.PQueueCreateInfos = ptr; } return(deviceCreateInfo); }
public static unsafe Instance CreateInstance(string[] instanceLayers, string[] instanceExtensions, IVkSurface windowSurface) { ApplicationInfo appInfo = new() { SType = StructureType.ApplicationInfo, PApplicationName = (byte *)SilkMarshal.StringToPtr("SilkyNvg-Vulkan-Example"), ApplicationVersion = Vk.MakeVersion(1, 0, 0), PEngineName = (byte *)SilkMarshal.StringToPtr("SilkyNvg (Renderer: Vulkan)"), EngineVersion = Vk.MakeVersion(1, 0, 0), ApiVersion = Vk.Version12 }; byte **windowExtensionsPtr = windowSurface.GetRequiredExtensions(out uint windowExtensionCount); byte **instanceExtensionsPtr = (byte **)SilkMarshal.StringArrayToPtr(instanceExtensions); byte **extensions = stackalloc byte *[(int)windowExtensionCount + instanceExtensions.Length]; int i = 0; for (; i < windowExtensionCount; i++) { extensions[i] = windowExtensionsPtr[i]; } for (; i < windowExtensionCount + instanceExtensions.Length; i++) { extensions[i] = instanceExtensionsPtr[i]; } CheckInstanceExtensionsPresent(extensions, (int)windowExtensionCount + instanceExtensions.Length); CheckInstanceLayersPresent(instanceLayers); byte **layers = (byte **)SilkMarshal.StringArrayToPtr(instanceLayers); InstanceCreateInfo instanceCreateInfo = VkInit.InstanceCreateInfo(appInfo, layers, (uint)instanceLayers.Length, extensions, windowExtensionCount); AssertVulkan(Vk.CreateInstance(instanceCreateInfo, null, out Instance instance)); return(instance); }
private void InitializeVulkan(string applicationName, uint applicationVersion) { Console.WriteLine("Initializing Vulkan"); #if VALIDITION DebugUtilsMessengerCreateInfoEXT GetDebugMessenger(void *pNext) { return(new DebugUtilsMessengerCreateInfoEXT( messageSeverity: DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt | DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt, messageType: DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt, pfnUserCallback: new PfnDebugUtilsMessengerCallbackEXT(DebugCallback), pNext: pNext)); } #endif _vk = Vk.GetApi(); const uint engineVersion = 1; const string engineName = "Videre"; var instanceLayers = new List <string>(); var instanceExtensions = new List <string>(); var pApplicationName = SilkMarshal.StringToPtr(applicationName); var pEngineName = SilkMarshal.StringToPtr(engineName); var applicationInfo = new ApplicationInfo(pApplicationName: (byte *)pApplicationName, applicationVersion: applicationVersion, pEngineName: (byte *)pEngineName, engineVersion: engineVersion, apiVersion: new Version32(1, 1, 0)); Version32 apiVersion = default; _vk.EnumerateInstanceVersion((uint *)&apiVersion); Console.WriteLine($"Instance Version: {apiVersion.Major}.{apiVersion.Minor}.{apiVersion.Patch}"); void *instancepNext = default; // instanceExtensions.Add(KhrSurface.ExtensionName); instanceExtensions.AddRange(SilkMarshal.PtrToStringArray((nint)View.VkSurface.GetRequiredExtensions(out var requiredExtensionsCount), (int)requiredExtensionsCount)); instanceExtensions.Add(ExtDebugUtils.ExtensionName); Console.WriteLine($"Creating Instance with {instanceExtensions.Count} extensions"); VerifyInstanceExtensionsAvailable(_vk, instanceExtensions); var ppEnabledLayers = instanceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceLayers) : null; var ppEnabledExtensions = instanceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(instanceExtensions) : null; _vk.CreateInstance( new InstanceCreateInfo(pApplicationInfo: &applicationInfo, enabledLayerCount: (uint)instanceLayers.Count, ppEnabledLayerNames: ppEnabledLayers, enabledExtensionCount: (uint)instanceExtensions.Count, ppEnabledExtensionNames: ppEnabledExtensions, pNext: instancepNext), _allocationCallbacks.AllocationCallbacks, out _instance) .ThrowCode(); SilkMarshal.Free((nint)ppEnabledLayers); SilkMarshal.Free((nint)ppEnabledExtensions); _vk.CurrentInstance = _instance; if (!_vk.TryGetInstanceExtension(_instance, out _khrSurface)) { Console.WriteLine($"Could not load {KhrSurface.ExtensionName}"); } _vk.TryGetInstanceExtension(_instance, out _debugUtils); Console.WriteLine("Creating Surface"); _surface = View.VkSurface.Create(_instance.ToHandle(), (AllocationCallbacks *)null).ToSurface(); uint deviceCount = 0; _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, null).ThrowCode(); var devices = (PhysicalDevice *)SilkMarshal.Allocate((int)(deviceCount * sizeof(PhysicalDevice))); _vk.EnumeratePhysicalDevices(_instance, ref deviceCount, devices).ThrowCode(); Console.WriteLine($"Found {deviceCount} devices"); Console.WriteLine("Creating Device"); // TODO: actually somehow reasonably find the best device. for (int i = 0; i < deviceCount; i++) { var physicalDevice = devices[i]; _physicalDeviceFeatures = _vk.GetPhysicalDeviceFeature(physicalDevice); uint presentModeCount = 0; _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, null).ThrowCode(); if (presentModeCount <= 0) { continue; } var presentModes = (PresentModeKHR *)SilkMarshal.Allocate((int)(presentModeCount * sizeof(PresentModeKHR))); _khrSurface.GetPhysicalDeviceSurfacePresentModes(physicalDevice, _surface, ref presentModeCount, presentModes).ThrowCode(); _presentMode = PresentModeKHR.PresentModeFifoKhr; View.FramesPerSecond = -1; for (int j = 0; j < presentModeCount; j++) { if (presentModes[j] == PresentModeKHR.PresentModeMailboxKhr) { _presentMode = PresentModeKHR.PresentModeMailboxKhr; View.FramesPerSecond = -1; break; } } SilkMarshal.Free((nint)presentModes); uint surfaceFormatCount = 0; _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, null).ThrowCode(); var surfaceFormats = (SurfaceFormatKHR *)SilkMarshal.Allocate((int)(surfaceFormatCount * sizeof(SurfaceFormatKHR))); _khrSurface.GetPhysicalDeviceSurfaceFormats(physicalDevice, _surface, ref surfaceFormatCount, surfaceFormats).ThrowCode(); int max = int.MinValue; SurfaceFormatKHR maxFormat = surfaceFormats[0]; for (int j = 0; j < surfaceFormatCount; j++) { var score = FormatRater.Rate(surfaceFormats[j].Format) + ColorSpaceRater.Rate(surfaceFormats[j].ColorSpace); if (score > max) { max = score; maxFormat = surfaceFormats[j]; } } SilkMarshal.Free((nint)surfaceFormats); _swapchainFormat = maxFormat.Format; _swapchainColorSpace = maxFormat.ColorSpace; Console.WriteLine($"Chose Swapchain Properties: {Enum.GetName(typeof(PresentModeKHR), _presentMode)} {Enum.GetName(typeof(Format), _swapchainFormat)} {Enum.GetName(typeof(ColorSpaceKHR), _swapchainColorSpace)}"); _khrSurface.GetPhysicalDeviceSurfaceCapabilities(physicalDevice, _surface, out var surfaceCapabilities).ThrowCode(); uint queueFamilyPropertyCount = 0; _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, null); var deviceQueueFamilyProperties = (QueueFamilyProperties *)SilkMarshal.Allocate((int)(queueFamilyPropertyCount * sizeof(QueueFamilyProperties))); _vk.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyPropertyCount, deviceQueueFamilyProperties); var queueCreateInfoList = new List <DeviceQueueCreateInfo>(); var deviceExtensions = new List <string>(); var deviceLayers = new List <string>(); for (int j = 0; j < queueFamilyPropertyCount; j++) { var queueCount = deviceQueueFamilyProperties[j].QueueCount; float *pQueuePriorities = stackalloc float[(int)queueCount]; // queue count should generally be 1 for (int k = 0; k < queueCount; k++) { pQueuePriorities[k] = 1.0f; } queueCreateInfoList.Add(new DeviceQueueCreateInfo(queueFamilyIndex: (uint)j, queueCount: queueCount, pQueuePriorities: pQueuePriorities)); } deviceExtensions.Add(KhrSwapchain.ExtensionName); // deviceExtensions.Add(KhrSynchronization2.ExtensionName); // deviceExtensions.Add(ExtBufferDeviceAddress.ExtensionName); var features = new PhysicalDeviceFeatures(); features.ShaderInt64 = true; void *devicePNext = null; // var physicalDeviceDescriptorIndexingFeaturesExt = new PhysicalDeviceDescriptorIndexingFeaturesEXT( // descriptorBindingSampledImageUpdateAfterBind: true, // descriptorBindingStorageBufferUpdateAfterBind: true, // descriptorBindingStorageImageUpdateAfterBind: true, // descriptorBindingUniformBufferUpdateAfterBind: true, // descriptorBindingStorageTexelBufferUpdateAfterBind: true, // descriptorBindingUniformTexelBufferUpdateAfterBind: true, // descriptorBindingUpdateUnusedWhilePending: true, // runtimeDescriptorArray: true, // pNext: devicePNext); // devicePNext = &physicalDeviceDescriptorIndexingFeaturesExt; // var physicalDeviceBufferDeviceAddressFeatures = new PhysicalDeviceBufferDeviceAddressFeatures(bufferDeviceAddress: true, #if DEBUG bufferDeviceAddressCaptureReplay: true, #endif pNext: devicePNext); devicePNext = &physicalDeviceBufferDeviceAddressFeatures; // var version12 = new PhysicalDeviceVulkan12Features(bufferDeviceAddress: true, // #if DEBUG // bufferDeviceAddressCaptureReplay: true, // #endif // descriptorBindingSampledImageUpdateAfterBind: true, // descriptorBindingStorageBufferUpdateAfterBind: true, // descriptorBindingStorageImageUpdateAfterBind: true, // descriptorBindingUniformBufferUpdateAfterBind: true, // descriptorBindingStorageTexelBufferUpdateAfterBind: true, // descriptorBindingUniformTexelBufferUpdateAfterBind: true, // descriptorBindingUpdateUnusedWhilePending: true, // runtimeDescriptorArray: true, // pNext: devicePNext); // devicePNext = &version12; var queueCreateInfos = queueCreateInfoList.Distinct().ToArray(); queueCreateInfoList = null; VerifyDeviceExtensionsAvailable(_vk, devices[i], deviceExtensions, ref deviceLayers); _physicalDevice = devices[i]; Console.WriteLine("Creating Logical Device"); var ppDeviceExtensions = deviceExtensions.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceExtensions) : null; var ppDeviceLayers = deviceLayers.Count > 0 ? (byte **)SilkMarshal.StringArrayToPtr(deviceLayers) : null; fixed(DeviceQueueCreateInfo *pQueueCreateInfos = queueCreateInfos) _vk.CreateDevice(physicalDevice, new DeviceCreateInfo(queueCreateInfoCount: (uint)queueCreateInfos.Length, pQueueCreateInfos: pQueueCreateInfos, enabledExtensionCount: (uint)deviceExtensions.Count, enabledLayerCount: (uint)deviceLayers.Count, ppEnabledExtensionNames: ppDeviceExtensions, ppEnabledLayerNames: ppDeviceLayers, pEnabledFeatures: &features, pNext: devicePNext), null, out _logicalDevice) .ThrowCode(); _vk.CurrentDevice = _logicalDevice; if (!_vk.TryGetDeviceExtension(_instance, _logicalDevice, out _khrSwapchain)) { Console.WriteLine($"Could not load {KhrSwapchain.ExtensionName}!"); } _queueManager = new(_vk, _khrSurface, _instance, _physicalDevice, _logicalDevice, _surface, new Span <QueueFamilyProperties>(deviceQueueFamilyProperties, (int)queueFamilyPropertyCount)); Console.WriteLine($"{_queueManager.QueueCount} queues found"); SilkMarshal.Free((nint)ppDeviceExtensions); SilkMarshal.Free((nint)ppDeviceLayers); SilkMarshal.Free((nint)deviceQueueFamilyProperties); break; } SilkMarshal.Free((nint)devices); Console.WriteLine("Initialized Vulkan"); }
internal unsafe VulkanLogicalDevice(Vk vk, VulkanContext context, string[] extensions, string[]?validationLayers) : base(vk) { _Context = context; SwapchainExtension = GetDeviceExtension <SwapchainExtension>(); float queuePriority = 1f; QueueFamilyIndices queueFamilyIndices = _Context.PhysicalDevice.GetQueueFamilies(); uint queueFamiliesCount = queueFamilyIndices.GetLength; DeviceQueueCreateInfo *deviceQueueCreateInfos = stackalloc DeviceQueueCreateInfo[2]; for (int i = 0; i < queueFamiliesCount; i++) { Debug.Assert(queueFamilyIndices[i] != null); deviceQueueCreateInfos[i] = new DeviceQueueCreateInfo { SType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = queueFamilyIndices[i] !.Value, QueueCount = 1, PQueuePriorities = &queuePriority }; } nint extensionsPointer = SilkMarshal.StringArrayToPtr(extensions); nint?validationLayersPointer = null; DeviceCreateInfo deviceCreateInfo = new DeviceCreateInfo { SType = StructureType.DeviceCreateInfo, EnabledExtensionCount = (uint)extensions.Length, PpEnabledExtensionNames = (byte **)extensionsPointer, QueueCreateInfoCount = queueFamiliesCount, PQueueCreateInfos = deviceQueueCreateInfos, PEnabledFeatures = (PhysicalDeviceFeatures *)null !, EnabledLayerCount = 0, PpEnabledLayerNames = null }; if (validationLayers is not null) { validationLayersPointer = SilkMarshal.StringArrayToPtr(validationLayers); deviceCreateInfo.EnabledLayerCount = (uint)validationLayers.Length; deviceCreateInfo.PpEnabledLayerNames = (byte **)validationLayersPointer.Value; } Result result = VK.CreateDevice(_Context.PhysicalDevice, &deviceCreateInfo, (AllocationCallbacks *)null !, out _LogicalDevice); if (result is not Result.Success) { throw new VulkanException(result, "Failed to create logical device."); } VK.GetDeviceQueue(this, queueFamilyIndices.GraphicsFamily !.Value, 0, out _GraphicsQueue); VK.GetDeviceQueue(this, queueFamilyIndices.PresentationFamily !.Value, 0, out _PresentationQueue); SilkMarshal.Free(extensionsPointer); if (validationLayersPointer is not null) { SilkMarshal.Free(validationLayersPointer.Value); } }
public unsafe Instance(Api api, Window window, uint vulkanVersion) { (_api, _window) = (api, window); // Check the minimum version. CheckVulkanMinimumVersion(vulkanVersion); // Get the list of required extensions. List <string> extensions = new List <string>(); extensions.AddRange(window.GetRequiredInstanceExtensions()); // Check the validation layers and add them to the list of required extensions. if (api.DebugLoggingEnabled == false) { _validationLayers.Clear(); } CheckVulkanValidationLayerSupport(_validationLayers); if (_validationLayers.Count > 0) { extensions.Add(ExtDebugUtils.ExtensionName); } // Create the Vulkan instance. var appInfo = new ApplicationInfo { SType = StructureType.ApplicationInfo, PApplicationName = (byte *)Marshal.StringToHGlobalAnsi(nameof(RayTracingInDotNet)), ApplicationVersion = new Version32(1, 0, 0), PEngineName = (byte *)Marshal.StringToHGlobalAnsi($"{nameof(RayTracingInDotNet)} engine"), EngineVersion = new Version32(1, 0, 0), ApiVersion = vulkanVersion }; var createInfo = new InstanceCreateInfo { SType = StructureType.InstanceCreateInfo, PApplicationInfo = &appInfo, EnabledExtensionCount = (uint)extensions.Count, PpEnabledExtensionNames = (byte **)SilkMarshal.StringArrayToPtr(extensions.ToArray()), EnabledLayerCount = (uint)_validationLayers.Count, PpEnabledLayerNames = (byte **)SilkMarshal.StringArrayToPtr(_validationLayers.ToArray()) }; #if DEBUG // For using debugPrintfEXT in shaders var enabled = stackalloc ValidationFeatureEnableEXT[] { ValidationFeatureEnableEXT.ValidationFeatureEnableDebugPrintfExt }; var features = new ValidationFeaturesEXT { SType = StructureType.ValidationFeaturesExt, DisabledValidationFeatureCount = 0, EnabledValidationFeatureCount = 1, PDisabledValidationFeatures = null, PEnabledValidationFeatures = enabled, PNext = createInfo.PNext }; createInfo.PNext = (void *)Unsafe.AsPointer(ref features); #endif fixed(VkInstance *instance = &_vkInstance) { Util.Verify(_api.Vk.CreateInstance(&createInfo, null, instance), $"{nameof(VulkanRenderer)}: Failed to create Vulkan instance"); } _api.Instance = this; Marshal.FreeHGlobal((nint)appInfo.PApplicationName); Marshal.FreeHGlobal((nint)appInfo.PEngineName); SilkMarshal.Free((nint)createInfo.PpEnabledExtensionNames); SilkMarshal.Free((nint)createInfo.PpEnabledLayerNames); GetVulkanPhysicalDevices(); GetVulkanLayers(); GetVulkanExtensions(); foreach (var layer in _validationLayers) { _api.Logger.Debug($"{nameof(Instance)}: Validation Layer: {layer}"); } foreach (var extension in _extensions) { _api.Logger.Debug($"{nameof(Instance)}: Extension: {extension}"); } }
private unsafe void Prepare() { // Create our API object for OpenXR. Xr = XR.GetApi(); Extensions.Clear(); //Extensions.Add("XR_KHR_vulkan_enable2"); Extensions.Add("XR_KHR_vulkan_enable"); Extensions.Add("XR_EXT_hp_mixed_reality_controller"); Extensions.Add("XR_HTC_vive_cosmos_controller_interaction"); Extensions.Add("XR_MSFT_hand_interaction"); Extensions.Add("XR_EXT_samsung_odyssey_controller"); uint propCount = 0; Xr.EnumerateInstanceExtensionProperties((byte *)null, 0, &propCount, null); ExtensionProperties[] props = new ExtensionProperties[propCount]; for (int i = 0; i < props.Length; i++) { props[i].Type = StructureType.TypeExtensionProperties; fixed(ExtensionProperties *pptr = &props[0]) Xr.EnumerateInstanceExtensionProperties((byte *)null, propCount, ref propCount, pptr); List <string> AvailableExtensions = new List <string>(); for (int i = 0; i < props.Length; i++) { fixed(void *nptr = props[i].ExtensionName) AvailableExtensions.Add(Marshal.PtrToStringAnsi(new System.IntPtr(nptr))); } for (int i = 0; i < Extensions.Count; i++) { if (AvailableExtensions.Contains(Extensions[i]) == false) { Extensions.RemoveAt(i); i--; } } InstanceCreateInfo instanceCreateInfo; var appInfo = new ApplicationInfo() { ApiVersion = new Version64(1, 0, 9) }; // We've got to marshal our strings and put them into global, immovable memory. To do that, we use // SilkMarshal. Span <byte> appName = new Span <byte>(appInfo.ApplicationName, 128); Span <byte> engName = new Span <byte>(appInfo.EngineName, 128); SilkMarshal.StringIntoSpan(System.AppDomain.CurrentDomain.FriendlyName, appName); SilkMarshal.StringIntoSpan("FocusEngine", engName); var requestedExtensions = SilkMarshal.StringArrayToPtr(Extensions); instanceCreateInfo = new InstanceCreateInfo ( applicationInfo: appInfo, enabledExtensionCount: (uint)Extensions.Count, enabledExtensionNames: (byte **)requestedExtensions ); // Now we're ready to make our instance! CheckResult(Xr.CreateInstance(in instanceCreateInfo, ref Instance), "CreateInstance"); // For our benefit, let's log some information about the instance we've just created. // skip this, as it crashes on Oculus runtime and is not needed /*InstanceProperties properties = new(); * CheckResult(Xr.GetInstanceProperties(Instance, ref properties), "GetInstanceProperties"); * * var runtimeName = SilkMarshal.PtrToString((nint)properties.RuntimeName); * var runtimeVersion = ((Version)(Version64)properties.RuntimeVersion).ToString(3); * * Console.WriteLine($"[INFO] Application: Using OpenXR Runtime \"{runtimeName}\" v{runtimeVersion}");*/ // We're creating a head-mounted-display (HMD, i.e. a VR headset) example, so we ask for a runtime which // supports that form factor. The response we get is a ulong that is the System ID. var getInfo = new SystemGetInfo(formFactor: FormFactor.HeadMountedDisplay); CheckResult(Xr.GetSystem(Instance, in getInfo, ref system_id), "GetSystem"); }