Exemplo n.º 1
0
        internal static SwapchainKhr CreateSwapchain(Context ctx)
        {
            // Get the window surface capabilities
            SurfaceCapabilitiesKhr capabilities = ctx.PhysicalDevice.GetSurfaceCapabilitiesKhr(ctx.Surface);

            // Get the window surface's supported formats
            SurfaceFormatKhr[] formats = ctx.PhysicalDevice.GetSurfaceFormatsKhr(ctx.Surface);
            // Get the window surface's supported present modes
            PresentModeKhr[] presentModes = ctx.PhysicalDevice.GetSurfacePresentModesKhr(ctx.Surface);
            // If the only format available is undedined then pick 32 bit BGRA
            Format format = formats.Length == 1 && formats[0].Format == Format.Undefined
                ? Format.B8G8R8A8UNorm
                : formats[0].Format;
            // Pick a present mode, preferring mailbox
            PresentModeKhr presentMode =
                presentModes.Contains(PresentModeKhr.Mailbox) ? PresentModeKhr.Mailbox :
                presentModes.Contains(PresentModeKhr.FifoRelaxed) ? PresentModeKhr.FifoRelaxed :
                presentModes.Contains(PresentModeKhr.Fifo) ? PresentModeKhr.Fifo :
                PresentModeKhr.Immediate;

            // Finally create a swapchain with the wanted settings
            return(ctx.Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr(
                                                     ctx.Surface,
                                                     format,
                                                     capabilities.CurrentExtent,
                                                     capabilities.CurrentTransform,
                                                     presentMode)));
        }
Exemplo n.º 2
0
        public static bool CheckSwapchainCreateInfo(PhysicalDevice physicalDevice, SwapchainCreateInfoKhr createInfo, bool fixExtend)
        {
            SurfaceKhr surface = createInfo.Surface;

            foreach (uint index in createInfo.QueueFamilyIndices)
            {
                if (!physicalDevice.GetSurfaceSupportKHR(index, surface))
                {
                    return(false);
                }
            }

            bool supportImageFormat = false;

            foreach (SurfaceFormatKhr suportedFormat in physicalDevice.GetSurfaceFormatsKHR(surface))
            {
                if (suportedFormat.Format == createInfo.ImageFormat &&
                    suportedFormat.ColorSpace == createInfo.ImageColorSpace)
                {
                    supportImageFormat = true;
                    break;
                }
            }
            if (!supportImageFormat)
            {
                return(false);
            }

            SurfaceCapabilitiesKhr capabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);

            if (fixExtend)
            {
                var extend = createInfo.ImageExtent;
                extend.Width           = Clamp(extend.Width, capabilities.MinImageExtent.Width, capabilities.MaxImageExtent.Width);
                extend.Height          = Clamp(extend.Height, capabilities.MinImageExtent.Height, capabilities.MaxImageExtent.Height);
                createInfo.ImageExtent = extend;
            }
            if (createInfo.PreTransform == SurfaceTransformFlagsKhr.Inherit)
            {
                createInfo.PreTransform = capabilities.CurrentTransform;
            }
            // TODO: Fix up CompositeAlpha if Inherit is set

            if (capabilities.MinImageCount <= createInfo.MinImageCount &&
                capabilities.MaxImageCount >= createInfo.MinImageCount &&
                capabilities.MaxImageArrayLayers <= createInfo.ImageArrayLayers &&
                ((capabilities.SupportedTransforms & createInfo.PreTransform) == createInfo.PreTransform) &&
                ((capabilities.SupportedCompositeAlpha & createInfo.CompositeAlpha) == createInfo.CompositeAlpha) &&
                ((capabilities.SupportedUsageFlags & createInfo.ImageUsage) == createInfo.ImageUsage) &&
                createInfo.ImageExtent.Width >= capabilities.MinImageExtent.Width &&
                createInfo.ImageExtent.Width <= capabilities.MaxImageExtent.Width &&
                createInfo.ImageExtent.Height >= capabilities.MinImageExtent.Height &&
                createInfo.ImageExtent.Height <= capabilities.MaxImageExtent.Height)
            {
                return(true);
            }
            return(false);
        }
Exemplo n.º 3
0
        private CommandBuffer[] CreateCommandBuffers(
            Image[] images,
            Framebuffer[] framebuffers,
            RenderPass renderPass,
            SurfaceCapabilitiesKhr surfaceCapabilities)
        {
            var createPoolInfo = new CommandPoolCreateInfo {
                Flags = CommandPoolCreateFlags.ResetCommandBuffer
            };
            var commandPool = _device.CreateCommandPool(createPoolInfo);
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo
            {
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = (uint)images.Length
            };
            var buffers = _device.AllocateCommandBuffers(commandBufferAllocateInfo);

            for (var i = 0; i < images.Length; i++)
            {
                var commandBufferBeginInfo = new CommandBufferBeginInfo();
                buffers[i].Begin(commandBufferBeginInfo);

                var renderPassBeginInfo = new RenderPassBeginInfo
                {
                    Framebuffer = framebuffers[i],
                    RenderPass  = renderPass,
                    ClearValues = new[]
                    {
                        new ClearValue
                        {
                            Color = new ClearColorValue(new[]
                            {
                                255f / RenderContext.ClearColor.R,
                                255f / RenderContext.ClearColor.G,
                                255f / RenderContext.ClearColor.B,
                                255f / RenderContext.ClearColor.A
                            })
                        }
                    },
                    RenderArea = new Rect2D {
                        Extent = surfaceCapabilities.CurrentExtent
                    }
                };
                buffers[i].CmdBeginRenderPass(renderPassBeginInfo, SubpassContents.Inline);

                RenderContext.FillCommandBuffer(buffers[i]);

                buffers[i].CmdEndRenderPass();
                buffers[i].End();
            }

            return(buffers);
        }
        private Extent2D ChooseSwapExtent(SurfaceCapabilitiesKhr capabilities)
        {
            if (capabilities.CurrentExtent.Width != uint.MaxValue)
            {
                return(capabilities.CurrentExtent);
            }

            return(new Extent2D()
            {
                Width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, (uint)this.width)),
                Height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, (uint)this.height)),
            });
        }
Exemplo n.º 5
0
        private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface)
        {
            var  queueFamilyProperties = physDev.GetQueueFamilyProperties();
            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new[] { 1.0f },
                QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_swapchain",
                },
                QueueCreateInfos = new[] { queueInfo }
            };

            _device = physDev.CreateDevice(deviceInfo);

            _queue = _device.GetQueue(0, 0);
            _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectSurfaceFormat(physDev, surface);

            _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat);
            _images       = _device.GetSwapchainImagesKHR(_swapchainKhr);
            _renderPass   = CreateRenderPass(surfaceFormat);
            _framebuffers = CreateFramebuffers(_images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            _fence = _device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore      = _device.CreateSemaphore(semaphoreInfo);
            _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities);
        }
        internal int GetSwapchainCount(SurfaceKhr surface)
        {
            SurfaceCapabilitiesKhr capabilities = GetCurrentCapabilities(surface);

            //1 more then min to support triple buffering
            int count = capabilities.MinImageCount + 1;

            //If the capabilities specify a max then clamp to that
            if (capabilities.MaxImageCount > 0)
            {
                count = IntUtils.Min(count, capabilities.MaxImageCount);
            }
            return(count);
        }
Exemplo n.º 7
0
        public void InitializeVulkan()
        {
            var devices = Instance.EnumeratePhysicalDevices();
            var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr {
                Window = aNativeWindow
            });
            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }
            };
            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };
            var physicalDevice = devices [0];

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain = CreateSwapchain(surface, surfaceFormat);
            var images = device.GetSwapchainImagesKHR(swapchain);

            renderPass = CreateRenderPass(surfaceFormat);

            var framebuffers = CreateFramebuffers(images, surfaceFormat);
            var vertexBuffer = CreateBuffer(physicalDevice, Logo.Vertices, BufferUsageFlags.VertexBuffer, typeof(float));
            var indexBuffer  = CreateBuffer(physicalDevice, Logo.Indexes, BufferUsageFlags.IndexBuffer, typeof(short));

            uniformBuffer       = CreateUniformBuffer(physicalDevice);
            descriptorSetLayout = CreateDescriptorSetLayout();
            var pipelines = CreatePipelines();

            descriptorSets = CreateDescriptorSets();
            UpdateDescriptorSets();

            commandBuffers = CreateCommandBuffers(images, framebuffers, pipelines [0], vertexBuffer, indexBuffer, (uint)Logo.Indexes.Length);
            var fenceInfo = new FenceCreateInfo();

            fences = new Fence [] { device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Exemplo n.º 8
0
        public virtual void Initialize(PhysicalDevice physicalDevice, SurfaceKhr surface)
        {
            var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();

            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physicalDevice.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }

                if (queueFamilyProperties [queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain    = CreateSwapchain(surface, surfaceFormat);
            images       = device.GetSwapchainImagesKHR(swapchain);
            renderPass   = CreateRenderPass(surfaceFormat);
            framebuffers = CreateFramebuffers(images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            fence = device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Exemplo n.º 9
0
        private Framebuffer [] CreateFramebuffers(
            Image[] images, SurfaceFormatKhr surfaceFormat, SurfaceCapabilitiesKhr surfaceCapabilities, RenderPass renderPass)
        {
            var displayViews = new ImageView[images.Length];

            for (int i = 0; i < images.Length; i++)
            {
                var viewCreateInfo = new ImageViewCreateInfo
                {
                    Image      = images [i],
                    ViewType   = ImageViewType.View2D,
                    Format     = surfaceFormat.Format,
                    Components = new ComponentMapping {
                        R = ComponentSwizzle.R,
                        G = ComponentSwizzle.G,
                        B = ComponentSwizzle.B,
                        A = ComponentSwizzle.A
                    },
                    SubresourceRange = new ImageSubresourceRange
                    {
                        AspectMask = ImageAspectFlags.Color,
                        LevelCount = 1,
                        LayerCount = 1
                    }
                };
                displayViews[i] = _device.CreateImageView(viewCreateInfo);
            }

            var framebuffers = new Framebuffer[images.Length];

            for (int i = 0; i < images.Length; i++)
            {
                var frameBufferCreateInfo = new FramebufferCreateInfo
                {
                    Layers      = 1,
                    RenderPass  = renderPass,
                    Attachments = new [] { displayViews [i] },
                    Width       = surfaceCapabilities.CurrentExtent.Width,
                    Height      = surfaceCapabilities.CurrentExtent.Height
                };
                framebuffers[i] = _device.CreateFramebuffer(frameBufferCreateInfo);
            }
            return(framebuffers);
        }
Exemplo n.º 10
0
        SwapchainKhr CreateSwapchain(SurfaceKhr surface, SurfaceCapabilitiesKhr surfaceCapabilities, SurfaceFormatKhr surfaceFormat)
        {
            var swapchainInfo = new SwapchainCreateInfoKhr {
                Surface            = surface,
                MinImageCount      = surfaceCapabilities.MinImageCount,
                ImageFormat        = surfaceFormat.Format,
                ImageColorSpace    = surfaceFormat.ColorSpace,
                ImageExtent        = surfaceCapabilities.CurrentExtent,
                ImageUsage         = ImageUsageFlags.ColorAttachment,
                PreTransform       = SurfaceTransformFlagsKhr.Identity,
                ImageArrayLayers   = 1,
                ImageSharingMode   = SharingMode.Exclusive,
                QueueFamilyIndices = new uint [] { 0 },
                PresentMode        = PresentModeKhr.Fifo,
                CompositeAlpha     = CompositeAlphaFlagsKhr.Inherit
            };

            return(device.CreateSwapchainKHR(swapchainInfo));
        }
Exemplo n.º 11
0
        private SwapchainKhr CreateSwapchain()
        {
            SurfaceCapabilitiesKhr capabilities = Context.PhysicalDevice.GetSurfaceCapabilitiesKhr(Surface);

            SurfaceFormatKhr[] formats      = Context.PhysicalDevice.GetSurfaceFormatsKhr(Surface);
            PresentModeKhr[]   presentModes = Context.PhysicalDevice.GetSurfacePresentModesKhr(Surface);
            Format             format       = formats.Length == 1 && formats[0].Format == Format.Undefined
                ? Format.B8G8R8A8UNorm
                : formats[0].Format;
            PresentModeKhr presentMode =
                presentModes.Contains(PresentModeKhr.Mailbox) ? PresentModeKhr.Mailbox :
                presentModes.Contains(PresentModeKhr.FifoRelaxed) ? PresentModeKhr.FifoRelaxed :
                presentModes.Contains(PresentModeKhr.Fifo) ? PresentModeKhr.Fifo :
                PresentModeKhr.Immediate;

            return(Context.Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr(
                                                         Surface,
                                                         format,
                                                         capabilities.CurrentExtent,
                                                         capabilities.CurrentTransform,
                                                         presentMode)));
        }
Exemplo n.º 12
0
        private static SwapchainKhr GetSwapchain(PhysicalDevice physicalDevice, SurfaceKhr surface, Device device, SurfaceCapabilitiesKhr surfaceInfo)
        {
            var format = physicalDevice.GetSurfaceFormatsKHR(surface).First();

            return(device.CreateSwapchainKHR(new SwapchainCreateInfoKhr
            {
                Surface = surface,
                MinImageCount = 2,
                ImageFormat = format.Format,
                ImageColorSpace = format.ColorSpace,
                ImageExtent = surfaceInfo.CurrentExtent,
                ImageArrayLayers = 1,
                ImageUsage = ImageUsageFlags.ColorAttachment | ImageUsageFlags.Sampled,
                ImageSharingMode = SharingMode.Exclusive,
                PreTransform = surfaceInfo.CurrentTransform,
                CompositeAlpha = CompositeAlphaFlagsKhr.Opaque,
                PresentMode = PresentModeKhr.Fifo,
                Clipped = true
            }));
        }
 public SwapChainSupportDetails(PhysicalDevice device, SurfaceKhr surface)
 {
     capabilities = device.GetSurfaceCapabilitiesKHR(surface);
     formats      = device.GetSurfaceFormatsKHR(surface);
     presentModes = device.GetSurfacePresentModesKHR(surface);
 }
Exemplo n.º 14
0
        private void CreateSwapchain(int swapchainCount)
        {
            SurfaceCapabilitiesKhr capabilities = hostDevice.GetCurrentCapabilities(surface);

            //Clamp the size to within the min and max extends reported by the surface capabilities
            swapchainSize = nativeWindow.ClientRect.Size.Clamp(
                new Int2(capabilities.MinImageExtent.Width, capabilities.MinImageExtent.Height),
                new Int2(capabilities.MaxImageExtent.Width, capabilities.MaxImageExtent.Height));

            //Gather info about the swapchain
            var createInfo = new SwapchainCreateInfoKhr
                             (
                surface: surface,
                minImageCount: swapchainCount,
                imageFormat: surfaceFormat,
                imageColorSpace: surfaceColorspace,
                imageExtent: new Extent2D(swapchainSize.X, swapchainSize.Y),
                imageArrayLayers: 1,
                imageUsage: ImageUsages.ColorAttachment,

                //If the graphics and present queues are different we need to allow sharing the
                //swapchain images
                imageSharingMode: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                SharingMode.Exclusive : SharingMode.Concurrent,
                queueFamilyIndices: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                null : new [] { graphicsQueue.FamilyIndex, presentQueue.FamilyIndex },

                preTransform: capabilities.CurrentTransform,
                compositeAlpha: CompositeAlphasKhr.Opaque,
                presentMode: presentMode,
                clipped: true
                             );

            //Create the swapchain
            swapchain = logicalDevice.CreateSwapchainKhr(createInfo);
            var swapchainImages = swapchain.GetImages();

            //Verify that we got the amount of images we expected
            if (swapchainImages.Length != swapchainCount)
            {
                throw new Exception(
                          $"[{nameof(Window)}] Incorrect number of swapchain images acquired, expected: {swapchainCount}, got: {swapchainImages.Length}");
            }

            //Create the image targets
            swapchainTextures = new DeviceTexture[swapchainCount];
            for (int i = 0; i < swapchainTextures.Length; i++)
            {
                swapchainTextures[i] = DeviceTexture.CreateSwapchainTarget(
                    swapchainSize, surfaceFormat, swapchainImages[i]);
            }

            logger?.Log(nameof(Window),
                        $@"Swapchain created:
{{
    size: {swapchainSize},
    texCount: {swapchainTextures.Length},
    mode: {presentMode},
    format: {surfaceFormat},
    colorSpace: {surfaceColorspace}
}}");
        }
Exemplo n.º 15
0
        public bool CreateSwapChain(DrunkSpock spock,
                                    int extentX, int extentY)
        {
            PhysicalDevice phys = mLogical.Parent;
            SurfaceKhr     surf = spock.GetSurface();

            SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf);

            SurfaceFormatKhr                [] surfFormats = phys.GetSurfaceFormatsKhr(surf);
            PresentModeKhr                  [] presModes   = phys.GetSurfacePresentModesKhr(surf);

            if (surfFormats.Length <= 0 || presModes.Length <= 0)
            {
                Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes...");
                return(false);
            }

            mSwapExtent = new Extent2D(extentX, extentY);

            int imageCount = surfCaps.MinImageCount + 1;

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

            SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr(
                surf, Format.B8G8R8A8UNorm, mSwapExtent,
                imageCount, ColorSpaceKhr.SRgbNonlinear, 1,
                ImageUsages.ColorAttachment);

            scci.ImageSharingMode = SharingMode.Exclusive;

            if (presModes.Contains(PresentModeKhr.Mailbox))
            {
                scci.PresentMode = PresentModeKhr.Mailbox;
            }

            mSwapChain = mLogical.CreateSwapchainKhr(scci);
            if (mSwapChain == null)
            {
                Misc.SafeInvoke(eErrorSpam, "Create swap chain failed...");
                return(false);
            }

            VulkanCore.Image        [] chainImages = mSwapChain.GetImages();

            mChainImageViews = new ImageView[chainImages.Length];

            for (int i = 0; i < chainImages.Length; i++)
            {
                ImageSubresourceRange isr = new ImageSubresourceRange(
                    ImageAspects.Color, 0, 1, 0, 1);

                ImageViewCreateInfo ivci = new ImageViewCreateInfo(
                    mSwapChain.Format, isr);

                mChainImageViews[i] = chainImages[i].CreateView(ivci);
            }

            //descriptor pool stuff
            DescriptorPoolSize dps = new DescriptorPoolSize(
                DescriptorType.UniformBuffer, chainImages.Length);

            DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo();

            dpci.PoolSizes = new DescriptorPoolSize[] { dps };
            dpci.MaxSets   = chainImages.Length;

            mDPool = mLogical.CreateDescriptorPool(dpci);

            return(true);
        }
Exemplo n.º 16
0
        public void CreateSwapChain(PresentModeKhr presentMode, uint imageCount)
        {
            SwapchainKhr oldSwapChain = SwapChain;

            if (SwapSurface == null)
            {
                // == Create Surface for Swap Chain
                IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module);

                Win32SurfaceCreateInfoKhr surfaceInfo = new Win32SurfaceCreateInfoKhr()
                {
                    Hwnd      = window.Handle,
                    Flags     = 0,
                    Hinstance = hInstance,
                };

                SurfaceKhr surface = Instance.CreateWin32SurfaceKHR(surfaceInfo, null);

                QueueInfo graphicsQueueInfo = GetQueue(QueueFlags.Graphics);
                Queue     graphicsQueue     = Device.GetQueue(graphicsQueueInfo.queueFamilyIndex, graphicsQueueInfo.queueIndex);

                SwapSurface = surface;
            }

            // == Create Swap Chain

            // TODO : this is bugged in Vulkan-Mono PresentModeKhr can not be called from Marshal.SizeOf

            /*bool presentModeSupported = false;
             * PresentModeKhr[] presentModes = Gpu.GetSurfacePresentModesKHR(SwapSurface);
             * foreach (PresentModeKhr checkMode in presentModes)
             * {
             *  if(checkMode == presentMode)
             *  {
             *      presentModeSupported = true;
             *      break;
             *  }
             * }
             * if(!presentModeSupported )
             * {
             *  throw new Exception("PresentMode :" + presentMode + " not supported by gpu.");
             * }*/

            SurfaceCapabilitiesKhr surfaceCapabilities = Gpu.GetSurfaceCapabilitiesKHR(SwapSurface);

            if (surfaceCapabilities.CurrentExtent.Width == uint.MaxValue)
            {
                BackBufferWidth  = (uint)window.Width;
                BackBufferHeight = (uint)window.Height;
            }
            else
            {
                BackBufferWidth  = surfaceCapabilities.CurrentExtent.Width;
                BackBufferHeight = surfaceCapabilities.CurrentExtent.Height;
            }

            uint reqImageCount = surfaceCapabilities.MinImageCount + imageCount;

            if (reqImageCount > 0 && reqImageCount > surfaceCapabilities.MaxImageCount)
            {
                reqImageCount = surfaceCapabilities.MaxImageCount;
            }


            SurfaceFormatKhr[] surfaceFormats = Gpu.GetSurfaceFormatsKHR(SwapSurface);
            Format             format         = surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined ?
                                                Format.B8g8r8a8Unorm : surfaceFormats[0].Format;
            SurfaceTransformFlagsKhr preTransform = (surfaceCapabilities.SupportedTransforms & SurfaceTransformFlagsKhr.Identity) == SurfaceTransformFlagsKhr.Identity ?
                                                    SurfaceTransformFlagsKhr.Identity : surfaceCapabilities.CurrentTransform;

            SwapchainCreateInfoKhr swapChainInfo = new SwapchainCreateInfoKhr
            {
                Surface         = SwapSurface,
                MinImageCount   = reqImageCount,
                ImageFormat     = format,
                ImageColorSpace = surfaceFormats[0].ColorSpace,
                ImageExtent     = new Extent2D
                {
                    Width  = BackBufferWidth,
                    Height = BackBufferHeight,
                },
                ImageUsage       = (uint)ImageUsageFlags.ColorAttachment,
                PreTransform     = preTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                ImageArrayLayers = 1,
                ImageSharingMode = SharingMode.Exclusive,
                PresentMode      = presentMode,
                // TODO : Vulkan : we cant assing a null swapChain
                //OldSwapchain = oldSwapChain != null ? oldSwapChain : null,
                Clipped = true,
            };

            if (oldSwapChain != null)
            {
                // this is a workaround as we cant assing a null one
                swapChainInfo.OldSwapchain = oldSwapChain;

                Device.DestroySwapchainKHR(oldSwapChain, null);
                oldSwapChain = null;
            }

            SwapchainKhr swapChain = Device.CreateSwapchainKHR(swapChainInfo, null);

            // ==  Create Images

            Image[] swapImages = Device.GetSwapchainImagesKHR(swapChain);

            SwapChainBuffer[] buffers = new SwapChainBuffer[swapImages.Length];
            for (uint i = 0; i < buffers.Length; i++)
            {
                ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo
                {
                    Format     = format,
                    Components = new ComponentMapping
                    {
                        R = ComponentSwizzle.R,
                        G = ComponentSwizzle.G,
                        B = ComponentSwizzle.B,
                        A = ComponentSwizzle.A,
                    },
                    SubresourceRange = new ImageSubresourceRange
                    {
                        AspectMask     = (uint)ImageAspectFlags.Color,
                        BaseMipLevel   = 1,
                        BaseArrayLayer = 0,
                        LayerCount     = 1,
                    },
                    ViewType = ImageViewType.View2D,
                    Flags    = 0,
                    Image    = swapImages[i],
                };

                ImageView view = Device.CreateImageView(imageViewInfo, null);

                buffers[i] = new SwapChainBuffer
                {
                    image = swapImages[i],
                    view  = view,
                };
            }
        }