static VkDevice CreateLogicalDevice(VkPhysicalDeviceFeatures enabledFeatures, CStringList enabledExtensions, bool useSwapChain = true, VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.Compute | VkQueueFlags.Transfer) { using Vector <VkDeviceQueueCreateInfo> queueCreateInfos = new Vector <VkDeviceQueueCreateInfo>(); float defaultQueuePriority = 0.0f; // Graphics queue if ((requestedQueueTypes & VkQueueFlags.Graphics) != 0) { QFGraphics = GetQueueFamilyIndex(VkQueueFlags.Graphics); var queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = QFGraphics, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos.Add(queueInfo); } else { QFGraphics = (uint)IntPtr.Zero; } // Dedicated compute queue if ((requestedQueueTypes & VkQueueFlags.Compute) != 0) { QFCompute = GetQueueFamilyIndex(VkQueueFlags.Compute); if (QFCompute != QFGraphics) { // If compute family index differs, we need an additional queue create info for the compute queue var queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = QFCompute, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos.Add(queueInfo); } } else { // Else we use the same queue QFCompute = QFGraphics; } // Dedicated transfer queue if ((requestedQueueTypes & VkQueueFlags.Transfer) != 0) { QFTransfer = GetQueueFamilyIndex(VkQueueFlags.Transfer); if (QFTransfer != QFGraphics && QFTransfer != QFCompute) { // If compute family index differs, we need an additional queue create info for the transfer queue var queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = QFTransfer, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos.Add(queueInfo); } } else { // Else we use the same queue QFTransfer = QFGraphics; } // Create the logical device representation using CStringList deviceExtensions = new CStringList(enabledExtensions); if (useSwapChain) { // If the device will be used for presenting to a display via a swapchain we need to request the swapchain extension deviceExtensions.Add(Vulkan.KHRSwapchainExtensionName); } var deviceCreateInfo = new VkDeviceCreateInfo { sType = VkStructureType.DeviceCreateInfo, queueCreateInfoCount = queueCreateInfos.Count, pQueueCreateInfos = queueCreateInfos.DataPtr, pEnabledFeatures = &enabledFeatures }; if (deviceExtensions.Count > 0) { deviceCreateInfo.enabledExtensionCount = deviceExtensions.Count; deviceCreateInfo.ppEnabledExtensionNames = (byte **)deviceExtensions.Data; } return(Vulkan.CreateDevice(PhysicalDevice, &deviceCreateInfo)); }