public unsafe GraphicsAdapterFactoryInstance(bool enableValidation) { var applicationInfo = new VkApplicationInfo { sType = VkStructureType.ApplicationInfo, apiVersion = new VkVersion(1, 0, 0), pEngineName = (byte *)Marshal.StringToHGlobalAnsi("Stride"), //engineVersion = new VkVersion() }; var validationLayerNames = new[] { "VK_LAYER_KHRONOS_validation", }; IntPtr[] enabledLayerNames = new IntPtr[0]; if (enableValidation) { var layers = vkEnumerateInstanceLayerProperties(); var availableLayerNames = new HashSet <string>(); for (int index = 0; index < layers.Length; index++) { var properties = layers[index]; var namePointer = properties.layerName; var name = Marshal.PtrToStringAnsi((IntPtr)namePointer); availableLayerNames.Add(name); } enabledLayerNames = validationLayerNames .Where(x => availableLayerNames.Contains(x)) .Select(Marshal.StringToHGlobalAnsi).ToArray(); // Check if validation was really available enableValidation = enabledLayerNames.Length > 0; } var extensionProperties = vkEnumerateInstanceExtensionProperties(); var availableExtensionNames = new List <string>(); var desiredExtensionNames = new List <string>(); for (int index = 0; index < extensionProperties.Length; index++) { var extensionProperty = extensionProperties[index]; var name = Marshal.PtrToStringAnsi((IntPtr)extensionProperty.extensionName); availableExtensionNames.Add(name); } desiredExtensionNames.Add(KHRSurfaceExtensionName); if (!availableExtensionNames.Contains(KHRSurfaceExtensionName)) { throw new InvalidOperationException($"Required extension {KHRSurfaceExtensionName} is not available"); } if (Platform.Type == PlatformType.Windows) { desiredExtensionNames.Add(KHRWin32SurfaceExtensionName); if (!availableExtensionNames.Contains(KHRWin32SurfaceExtensionName)) { throw new InvalidOperationException($"Required extension {KHRWin32SurfaceExtensionName} is not available"); } } else if (Platform.Type == PlatformType.Android) { desiredExtensionNames.Add(KHRAndroidSurfaceExtensionName); if (!availableExtensionNames.Contains(KHRAndroidSurfaceExtensionName)) { throw new InvalidOperationException($"Required extension {KHRAndroidSurfaceExtensionName} is not available"); } } else if (Platform.Type == PlatformType.Linux) { if (availableExtensionNames.Contains("VK_KHR_xlib_surface")) { desiredExtensionNames.Add("VK_KHR_xlib_surface"); HasXlibSurfaceSupport = true; } else if (availableExtensionNames.Contains("VK_KHR_xcb_surface")) { desiredExtensionNames.Add("VK_KHR_xcb_surface"); } else { throw new InvalidOperationException("None of the supported surface extensions VK_KHR_xcb_surface or VK_KHR_xlib_surface is available"); } } bool enableDebugReport = enableValidation && availableExtensionNames.Contains(EXTDebugUtilsExtensionName); if (enableDebugReport) { desiredExtensionNames.Add(EXTDebugUtilsExtensionName); } var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray(); try { fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0]) { var instanceCreateInfo = new VkInstanceCreateInfo { sType = VkStructureType.InstanceCreateInfo, pApplicationInfo = &applicationInfo, enabledLayerCount = enabledLayerNames != null ? (uint)enabledLayerNames.Length : 0, ppEnabledLayerNames = enabledLayerNames?.Length > 0 ? (byte **)Core.Interop.Fixed(enabledLayerNames) : null, enabledExtensionCount = (uint)enabledExtensionNames.Length, ppEnabledExtensionNames = (byte **)enabledExtensionNamesPointer, }; vkCreateInstance(&instanceCreateInfo, null, out NativeInstance); vkLoadInstance(NativeInstance); } // Check if validation layer was available (otherwise detected count is 0) if (enableValidation) { debugReport = DebugReport; var createInfo = new VkDebugUtilsMessengerCreateInfoEXT { sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT, messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning, messageType = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance, pfnUserCallback = Marshal.GetFunctionPointerForDelegate(debugReport) }; vkCreateDebugUtilsMessengerEXT(NativeInstance, &createInfo, null, out debugReportCallback).CheckResult(); } } finally { foreach (var enabledExtensionName in enabledExtensionNames) { Marshal.FreeHGlobal(enabledExtensionName); } foreach (var enabledLayerName in enabledLayerNames) { Marshal.FreeHGlobal(enabledLayerName); } Marshal.FreeHGlobal((IntPtr)applicationInfo.pEngineName); } }
public GraphicsDevice(string applicationName, bool enableValidation, Window window) { VkString name = applicationName; var appInfo = new VkApplicationInfo { sType = VkStructureType.ApplicationInfo, pApplicationName = name, applicationVersion = new VkVersion(1, 0, 0), pEngineName = s_EngineName, engineVersion = new VkVersion(1, 0, 0), apiVersion = vkEnumerateInstanceVersion() }; var instanceExtensions = new List <string> { KHRSurfaceExtensionName }; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { instanceExtensions.Add(KHRWin32SurfaceExtensionName); } var instanceLayers = new List <string>(); if (enableValidation) { FindValidationLayers(instanceLayers); } if (instanceLayers.Count > 0) { instanceExtensions.Add(EXTDebugUtilsExtensionName); } using var vkInstanceExtensions = new VkStringArray(instanceExtensions); var instanceCreateInfo = new VkInstanceCreateInfo { sType = VkStructureType.InstanceCreateInfo, pApplicationInfo = &appInfo, enabledExtensionCount = vkInstanceExtensions.Length, ppEnabledExtensionNames = vkInstanceExtensions }; using var vkLayerNames = new VkStringArray(instanceLayers); if (instanceLayers.Count > 0) { instanceCreateInfo.enabledLayerCount = vkLayerNames.Length; instanceCreateInfo.ppEnabledLayerNames = vkLayerNames; } var debugUtilsCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT { sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT }; if (instanceLayers.Count > 0) { _debugMessengerCallbackFunc = DebugMessengerCallback; debugUtilsCreateInfo.messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning; debugUtilsCreateInfo.messageType = VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance; debugUtilsCreateInfo.pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc); instanceCreateInfo.pNext = &debugUtilsCreateInfo; } VkResult result = vkCreateInstance(&instanceCreateInfo, null, out VkInstance); if (result != VkResult.Success) { throw new InvalidOperationException($"Failed to create vulkan instance: {result}"); } vkLoadInstance(VkInstance); if (instanceLayers.Count > 0) { vkCreateDebugUtilsMessengerEXT(VkInstance, &debugUtilsCreateInfo, null, out _debugMessenger).CheckResult(); } Log.Info($"Created VkInstance with version: {appInfo.apiVersion.Major}.{appInfo.apiVersion.Minor}.{appInfo.apiVersion.Patch}"); if (instanceLayers.Count > 0) { foreach (var layer in instanceLayers) { Log.Info($"Instance layer '{layer}'"); } } foreach (var extension in instanceExtensions) { Log.Info($"Instance extension '{extension}'"); } _surface = CreateSurface(window); // Find physical device, setup queue's and create device. var physicalDevices = vkEnumeratePhysicalDevices(VkInstance); foreach (var physicalDevice in physicalDevices) { vkGetPhysicalDeviceProperties(physicalDevice, out var properties); var deviceName = properties.GetDeviceName(); } PhysicalDevice = physicalDevices[0]; var queueFamilies = FindQueueFamilies(PhysicalDevice, _surface); var priority = 1.0f; var queueCreateInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = queueFamilies.graphicsFamily, queueCount = 1, pQueuePriorities = &priority }; List <string> deviceExtensions = new List <string> { KHRSwapchainExtensionName }; var deviceCreateInfo = new VkDeviceCreateInfo { sType = VkStructureType.DeviceCreateInfo, pQueueCreateInfos = &queueCreateInfo, queueCreateInfoCount = 1, pEnabledFeatures = null, }; using var deviceExtensionNames = new VkStringArray(deviceExtensions); deviceCreateInfo.enabledExtensionCount = deviceExtensionNames.Length; deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames; result = vkCreateDevice(PhysicalDevice, &deviceCreateInfo, null, out VkDevice); if (result != VkResult.Success) { throw new Exception($"Failed to create Vulkan Logical Device, {result}"); } vkGetDeviceQueue(VkDevice, queueFamilies.graphicsFamily, 0, out GraphicsQueue); vkGetDeviceQueue(VkDevice, queueFamilies.presentFamily, 0, out PresentQueue); // Create swap chain Swapchain = new Swapchain(this, window); _perFrame = new PerFrame[Swapchain.ImageCount]; for (var i = 0; i < _perFrame.Length; i++) { VkFenceCreateInfo fenceCreateInfo = new VkFenceCreateInfo(VkFenceCreateFlags.Signaled); vkCreateFence(VkDevice, &fenceCreateInfo, null, out _perFrame[i].QueueSubmitFence).CheckResult(); VkCommandPoolCreateInfo poolCreateInfo = new VkCommandPoolCreateInfo { sType = VkStructureType.CommandPoolCreateInfo, flags = VkCommandPoolCreateFlags.Transient, queueFamilyIndex = queueFamilies.graphicsFamily, }; vkCreateCommandPool(VkDevice, &poolCreateInfo, null, out _perFrame[i].PrimaryCommandPool).CheckResult(); VkCommandBufferAllocateInfo commandBufferInfo = new VkCommandBufferAllocateInfo { sType = VkStructureType.CommandBufferAllocateInfo, commandPool = _perFrame[i].PrimaryCommandPool, level = VkCommandBufferLevel.Primary, commandBufferCount = 1 }; vkAllocateCommandBuffers(VkDevice, &commandBufferInfo, out _perFrame[i].PrimaryCommandBuffer).CheckResult(); } }
protected override void Initialize() { var result = vkInitialize(); result.CheckResult(); var version = vkEnumerateInstanceVersion(); var queryExtensions = vkEnumerateInstanceExtensionProperties(); var queryLayers = vkEnumerateInstanceLayerProperties(); VkString name = "01-ClearScreen"; var appInfo = new VkApplicationInfo { sType = VkStructureType.ApplicationInfo, pApplicationName = name, applicationVersion = new VkVersion(1, 0, 0), pEngineName = s_EngineName, engineVersion = new VkVersion(1, 0, 0), apiVersion = VkVersion.Version_1_0, }; var instanceExtensions = new List <string> { KHRSurfaceExtensionName, KHRWin32SurfaceExtensionName }; var instanceLayers = new List <string>(); if (EnableValidationLayers) { FindValidationLayers(instanceLayers); } if (instanceLayers.Count > 0) { instanceExtensions.Add(EXTDebugUtilsExtensionName); } using var vkInstanceExtensions = new VkStringArray(instanceExtensions); var instanceCreateInfo = new VkInstanceCreateInfo { sType = VkStructureType.InstanceCreateInfo, pApplicationInfo = &appInfo, enabledExtensionCount = vkInstanceExtensions.Length, ppEnabledExtensionNames = vkInstanceExtensions }; using var vkLayerNames = new VkStringArray(instanceLayers); if (instanceLayers.Count > 0) { instanceCreateInfo.enabledLayerCount = vkLayerNames.Length; instanceCreateInfo.ppEnabledLayerNames = vkLayerNames; } result = vkCreateInstance(&instanceCreateInfo, null, out instance); vkLoadInstance(instance); if (instanceLayers.Count > 0) { _debugMessengerCallbackFunc = DebugMessengerCallback; var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT { sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT, messageSeverity = /*VkDebugUtilsMessageSeverityFlagsEXT.VerboseEXT | */ VkDebugUtilsMessageSeverityFlagsEXT.ErrorEXT | VkDebugUtilsMessageSeverityFlagsEXT.WarningEXT, messageType = VkDebugUtilsMessageTypeFlagsEXT.GeneralEXT | VkDebugUtilsMessageTypeFlagsEXT.ValidationEXT | VkDebugUtilsMessageTypeFlagsEXT.PerformanceEXT, pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc) }; vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult(); } var surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR { sType = VkStructureType.Win32SurfaceCreateInfoKHR, hinstance = HInstance, hwnd = MainWindow.Handle }; result = vkCreateWin32SurfaceKHR(instance, &surfaceCreateInfo, null, out surface); var physicalDevices = vkEnumeratePhysicalDevices(instance); foreach (var physicalDevice in physicalDevices) { vkGetPhysicalDeviceProperties(physicalDevice, out var properties); var deviceName = properties.GetDeviceName(); } physicalDevice = physicalDevices[0]; var queueFamilies = FindQueueFamilies(physicalDevice, surface); var priority = 1.0f; var queueCreateInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = queueFamilies.graphicsFamily, queueCount = 1, pQueuePriorities = &priority }; List <string> deviceExtensions = new List <string> { KHRSwapchainExtensionName }; var deviceCreateInfo = new VkDeviceCreateInfo { sType = VkStructureType.DeviceCreateInfo, pQueueCreateInfos = &queueCreateInfo, queueCreateInfoCount = 1, pEnabledFeatures = null, }; using var deviceExtensionNames = new VkStringArray(deviceExtensions); deviceCreateInfo.enabledExtensionCount = deviceExtensionNames.Length; deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames; result = vkCreateDevice(physicalDevice, &deviceCreateInfo, null, out device); if (result != VkResult.Success) { throw new Exception($"Failed to create Vulkan Logical Device, {result}"); } vkGetDeviceQueue(device, queueFamilies.graphicsFamily, 0, out graphicsQueue); vkGetDeviceQueue(device, queueFamilies.presentFamily, 0, out presentQueue); CreateSwapchain(); CreateSyncPrimitives(); }
private VkInstance CreateInstance(bool debug) { VkInstance instance; // Specify standard validation layers. string surfaceExtension; switch (Host.Platform) { case Platform.Android: surfaceExtension = KHRAndroidSurfaceExtensionName; break; case Platform.Win32: surfaceExtension = KHRWin32SurfaceExtensionName; break; default: throw new NotImplementedException(); } VkString name = "TODO Application Name"; var appInfo = new VkApplicationInfo { sType = VkStructureType.ApplicationInfo, pApplicationName = name, applicationVersion = new VkVersion(1, 0, 0), pEngineName = s_EngineName, engineVersion = new VkVersion(1, 0, 0), apiVersion = VkVersion.Version_1_0, }; var instanceExtensions = new List <string> { KHRSurfaceExtensionName, surfaceExtension }; var instanceLayers = new List <string>(); if (EnableValidationLayers) { FindValidationLayers(instanceLayers); } if (instanceLayers.Count > 0) { instanceExtensions.Add(EXTDebugUtilsExtensionName); } using var vkInstanceExtensions = new VkStringArray(instanceExtensions); var instanceCreateInfo = new VkInstanceCreateInfo { sType = VkStructureType.InstanceCreateInfo, pApplicationInfo = &appInfo, enabledExtensionCount = vkInstanceExtensions.Length, ppEnabledExtensionNames = vkInstanceExtensions }; using var vkLayerNames = new VkStringArray(instanceLayers); if (instanceLayers.Count > 0) { instanceCreateInfo.enabledLayerCount = vkLayerNames.Length; instanceCreateInfo.ppEnabledLayerNames = vkLayerNames; } VkResult result = vkCreateInstance(&instanceCreateInfo, null, out instance); vkLoadInstance(instance); if (instanceLayers.Count > 0) { _debugMessengerCallbackFunc = DebugMessengerCallback; var debugCreateInfo = new VkDebugUtilsMessengerCreateInfoEXT { sType = VkStructureType.DebugUtilsMessengerCreateInfoEXT, messageSeverity = VkDebugUtilsMessageSeverityFlagsEXT.Verbose | VkDebugUtilsMessageSeverityFlagsEXT.Error | VkDebugUtilsMessageSeverityFlagsEXT.Warning, messageType = VkDebugUtilsMessageTypeFlagsEXT.General | VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance, pfnUserCallback = Marshal.GetFunctionPointerForDelegate(_debugMessengerCallbackFunc) }; vkCreateDebugUtilsMessengerEXT(instance, &debugCreateInfo, null, out debugMessenger).CheckResult(); } return(instance); }