public void Set(params VkDeviceQueueCreateInfo[] value) { IntPtr ptr = (IntPtr)this.pointer; value.Set(ref ptr, ref this.count); this.pointer = (VkDeviceQueueCreateInfo *)ptr; }
public VkDeviceQueueCreateInfoGroup(params VkDeviceQueueCreateInfo[] value) { this.count = 0; this.pointer = null; if (value != null) { IntPtr ptr = IntPtr.Zero; value.Set(ref ptr, ref this.count); this.pointer = (VkDeviceQueueCreateInfo *)ptr; } }
public VulkanContext(VkInstance instance, VkSurfaceKHR surface, Platform platform) { // Find graphics and presentation capable physical device(s) that support // the provided surface for platform. int graphicsQueueFamilyIndex = -1; int computeQueueFamilyIndex = -1; int presentQueueFamilyIndex = -1; var physicalDevices = vkEnumeratePhysicalDevices(instance); foreach (var physicalDevice in physicalDevices) { uint Count = 0; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &Count, null); VkQueueFamilyProperties *queueFamilyPropertiesptr = stackalloc VkQueueFamilyProperties[(int)Count]; vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &Count, queueFamilyPropertiesptr); for (int i = 0; i < Count; i++) { if (queueFamilyPropertiesptr[i].queueFlags.HasFlag(VkQueueFlags.Graphics)) { if (graphicsQueueFamilyIndex == -1) { graphicsQueueFamilyIndex = i; } if (computeQueueFamilyIndex == -1) { computeQueueFamilyIndex = i; } VkBool32 isSupported; uint queueFamilyIndex = (uint)i; VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamilyIndex, surface, out isSupported); result.CheckResult(); if (isSupported == VkBool32.True) { bool presentationSupport = false; if (platform == Platform.Win32) { presentationSupport = vkGetPhysicalDeviceWin32PresentationSupportKHR(physicalDevice, queueFamilyIndex); } else { presentationSupport = true; } if (presentationSupport) { presentQueueFamilyIndex = i; } } if (graphicsQueueFamilyIndex != -1 && computeQueueFamilyIndex != -1 && presentQueueFamilyIndex != -1) { PhysicalDevice = physicalDevice; break; } } } if (PhysicalDevice != null) { break; } } if (PhysicalDevice == null) { throw new InvalidOperationException("No suitable physical device found."); } vkGetPhysicalDeviceMemoryProperties(PhysicalDevice, out VkPhysicalDeviceMemoryProperties memoryProperties); MemoryProperties = memoryProperties; vkGetPhysicalDeviceFeatures(PhysicalDevice, out VkPhysicalDeviceFeatures features); Features = features; vkGetPhysicalDeviceProperties(PhysicalDevice, out VkPhysicalDeviceProperties physicalDeviceProperties); Properties = physicalDeviceProperties; // Create a logical device. bool sameGraphicsAndPresent = graphicsQueueFamilyIndex == presentQueueFamilyIndex; VkDeviceQueueCreateInfo *queueCreateInfos = stackalloc VkDeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2]; float defaultQueuePriority = 1.0f; VkDeviceQueueCreateInfo queueInfoGraphics = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = (uint)graphicsQueueFamilyIndex, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos[0] = queueInfoGraphics; if (!sameGraphicsAndPresent) { queueCreateInfos[1] = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = (uint)presentQueueFamilyIndex, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; } VkDeviceCreateInfo deviceCreateInfo = new VkDeviceCreateInfo { sType = VkStructureType.DeviceCreateInfo, pNext = null, flags = VkDeviceCreateFlags.None, queueCreateInfoCount = (uint)(sameGraphicsAndPresent ? 1 : 2), pQueueCreateInfos = queueCreateInfos, }; deviceCreateInfo.pEnabledFeatures = &features; string[] deviceExtensions = new[] { // If the device will be used for presenting to a display via a swapchain we need to request the swapchain extension "VK_KHR_swapchain" }; deviceCreateInfo.enabledExtensionCount = (uint)deviceExtensions.Length; deviceCreateInfo.ppEnabledExtensionNames = Interop.String.AllocToPointers(deviceExtensions); VkResult result2 = vkCreateDevice(PhysicalDevice, &deviceCreateInfo, null, out VkDevice device); result2.CheckResult(); Device = device; // Get queue(s). GraphicsQueue = GetQueue((uint)graphicsQueueFamilyIndex); ComputeQueue = computeQueueFamilyIndex == graphicsQueueFamilyIndex ? GraphicsQueue : GetQueue((uint)computeQueueFamilyIndex); PresentQueue = presentQueueFamilyIndex == graphicsQueueFamilyIndex ? GraphicsQueue : GetQueue((uint)presentQueueFamilyIndex); GraphicsQueueFamilyIndex = graphicsQueueFamilyIndex; PresentQueueFamilyIndex = presentQueueFamilyIndex; ComputeQueueFamilyIndex = presentQueueFamilyIndex; GraphicsCommandPool = CreateCommandPool((uint)graphicsQueueFamilyIndex); ComputeCommandPool = CreateCommandPool((uint)computeQueueFamilyIndex); }
internal void CreateDevice() { VkDeviceQueueCreateInfo *queueCreateInfos = stackalloc VkDeviceQueueCreateInfo[3]; float defaultQueuePriority = 0.0f; VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.Compute | VkQueueFlags.Transfer; // Graphics queue if ((requestedQueueTypes & VkQueueFlags.Graphics) != 0) { GraphicsFamily = GetQueueFamilyIndex(VkQueueFlags.Graphics, QueueFamilyProperties); VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = GraphicsFamily, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos[0] = (queueInfo); } else { GraphicsFamily = (uint)NullHandle; } // Dedicated compute queue if ((requestedQueueTypes & VkQueueFlags.Compute) != 0) { ComputeFamily = GetQueueFamilyIndex(VkQueueFlags.Compute, QueueFamilyProperties); if (ComputeFamily != GraphicsFamily) { // If compute family index differs, we need an additional queue create info for the compute queue VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = ComputeFamily, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos[1] = (queueInfo); } } else { // Else we use the same queue ComputeFamily = GraphicsFamily; } // Dedicated transfer queue if ((requestedQueueTypes & VkQueueFlags.Transfer) != 0) { TransferFamily = GetQueueFamilyIndex(VkQueueFlags.Transfer, QueueFamilyProperties); if (TransferFamily != GraphicsFamily && TransferFamily != ComputeFamily) { // If compute family index differs, we need an additional queue create info for the transfer queue VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueFamilyIndex = TransferFamily, queueCount = 1, pQueuePriorities = &defaultQueuePriority }; queueCreateInfos[2] = (queueInfo); } } else { // Else we use the same queue TransferFamily = GraphicsFamily; } // Create the logical device representation List <string> deviceExtensions = new List <string>(); // If the device will be used for presenting to a display via a swapchain we need to request the swapchain extension deviceExtensions.Add("VK_KHR_swapchain"); var oldFeatures = Features; VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New(); deviceCreateInfo.queueCreateInfoCount = 3; deviceCreateInfo.pQueueCreateInfos = queueCreateInfos; deviceCreateInfo.pEnabledFeatures = &oldFeatures; if (deviceExtensions.Count > 0) { deviceCreateInfo.enabledExtensionCount = (uint)deviceExtensions.Count; deviceCreateInfo.ppEnabledExtensionNames = Interop.String.AllocToPointers(deviceExtensions.ToArray()); } vkCreateDevice(NativeAdapter.NativePhysicalDevice, &deviceCreateInfo, null, out var device); Device = device; }