Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
        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);
                }
            }
        }
Beispiel #5
0
        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
        }
Beispiel #6
0
        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;
        }