private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            var queueCreateInfos = new DeviceQueueCreateInfo[]
            {
                new DeviceQueueCreateInfo()
                {
                    QueueFamilyIndex = (uint)indices.GraphicsFamily,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f },
                }
            };

            var createInfo = new DeviceCreateInfo()
            {
                EnabledExtensionNames = new string[] { "VK_KHR_swapchain" },
                QueueCreateInfos      = queueCreateInfos,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
            };

            vkDevice = vkPhysicalDevice.CreateDevice(createInfo);

            vkGraphicsQueue = vkDevice.GetQueue((uint)indices.GraphicsFamily, 0);
            vkPresentQueue  = vkDevice.GetQueue((uint)indices.PresentFamily, 0);
        }
        private void CreateCommandPool()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            var poolInfo = new CommandPoolCreateInfo()
            {
                QueueFamilyIndex = (uint)indices.GraphicsFamily,
                Flags            = 0,
            };

            vkCommandPool = vkDevice.CreateCommandPool(poolInfo);
        }
        private void CreateSwapChain()
        {
            var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface);

            SurfaceFormatKhr surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats);
            PresentModeKhr   presentMode   = ChooseSwapPresentMode(swapChainSupport.presentModes);
            Extent2D         extent        = ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.MinImageCount + 1;

            if (swapChainSupport.capabilities.MaxImageCount > 0)
            {
                imageCount = Math.Min(imageCount, swapChainSupport.capabilities.MaxImageCount);
            }

            var createInfo = new SwapchainCreateInfoKhr()
            {
                MinImageCount    = imageCount,
                ImageFormat      = surfaceFormat.Format,
                ImageColorSpace  = surfaceFormat.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ColorAttachment,
                PreTransform     = swapChainSupport.capabilities.CurrentTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                PresentMode      = presentMode,
                Surface          = vkSurface,
            };

            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            if (indices.GraphicsFamily != indices.PresentFamily)
            {
                createInfo.ImageSharingMode   = SharingMode.Concurrent;
                createInfo.QueueFamilyIndices = new[]
                {
                    (uint)indices.GraphicsFamily,
                    (uint)indices.PresentFamily,
                };
            }
            else
            {
                createInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            vkSwapChain            = vkDevice.CreateSwapchainKHR(createInfo);
            vkSwapChainImages      = vkDevice.GetSwapchainImagesKHR(vkSwapChain);
            vkSwapChainImageFormat = surfaceFormat.Format;
            vkSwapChainExtent      = extent;
        }