void CreateSwapchain()
        {
            var support = GetSwapchainSupport(physicalDevice);
            var cap     = support.cap;

            var surfaceFormat = ChooseSwapSurfaceFormat(support.formats);
            var mode          = ChooseSwapPresentMode(support.modes);
            var extent        = ChooseSwapExtent(ref cap);

            int imageCount = cap.minImageCount + 1;

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

            var oldSwapchain = swapchain;
            var info         = new VkSwapchainCreateInfo();

            info.surface          = surface;
            info.oldSwapchain     = oldSwapchain;
            info.minImageCount    = imageCount;
            info.imageFormat      = surfaceFormat.format;
            info.imageColorSpace  = surfaceFormat.colorSpace;
            info.imageExtent      = extent;
            info.imageArrayLayers = 1;
            info.imageUsage       = VkImageUsageFlags.ColorAttachmentBit;

            var queueFamilyIndices = new List <int> {
                graphicsIndex, presentIndex
            };

            if (graphicsIndex != presentIndex)
            {
                info.imageSharingMode   = VkSharingMode.Concurrent;
                info.queueFamilyIndices = queueFamilyIndices;
            }
            else
            {
                info.imageSharingMode = VkSharingMode.Exclusive;
            }

            info.preTransform   = cap.currentTransform;
            info.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueBitKhr;
            info.presentMode    = mode;
            info.clipped        = true;

            swapchain = new VkSwapchain(device, info);
            oldSwapchain?.Dispose();

            swapchainImages = new List <VkImage>(swapchain.Images);

            swapchainImageFormat = surfaceFormat.format;
            swapchainExtent      = extent;
        }
Exemple #2
0
        private SwapchainKHR CreateSwapchain(out Extent2D extent, out Format swapImageFormat, out SwapchainImage[] swapImages)
        {
            QuerySwapchainSupport(this.PhysicalDevice, out var details);

            var surfaceFormat = ChooseSwapSurfaceFormat(details.Formats);
            var presentMode   = ChooseSwapPresentMode(details.PresentModes);

            extent = ChooseSwapExtent(details.Capabilities);

            var imageCount = details.Capabilities.MinImageCount + 1;

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

            var createInfo = new SwapchainCreateInfoKHR
            {
                SType            = StructureType.SwapchainCreateInfoKhr,
                Surface          = this.WindowSurface,
                MinImageCount    = imageCount,
                ImageFormat      = surfaceFormat.Format,
                ImageColorSpace  = surfaceFormat.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ImageUsageColorAttachmentBit
            };

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                createInfo.ImageSharingMode      = SharingMode.Concurrent;
                createInfo.QueueFamilyIndexCount = 2;

                var indices = stackalloc uint[2] {
                    this.QueueIndices.GraphicsFamily.Value, this.QueueIndices.PresentFamily.Value
                };

                createInfo.PQueueFamilyIndices = indices;
            }
            else
            {
                createInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            createInfo.PreTransform   = details.Capabilities.CurrentTransform;
            createInfo.CompositeAlpha = CompositeAlphaFlagsKHR.CompositeAlphaOpaqueBitKhr;
            createInfo.PresentMode    = presentMode;
            createInfo.Clipped        = true;

            createInfo.OldSwapchain = default;

            SwapchainKHR swapchain;

            var res = this.VkSwapchain.CreateSwapchain(Device, &createInfo, null, &swapchain);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to create swapchain!", res);
            }

            uint count = 0;

            res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, null);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res);
            }

            var images = stackalloc Image[(int)count];

            res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, images);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res);
            }

            var viewCreateInfo = new ImageViewCreateInfo
            {
                SType      = StructureType.ImageViewCreateInfo,
                ViewType   = ImageViewType.ImageViewType2D,
                Format     = surfaceFormat.Format,
                Components =
                {
                    R = ComponentSwizzle.Identity,
                    G = ComponentSwizzle.Identity,
                    B = ComponentSwizzle.Identity,
                    A = ComponentSwizzle.Identity
                },
                SubresourceRange =
                {
                    AspectMask     = ImageAspectFlags.ImageAspectColorBit,
                    BaseMipLevel   =                                    0,
                    LevelCount     =                                    1,
                    BaseArrayLayer =                                    0,
                    LayerCount     = 1
                }
            };

            var arr = new SwapchainImage[count];

            for (int i = 0; i < arr.Length; ++i)
            {
                viewCreateInfo.Image = images[i];

                ImageView view = default;
                res = VkApi.CreateImageView(this.Device, &viewCreateInfo, null, &view);

                if (res != Result.Success)
                {
                    throw new VMASharp.VulkanResultException("Swapchain image view creation failed!", res);
                }

                arr[i] = new SwapchainImage {
                    Image = images[i], View = view
                };
            }

            swapImageFormat = surfaceFormat.Format;
            swapImages      = arr;

            return(swapchain);
        }