public static VkQueueFamilyProperties Create(int queueCount, VkQueueFlagBits queueFlags) { return(new VkQueueFamilyProperties() { queueCount = queueCount, queueFlags = queueFlags, minImageTransferGranularity = VkExtent3D.Create(1, 1, 1) }); }
private uint GetQueueFamilyIndex(VkQueueFlagBits queueFlags) { // Dedicated queue for compute // Try to find a queue family index that supports compute but not graphics if ((queueFlags & VkQueueFlagBits.Compute) != 0) { for (uint i = 0; i < QueueFamilyProperties.Length; i++) { if (((QueueFamilyProperties[i].queueFlags & queueFlags) != 0) && (QueueFamilyProperties[i].queueFlags & VkQueueFlagBits.Graphics) == 0) { return(i); } } } // Dedicated queue for transfer // Try to find a queue family index that supports transfer but not graphics and compute if ((queueFlags & VkQueueFlagBits.Transfer) != 0) { for (uint i = 0; i < QueueFamilyProperties.Length; i++) { if (((QueueFamilyProperties[i].queueFlags & queueFlags) != 0) && (QueueFamilyProperties[i].queueFlags & VkQueueFlagBits.Graphics) == 0 && (QueueFamilyProperties[i].queueFlags & VkQueueFlagBits.Compute) == 0) { return(i); } } } // For other queue types or if no separate compute queue is present, return the first one to support the requested flags for (uint i = 0; i < QueueFamilyProperties.Length; i++) { if ((QueueFamilyProperties[i].queueFlags & queueFlags) != 0) { return(i); } } throw new InvalidOperationException("Could not find a matching queue family index"); }
public VkResult CreateLogicalDevice( VkPhysicalDeviceFeatures enabledFeatures, string[] enabledExtensions, bool useSwapChain = true, VkQueueFlagBits requestedQueueTypes = VkQueueFlagBits.Graphics | VkQueueFlagBits.Compute) { // Desired queues need to be requested upon logical device creation // Due to differing queue family configurations of Vulkan implementations this can be a bit tricky, especially if the application // requests different queue types var queueCreateInfos = new List <VkDeviceQueueCreateInfo>(); float defaultQueuePriority = 0.0f; // Graphics queue if ((requestedQueueTypes & VkQueueFlagBits.Graphics) != 0) { QFIndices.Graphics = GetQueueFamilyIndex(VkQueueFlagBits.Graphics); VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo(); queueInfo.sType = DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Graphics; queueInfo.queuePriorities = defaultQueuePriority; queueCreateInfos.Add(queueInfo); } else { QFIndices.Graphics = 0; } // Dedicated compute queue if ((requestedQueueTypes & VkQueueFlagBits.Compute) != 0) { QFIndices.Compute = GetQueueFamilyIndex(VkQueueFlagBits.Compute); if (QFIndices.Compute != QFIndices.Graphics) { // If compute family index differs, we need an additional queue create info for the compute queue VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo(); queueInfo.sType = DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Compute; queueInfo.queuePriorities = defaultQueuePriority; queueCreateInfos.Add(queueInfo); } } else { // Else we use the same queue QFIndices.Compute = QFIndices.Graphics; } // Dedicated transfer queue if ((requestedQueueTypes & VkQueueFlagBits.Transfer) != 0) { QFIndices.Transfer = GetQueueFamilyIndex(VkQueueFlagBits.Transfer); if (QFIndices.Transfer != QFIndices.Graphics && QFIndices.Transfer != QFIndices.Compute) { // If compute family index differs, we need an additional queue create info for the transfer queue VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo(); queueInfo.sType = DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Transfer; queueInfo.queuePriorities = defaultQueuePriority; queueCreateInfos.Add(queueInfo); } } else { // Else we use the same queue QFIndices.Transfer = QFIndices.Graphics; } // Create the logical device representation //using (NativeList<IntPtr> deviceExtensions = new NativeList<IntPtr>(enabledExtensions)) { var deviceExtensions = new List <string>(); 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(Strings.VK_KHR_SWAPCHAIN_EXTENSION_NAME); } var deviceCreateInfo = VkDeviceCreateInfo.Alloc(); deviceCreateInfo->queueCreateInfos = queueCreateInfos.ToArray(); deviceCreateInfo->pEnabledFeatures = &enabledFeatures; if (deviceExtensions.Count > 0) { string[] array = deviceExtensions.ToArray(); deviceCreateInfo[0].EnabledExtensions = array; } VkDevice device; VkResult result = vkCreateDevice(PhysicalDevice, deviceCreateInfo, null, &device); this._logicalDevice = device; if (result == VkResult.Success) { // Create a default command pool for graphics command buffers CommandPool = CreateCommandPool(QFIndices.Graphics); } return(result); }