private static VkDevice CreateDevice(VkInstance instance, out VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, out uint queueFamilyIndex) { queueFamilyIndex = 0;//SHORTCUT computed from queue properties physicalDevice = PickPhysicalDevice(instance, surface, out queueFamilyIndex); List <GCHandle> handles = new List <GCHandle>(); List <string> requiredExtensions = new List <string>(); requiredExtensions.Add("VK_KHR_swapchain"); string[] extensionNames = requiredExtensions.ToArray(); byte[][] pExtensionNames = new byte[extensionNames.Length][]; byte *[] ppExtensionNamesArray = new byte *[extensionNames.Length]; for (int i = 0; i < pExtensionNames.Length; i++) { pExtensionNames[i] = Encoding.UTF8.GetBytes(extensionNames[i] + char.MinValue); GCHandle handle = GCHandle.Alloc(pExtensionNames[i]); handles.Add(handle); fixed(byte *p = &(((byte[])handle.Target)[0])) { ppExtensionNamesArray[i] = p; } } VkDevice device; fixed(byte **extensions = &ppExtensionNamesArray[0]) { float[] pQueuePriorities = new float[] { 1.0f }; VkDeviceQueueCreateInfo deviceQueueCreateInfo = VkDeviceQueueCreateInfo.New(); deviceQueueCreateInfo.queueFamilyIndex = queueFamilyIndex; deviceQueueCreateInfo.queueCount = 1; fixed(float *ptr = &(pQueuePriorities[0])) deviceQueueCreateInfo.pQueuePriorities = ptr; VkDeviceCreateInfo createInfo = VkDeviceCreateInfo.New(); createInfo.queueCreateInfoCount = 1; createInfo.pQueueCreateInfos = &deviceQueueCreateInfo; createInfo.ppEnabledExtensionNames = extensions; createInfo.enabledExtensionCount = (uint)extensionNames.Length; device = VkDevice.Null; Assert(vkCreateDevice(physicalDevice, &createInfo, null, &device)); foreach (var handle in handles) { handle.Free(); } } return(device); }
private void CreateLogicalDevice() { GetQueueFamilyIndices(); HashSet <uint> familyIndices = new HashSet <uint> { _graphicsQueueIndex, _presentQueueIndex }; RawList <VkDeviceQueueCreateInfo> queueCreateInfos = new RawList <VkDeviceQueueCreateInfo>(); foreach (uint index in familyIndices) { VkDeviceQueueCreateInfo queueCreateInfo = VkDeviceQueueCreateInfo.New(); queueCreateInfo.queueFamilyIndex = _graphicsQueueIndex; queueCreateInfo.queueCount = 1; float priority = 1f; queueCreateInfo.pQueuePriorities = &priority; queueCreateInfos.Add(queueCreateInfo); } VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures(); deviceFeatures.samplerAnisotropy = true; deviceFeatures.fillModeNonSolid = true; deviceFeatures.geometryShader = true; deviceFeatures.depthClamp = true; VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New(); fixed(VkDeviceQueueCreateInfo *qciPtr = &queueCreateInfos.Items[0]) { deviceCreateInfo.pQueueCreateInfos = qciPtr; deviceCreateInfo.queueCreateInfoCount = queueCreateInfos.Count; deviceCreateInfo.pEnabledFeatures = &deviceFeatures; StackList <IntPtr> layerNames = new StackList <IntPtr>(); layerNames.Add(CommonStrings.StandardValidationLayerName); deviceCreateInfo.enabledLayerCount = layerNames.Count; deviceCreateInfo.ppEnabledLayerNames = (byte **)layerNames.Data; byte *extensionNames = CommonStrings.VK_KHR_SWAPCHAIN_EXTENSION_NAME; deviceCreateInfo.enabledExtensionCount = 1; deviceCreateInfo.ppEnabledExtensionNames = &extensionNames; vkCreateDevice(_physicalDevice, ref deviceCreateInfo, null, out _device); } vkGetDeviceQueue(_device, _graphicsQueueIndex, 0, out _graphicsQueue); vkGetDeviceQueue(_device, _presentQueueIndex, 0, out _presentQueue); }
private void CreateLogicalDevice() { GetQueueFamilyIndices(); HashSet <uint> familyIndices = new HashSet <uint> { _graphicsQueueIndex, _presentQueueIndex }; RawList <VkDeviceQueueCreateInfo> queueCreateInfos = new RawList <VkDeviceQueueCreateInfo>(); foreach (uint index in familyIndices) { VkDeviceQueueCreateInfo queueCreateInfo = VkDeviceQueueCreateInfo.New(); queueCreateInfo.queueFamilyIndex = _graphicsQueueIndex; queueCreateInfo.queueCount = 1; float priority = 1f; queueCreateInfo.pQueuePriorities = &priority; queueCreateInfos.Add(queueCreateInfo); } VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures(); deviceFeatures.samplerAnisotropy = true; deviceFeatures.fillModeNonSolid = true; deviceFeatures.geometryShader = true; deviceFeatures.depthClamp = true; bool debugMarkerSupported = false; uint propertyCount = 0; VkResult result = vkEnumerateDeviceExtensionProperties(_physicalDevice, (byte *)null, &propertyCount, null); CheckResult(result); VkExtensionProperties *properties = stackalloc VkExtensionProperties[(int)propertyCount]; result = vkEnumerateDeviceExtensionProperties(_physicalDevice, (byte *)null, &propertyCount, properties); CheckResult(result); for (int i = 0; i < propertyCount; i++) { if (Util.GetString(properties[i].extensionName) == "VK_EXT_debug_marker") { Console.WriteLine("VK_EXT_debug_marker is available."); debugMarkerSupported = true; break; } } VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New(); fixed(VkDeviceQueueCreateInfo *qciPtr = &queueCreateInfos.Items[0]) { deviceCreateInfo.pQueueCreateInfos = qciPtr; deviceCreateInfo.queueCreateInfoCount = queueCreateInfos.Count; deviceCreateInfo.pEnabledFeatures = &deviceFeatures; StackList <IntPtr> layerNames = new StackList <IntPtr>(); layerNames.Add(CommonStrings.StandardValidationLayerName); deviceCreateInfo.enabledLayerCount = layerNames.Count; deviceCreateInfo.ppEnabledLayerNames = (byte **)layerNames.Data; StackList <IntPtr> extensionNames = new StackList <IntPtr>(); extensionNames.Add(CommonStrings.VK_KHR_SWAPCHAIN_EXTENSION_NAME); if (debugMarkerSupported) { extensionNames.Add(CommonStrings.VK_EXT_DEBUG_MARKER_EXTENSION_NAME); _debugMarkerEnabled = true; } deviceCreateInfo.enabledExtensionCount = extensionNames.Count; deviceCreateInfo.ppEnabledExtensionNames = (byte **)extensionNames.Data; result = vkCreateDevice(_physicalDevice, ref deviceCreateInfo, null, out _device); CheckResult(result); } vkGetDeviceQueue(_device, _graphicsQueueIndex, 0, out _graphicsQueue); vkGetDeviceQueue(_device, _presentQueueIndex, 0, out _presentQueue); if (debugMarkerSupported) { IntPtr setObjectNamePtr; using (FixedUtf8String debugExtFnName = "vkDebugMarkerSetObjectNameEXT") { setObjectNamePtr = vkGetInstanceProcAddr(_instance, debugExtFnName); } _setObjectNameDelegate = Marshal.GetDelegateForFunctionPointer <vkDebugMarkerSetObjectNameEXT_d>(setObjectNamePtr); } }
public VkResult CreateLogicalDevice( VkPhysicalDeviceFeatures enabledFeatures, NativeList <IntPtr> enabledExtensions, bool useSwapChain = true, VkQueueFlags requestedQueueTypes = VkQueueFlags.Graphics | VkQueueFlags.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 using (NativeList <VkDeviceQueueCreateInfo> queueCreateInfos = new NativeList <VkDeviceQueueCreateInfo>()) { float defaultQueuePriority = 0.0f; // Graphics queue if ((requestedQueueTypes & VkQueueFlags.Graphics) != 0) { QFIndices.Graphics = GetQueueFamilyIndex(VkQueueFlags.Graphics); VkDeviceQueueCreateInfo queueInfo = new VkDeviceQueueCreateInfo(); queueInfo.sType = VkStructureType.DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Graphics; queueInfo.queueCount = 1; queueInfo.pQueuePriorities = &defaultQueuePriority; queueCreateInfos.Add(queueInfo); } else { QFIndices.Graphics = (uint)NullHandle; } // Dedicated compute queue if ((requestedQueueTypes & VkQueueFlags.Compute) != 0) { QFIndices.Compute = GetQueueFamilyIndex(VkQueueFlags.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 = VkStructureType.DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Compute; queueInfo.queueCount = 1; queueInfo.pQueuePriorities = &defaultQueuePriority; queueCreateInfos.Add(queueInfo); } } else { // Else we use the same queue QFIndices.Compute = QFIndices.Graphics; } // Dedicated transfer queue if ((requestedQueueTypes & VkQueueFlags.Transfer) != 0) { QFIndices.Transfer = GetQueueFamilyIndex(VkQueueFlags.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 = VkStructureType.DeviceQueueCreateInfo; queueInfo.queueFamilyIndex = QFIndices.Transfer; queueInfo.queueCount = 1; queueInfo.pQueuePriorities = &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)) { 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); } VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New(); deviceCreateInfo.queueCreateInfoCount = queueCreateInfos.Count; deviceCreateInfo.pQueueCreateInfos = (VkDeviceQueueCreateInfo *)queueCreateInfos.Data.ToPointer(); deviceCreateInfo.pEnabledFeatures = &enabledFeatures; if (deviceExtensions.Count > 0) { deviceCreateInfo.enabledExtensionCount = deviceExtensions.Count; deviceCreateInfo.ppEnabledExtensionNames = (byte **)deviceExtensions.Data.ToPointer(); } VkResult result = vkCreateDevice(PhysicalDevice, &deviceCreateInfo, null, out _logicalDevice); if (result == VkResult.Success) { // Create a default command pool for graphics command buffers CommandPool = CreateCommandPool(QFIndices.Graphics); } return(result); } } }
public void Activate(VkPhysicalDeviceFeatures enabledFeatures, params string[] extensions) { List <VkDeviceQueueCreateInfo> qInfos = new List <VkDeviceQueueCreateInfo> (); List <List <float> > prioritiesLists = new List <List <float> > ();//store pinned lists for later unpin foreach (IGrouping <uint, Queue> qfams in queues.GroupBy(q => q.qFamIndex)) { int qTot = qfams.Count(); uint qIndex = 0; List <float> priorities = new List <float> (); bool qCountReached = false; //true when queue count of that family is reached foreach (Queue q in qfams) { if (!qCountReached) { priorities.Add(q.priority); } q.index = qIndex++; if (qIndex == phy.QueueFamilies[qfams.Key].queueCount) { qIndex = 0; qCountReached = true; } } qInfos.Add(new VkDeviceQueueCreateInfo { sType = VkStructureType.DeviceQueueCreateInfo, queueCount = qCountReached ? phy.QueueFamilies[qfams.Key].queueCount : qIndex, queueFamilyIndex = qfams.Key, pQueuePriorities = priorities.Pin() }); prioritiesLists.Add(priorities); //add for unpined } //enable only supported exceptions List <IntPtr> deviceExtensions = new List <IntPtr> (); for (int i = 0; i < extensions.Length; i++) { if (phy.GetDeviceExtensionSupported(extensions[i])) { deviceExtensions.Add(new FixedUtf8String(extensions[i])); } } VkDeviceCreateInfo deviceCreateInfo = VkDeviceCreateInfo.New(); deviceCreateInfo.queueCreateInfoCount = (uint)qInfos.Count; deviceCreateInfo.pQueueCreateInfos = qInfos.Pin(); deviceCreateInfo.pEnabledFeatures = enabledFeatures.Pin(); if (deviceExtensions.Count > 0) { deviceCreateInfo.enabledExtensionCount = (uint)deviceExtensions.Count; deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.Pin(); } Utils.CheckResult(vkCreateDevice(phy.Handle, ref deviceCreateInfo, IntPtr.Zero, out dev)); qInfos.Unpin(); enabledFeatures.Unpin(); foreach (List <float> fa in prioritiesLists) { fa.Unpin(); } deviceExtensions.Unpin(); //Vk.LoadDeviceFunctionPointers (dev); foreach (Queue q in queues) { q.updateHandle(); } #if MEMORY_POOLS resourceManager = new ResourceManager(this); #endif }
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; }