Example #1
0
        private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice);

            // acquire Raytracing features
            VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR,
                pNext = null,
            };

            VkPhysicalDeviceFeatures2 deviceFeatures2 = new VkPhysicalDeviceFeatures2()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
                pNext = &rayTracingFeatures,
            };

            VulkanNative.vkGetPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2);

            extensionsSupported = extensionsSupported && rayTracingFeatures.rayTracing;

            bool swapChainAdequate = false;

            if (extensionsSupported)
            {
                SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice);
                swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0);
            }

            return(indices.IsComplete() && extensionsSupported && swapChainAdequate);
        }
Example #2
0
        private void FindQueueFamilies(PhysicalDevice device, out QueueFamilyIndices indices)
        {
            indices = new QueueFamilyIndices();

            var families = QuerryQueueFamilyProperties(device);

            for (int i = 0; i < families.Length; ++i)
            {
                ref QueueFamilyProperties queueFamily = ref families[i];

                const QueueFlags GraphicsQueueBits = QueueFlags.QueueGraphicsBit | QueueFlags.QueueTransferBit;

                if ((queueFamily.QueueFlags & GraphicsQueueBits) == GraphicsQueueBits)
                {
                    indices.GraphicsFamily = (uint)i;
                }

                var res = VkSurface.GetPhysicalDeviceSurfaceSupport(device, (uint)i, this.WindowSurface, out var presentSupport);

                if (res == Result.Success && presentSupport)
                {
                    indices.PresentFamily = (uint)i;
                }

                if (indices.IsComplete())
                {
                    break;
                }
            }
Example #3
0
        private QueueFamilyIndices FindQueueFamilies(PhysicalDevice device)
        {
            QueueFamilyIndices indices = new QueueFamilyIndices();

            var queueFamilies = device.GetQueueFamilyProperties();

            for (uint index = 0; index < queueFamilies.Length && !indices.IsComplete; index++)
            {
                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.GraphicsFamily = index;
                }

                if (device.GetSurfaceSupport(index, this.surface))
                {
                    indices.PresentFamily = index;
                }

                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Transfer) && !queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.TransferFamily = index;
                }
            }

            if (!indices.TransferFamily.HasValue)
            {
                indices.TransferFamily = indices.GraphicsFamily;
            }

            return(indices);
        }
Example #4
0
        private void CreateCommandPools()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(this.physicalDevice);

            this.transientCommandPool = device.CreateCommandPool(queueFamilies.TransferFamily.Value, CommandPoolCreateFlags.Transient);

            this.commandPool = device.CreateCommandPool(queueFamilies.GraphicsFamily.Value);
        }
Example #5
0
        private void CreateCommandPool()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(this.physicalDevice);

            this.commandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                QueueFamilyIndex = queueFamilies.GraphicsFamily.Value
            });
        }
Example #6
0
        public void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = helper.FindQueueFamilies(this.physicalDevice, surface);

            this.device = physicalDevice.CreateDevice(queueFamilies.Indices
                                                      .Select(index => new DeviceQueueCreateInfo {
                QueueFamilyIndex = index,
                QueuePriorities  = new[] { 1f }
            }).ToArray(),
                                                      null,
                                                      KhrExtensions.Swapchain);

            this.graphicsQueue = this.device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            this.presentQueue  = this.device.GetQueue(queueFamilies.PresentFamily.Value, 0);
        }
Example #7
0
        private void CreateCommandPools()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(this.physicalDevice);

            this.transientCommandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                Flags            = CommandPoolCreateFlags.Transient,
                QueueFamilyIndex = queueFamilies.TransferFamily.Value
            });

            this.commandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                QueueFamilyIndex = queueFamilies.GraphicsFamily.Value
            });
        }
Example #8
0
        private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice);

            bool swapChainAdequate = false;

            if (extensionsSupported)
            {
                SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice);
                swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0);
            }

            return(indices.IsComplete() && extensionsSupported && swapChainAdequate);
        }
        private void CreateCommandPool()
        {
            QueueFamilyIndices queueFamilyIndices = this.FindQueueFamilies(this.physicalDevice);

            VkCommandPoolCreateInfo poolInfo = new VkCommandPoolCreateInfo()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
                queueFamilyIndex = queueFamilyIndices.graphicsFamily.Value,
                flags            = 0, // Optional,
            };

            fixed(VkCommandPool *commandPoolPtr = &this.commandPool)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateCommandPool(device, &poolInfo, null, commandPoolPtr));
            }
        }
Example #10
0
        private void CreateSwapChain()
        {
            SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice);

            uint imageCount = swapChainSupport.Capabilities.MinImageCount + 1;

            if (swapChainSupport.Capabilities.MaxImageCount > 0 && imageCount > swapChainSupport.Capabilities.MaxImageCount)
            {
                imageCount = swapChainSupport.Capabilities.MaxImageCount;
            }

            SurfaceFormat surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.Formats);

            QueueFamilyIndices queueFamilies = this.FindQueueFamilies(this.physicalDevice);

            var indices = queueFamilies.Indices.ToArray();

            Extent2D extent = this.ChooseSwapExtent(swapChainSupport.Capabilities);

            this.swapChain = device.CreateSwapchain(new SwapchainCreateInfo
            {
                Surface          = surface,
                Flags            = SwapchainCreateFlags.None,
                PresentMode      = this.ChooseSwapPresentMode(swapChainSupport.PresentModes),
                MinImageCount    = imageCount,
                ImageExtent      = extent,
                ImageUsage       = ImageUsageFlags.ColorAttachment,
                PreTransform     = swapChainSupport.Capabilities.CurrentTransform,
                ImageArrayLayers = 1,
                ImageSharingMode = indices.Length == 1
                                    ? SharingMode.Exclusive
                                    : SharingMode.Concurrent,
                QueueFamilyIndices = indices,
                ImageFormat        = surfaceFormat.Format,
                ImageColorSpace    = surfaceFormat.ColorSpace,
                Clipped            = true,
                CompositeAlpha     = CompositeAlphaFlags.Opaque,
                OldSwapchain       = this.swapChain
            });

            this.swapChainFormat = surfaceFormat.Format;
            this.swapChainExtent = extent;

            this.swapChainImages = this.swapChain.GetImages();

            this.swapChainImageViews = swapChainImages.Select(image => this.CreateImageView(image, this.swapChainFormat, ImageAspectFlags.Color)).ToArray();
        }
Example #11
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(this.physicalDevice);

            this.device = physicalDevice.CreateDevice(queueFamilies.Indices
                                                      .Select(index => new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = index,
                QueuePriorities  = new[] { 1f }
            }).ToArray(),
                                                      null,
                                                      new[] { "VK_KHR_swapchain" });

            this.graphicsQueue = this.device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            this.presentQueue  = this.device.GetQueue(queueFamilies.PresentFamily.Value, 0);
            this.transferQueue = this.device.GetQueue(queueFamilies.TransferFamily.Value, 0);
        }
Example #12
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(physicalDevice);

            device = physicalDevice.CreateDevice(
                queueFamilies.Indices.Select(index => new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = index,
                QueuePriorities  = new[] { 1f }
            }).ToArray(),
                null,
                KhrExtensions.Swapchain
                );

            graphicsQueue = device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            presentQueue  = device.GetQueue(queueFamilies.PresentFamily.Value, 0);
            transferQueue = device.GetQueue(queueFamilies.TransferFamily.Value, 0);
        }
Example #13
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(this.physicalDevice);

            this.device = physicalDevice.CreateDevice(new DeviceCreateInfo
            {
                QueueCreateInfos = queueFamilies.Indices
                                   .Select(index => new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = index,
                    QueuePriorities  = new[] { 1f }
                }).ToArray(),
                EnabledExtensionNames = new[] { KhrSwapchain.ExtensionName }
            });

            this.graphicsQueue = this.device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            this.presentQueue  = this.device.GetQueue(queueFamilies.PresentFamily.Value, 0);
        }
Example #14
0
        private void CreateSwapChain()
        {
            SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice);

            uint imageCount = swapChainSupport.Capabilities.MinImageCount + 1;

            if (swapChainSupport.Capabilities.MaxImageCount > 0 && imageCount > swapChainSupport.Capabilities.MaxImageCount)
            {
                imageCount = swapChainSupport.Capabilities.MaxImageCount;
            }

            SurfaceFormat surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.Formats);

            QueueFamilyIndices queueFamilies = this.FindQueueFamilies(this.physicalDevice);

            var indices = queueFamilies.Indices.ToArray();

            Extent2D extent = this.ChooseSwapExtent(swapChainSupport.Capabilities);

            this.swapChain = device.CreateSwapchain(surface,
                                                    imageCount,
                                                    surfaceFormat.Format,
                                                    surfaceFormat.ColorSpace,
                                                    extent,
                                                    1,
                                                    ImageUsageFlags.ColorAttachment | ImageUsageFlags.TransferDestination,
                                                    indices.Length == 1
                                                        ? SharingMode.Exclusive
                                                        : SharingMode.Concurrent,
                                                    indices,
                                                    swapChainSupport.Capabilities.CurrentTransform,
                                                    CompositeAlphaFlags.Opaque,
                                                    this.ChooseSwapPresentMode(swapChainSupport.PresentModes),
                                                    true,
                                                    this.swapChain);

            this.swapChainFormat = surfaceFormat.Format;
            this.swapChainExtent = extent;

            this.swapChainImages = this.swapChain.GetImages();

            this.swapChainImageViews = swapChainImages.Select(image => this.CreateImageView(image, this.swapChainFormat, ImageAspectFlags.Color)).ToArray();
        }
Example #15
0
        private QueueFamilyIndices FindQueueFamilies(PhysicalDevice device)
        {
            var queueFamilyProperties = device.GetQueueFamilyProperties();
            var queueFamilyIndices    = new QueueFamilyIndices();

            for (int queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; queueFamilyUsedIndex++)
            {
                //Check Present Support
                if (device.GetSurfaceSupportKHR((uint)queueFamilyUsedIndex, data.surface))
                {
                    queueFamilyIndices.PresentFamily = queueFamilyUsedIndex;
                }
                //Check Graphics Support
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    queueFamilyIndices.GraphicsFamily = queueFamilyUsedIndex;
                }
            }
            return(queueFamilyIndices);
        }
Example #16
0
        public static QueueFamilyIndices _FindQueueFamilies(PhysicalDevice device, Surface surface)
        {
            QueueFamilyIndices indices = new QueueFamilyIndices();

            var queueFamilies = device.GetQueueFamilyProperties();

            for (uint index = 0; index < queueFamilies.Length && !indices.IsComplete; index++)
            {
                if (queueFamilies[index].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    indices.GraphicsFamily = index;
                }

                if (device.GetSurfaceSupport(index, surface))
                {
                    indices.PresentFamily = index;
                }
            }

            return(indices);
        }
Example #17
0
        private QueueFamilyIndices FindQueueFamilies(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = default;

            uint queueFamilyCount = 0;

            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, null);

            VkQueueFamilyProperties *queueFamilies = stackalloc VkQueueFamilyProperties[(int)queueFamilyCount];

            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies);

            for (uint i = 0; i < queueFamilyCount; i++)
            {
                var queueFamily = queueFamilies[i];
                if ((queueFamily.queueFlags & VkQueueFlags.VK_QUEUE_GRAPHICS_BIT) != 0)
                {
                    indices.graphicsFamily = i;
                }

                VkBool32 presentSupport = false;
                Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, this.surface, &presentSupport));

                if (presentSupport)
                {
                    indices.presentFamily = i;
                }

                if (indices.IsComplete())
                {
                    break;
                }
            }

            return(indices);
        }
Example #18
0
        private PhysicalDevice SelectPhysicalDevice(out QueueFamilyIndices indices)
        {
            uint count = 0;
            var  res   = VkApi.EnumeratePhysicalDevices(this.Instance, &count, null);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Unable to enumerate physical devices", res);
            }

            if (count == 0)
            {
                throw new Exception("No physical devices found!");
            }

            PhysicalDevice *deviceList = stackalloc PhysicalDevice[(int)count];

            res = VkApi.EnumeratePhysicalDevices(this.Instance, &count, deviceList);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Unable to enumerate physical devices", res);
            }

            for (uint i = 0; i < count; ++i)
            {
                var device = deviceList[i];

                if (IsDeviceSuitable(device, out indices))
                {
                    return(device);
                }
            }

            throw new Exception("No suitable device found!");
        }
Example #19
0
        private bool IsDeviceSuitable(VkPhysicalDevice physicalDevice)
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            return(indices.IsComplete());
        }
Example #20
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            List <VkDeviceQueueCreateInfo> queueCreateInfos = new List <VkDeviceQueueCreateInfo>();
            HashSet <uint> uniqueQueueFamilies = new HashSet <uint>()
            {
                indices.graphicsFamily.Value, indices.presentFamily.Value
            };

            float queuePriority = 1.0f;

            foreach (uint queueFamily in uniqueQueueFamilies)
            {
                VkDeviceQueueCreateInfo queueCreateInfo = new VkDeviceQueueCreateInfo()
                {
                    sType            = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
                    queueFamilyIndex = queueFamily,
                    queueCount       = 1,
                    pQueuePriorities = &queuePriority,
                };
                queueCreateInfos.Add(queueCreateInfo);
            }

            VkPhysicalDeviceFeatures deviceFeatures = default;

            // Raytracing extensions
            VkPhysicalDeviceRayTracingFeaturesKHR deviceRayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR()
            {
                sType      = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR,
                pNext      = null,
                rayTracing = true,
            };

            VkPhysicalDeviceVulkan12Features deviceVulkan12Features = new VkPhysicalDeviceVulkan12Features()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
                pNext = &deviceRayTracingFeatures,
                bufferDeviceAddress = true,
            };

            int     deviceExtensionsCount = deviceExtensions.Length;
            IntPtr *deviceExtensionsArray = stackalloc IntPtr[deviceExtensionsCount];

            for (int i = 0; i < deviceExtensionsCount; i++)
            {
                string extension = deviceExtensions[i];
                deviceExtensionsArray[i] = Marshal.StringToHGlobalAnsi(extension);
            }

            VkDeviceCreateInfo createInfo = new VkDeviceCreateInfo();

            createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
            createInfo.pNext = &deviceVulkan12Features;

            VkDeviceQueueCreateInfo[] queueCreateInfosArray = queueCreateInfos.ToArray();
            fixed(VkDeviceQueueCreateInfo *queueCreateInfosArrayPtr = &queueCreateInfosArray[0])
            {
                createInfo.queueCreateInfoCount = (uint)queueCreateInfos.Count;
                createInfo.pQueueCreateInfos    = queueCreateInfosArrayPtr;
            }

            createInfo.pEnabledFeatures        = &deviceFeatures;
            createInfo.enabledExtensionCount   = (uint)deviceExtensions.Length;
            createInfo.ppEnabledExtensionNames = (byte **)deviceExtensionsArray;

            fixed(VkDevice *devicePtr = &device)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateDevice(physicalDevice, &createInfo, null, devicePtr));
            }

            fixed(VkQueue *graphicsQueuePtr = &graphicsQueue)
            {
                VulkanNative.vkGetDeviceQueue(device, indices.graphicsFamily.Value, 0, graphicsQueuePtr);
            }

            fixed(VkQueue *presentQueuePtr = &presentQueue)
            {
                VulkanNative.vkGetDeviceQueue(device, indices.presentFamily.Value, 0, presentQueuePtr); // TODO queue index 0 ?¿?¿
            }
        }
        private void CreateSwapChain()
        {
            // Create SwapChain
            SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice);

            VkSurfaceFormatKHR surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = this.ChooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = this.ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.minImageCount + 1;

            if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
            {
                imageCount = swapChainSupport.capabilities.maxImageCount;
            }

            VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR();

            createInfo.sType            = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
            createInfo.surface          = surface;
            createInfo.minImageCount    = imageCount;
            createInfo.imageFormat      = surfaceFormat.format;
            createInfo.imageColorSpace  = surfaceFormat.colorSpace;
            createInfo.imageExtent      = extent;
            createInfo.imageArrayLayers = 1;
            createInfo.imageUsage       = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            QueueFamilyIndices indices = this.FindQueueFamilies(this.physicalDevice);
            uint *queueFamilyIndices   = stackalloc uint[] { indices.graphicsFamily.Value, indices.presentFamily.Value };

            if (indices.graphicsFamily != indices.presentFamily)
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.queueFamilyIndexCount = 2;
                createInfo.pQueueFamilyIndices   = queueFamilyIndices;
            }
            else
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
                createInfo.queueFamilyIndexCount = 0;    //Optional
                createInfo.pQueueFamilyIndices   = null; //Optional
            }
            createInfo.preTransform   = swapChainSupport.capabilities.currentTransform;
            createInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
            createInfo.presentMode    = presentMode;
            createInfo.clipped        = true;
            createInfo.oldSwapchain   = 0;

            fixed(VkSwapchainKHR *swapChainPtr = &swapChain)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateSwapchainKHR(device, &createInfo, null, swapChainPtr));
            }

            // SwapChain Images
            VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, null);
            this.swapChainImages = new VkImage[imageCount];
            fixed(VkImage *swapChainImagesPtr = &this.swapChainImages[0])
            {
                VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImagesPtr);
            }

            this.swapChainImageFormat = surfaceFormat.format;
            this.swapChainExtent      = extent;
        }
Example #22
0
        private bool IsDeviceSuitable(PhysicalDevice device, out QueueFamilyIndices indices)
        {
            FindQueueFamilies(device, out indices);

            return(indices.IsComplete() && HasAllRequiredExtensions(device) && IsSwapchainSupportAdequate(device));
        }