Example #1
0
        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);
            }
        }
Example #2
0
        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();
        }
Example #3
0
        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();
        }
Example #4
0
        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();
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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");
        }
Example #8
0
        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);
            }
        }
Example #9
0
        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}");
            }
        }
Example #10
0
        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");
        }