Esempio n. 1
0
        public void Set(params VkDeviceQueueCreateInfo[] value)
        {
            IntPtr ptr = (IntPtr)this.pointer;

            value.Set(ref ptr, ref this.count);
            this.pointer = (VkDeviceQueueCreateInfo *)ptr;
        }
Esempio n. 2
0
 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);
        }
Esempio n. 4
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;
        }