void CreateDevice() { var features = new Native <VkPhysicalDeviceFeatures>(); VK.GetPhysicalDeviceFeatures(physicalDevice, features.Address); HashSet <uint> uniqueIndices = new HashSet <uint> { graphicsIndex, presentIndex }; var queueInfos = new NativeArray <VkDeviceQueueCreateInfo>(uniqueIndices.Count); var priorities = new Native <float>(1); int i = 0; foreach (var ind in uniqueIndices) { var queueInfo = new VkDeviceQueueCreateInfo(); queueInfo.sType = CSGL.Vulkan.VkStructureType.DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = ind; queueInfo.queueCount = 1; queueInfo.pQueuePriorities = priorities.Address; queueInfos[i] = queueInfo; i++; } var info = new VkDeviceCreateInfo(); info.sType = CSGL.Vulkan.VkStructureType.DeviceCreateInfo; info.pQueueCreateInfos = queueInfos.Address; info.queueCreateInfoCount = (uint)uniqueIndices.Count; info.pEnabledFeatures = features.Address; var extensionsNative = new NativeStringArray(deviceExtensions); info.ppEnabledExtensionNames = extensionsNative.Address; info.enabledExtensionCount = (uint)deviceExtensions.Length; var result = VK.CreateDevice(physicalDevice, ref info, alloc, out device); VK.GetDeviceQueue(device, graphicsIndex, 0, out graphicsQueue); VK.GetDeviceQueue(device, presentIndex, 0, out presentQueue); features.Dispose(); priorities.Dispose(); queueInfos.Dispose(); extensionsNative.Dispose(); }
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); } }