Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure.
 /// </summary>
 /// <param name="surface">
 /// The <see cref="SurfaceKhr"/> that the swapchain will present images to.
 /// </param>
 /// <param name="imageExtent">
 /// The size (in pixels) of the swapchain.
 /// <para>
 /// Behavior is platform-dependent when the image extent does not match the surface's <see
 /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>.
 /// </para>
 /// </param>
 /// <param name="preTransform">
 /// A bitmask describing the transform, relative to the presentation engine's natural
 /// orientation, applied to the image content prior to presentation.
 /// <para>
 /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value
 /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the
 /// presentation engine will transform the image content as part of the presentation operation.
 /// </para>
 /// </param>
 /// <param name="imageUsage">
 /// A bitmask indicating how the application will use the swapchain's presentable images.
 /// </param>
 /// <param name="flags">A bitmask indicating parameters of swapchain creation.</param>
 /// <param name="minImageCount">
 /// The minimum number of presentable images that the application needs. The platform will
 /// either create the swapchain with at least that many images, or will fail to create the swapchain.
 /// </param>
 /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param>
 /// <param name="compositeAlpha">
 /// A bitmask indicating the alpha compositing mode to use when this surface is composited
 /// together with other surfaces on certain window systems.
 /// </param>
 /// <param name="imageArrayLayers">
 /// The number of views in a multiview/stereo surface. For non-stereoscopic-3D applications,
 /// this value is 1.
 /// </param>
 /// <param name="presentMode">
 /// The presentation mode the swapchain will use.
 /// <para>
 /// A swapchain's present mode determines how incoming present requests will be processed and
 /// queued internally.
 /// </para>
 /// </param>
 /// <param name="clipped">
 /// Indicates whether the Vulkan implementation is allowed to discard rendering operations
 /// that affect regions of the surface which are not visible.
 /// </param>
 /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param>
 public SwapchainCreateInfoKhr(
     SurfaceKhr surface,
     Format imageFormat,
     Extent2D imageExtent,
     SurfaceTransformsKhr preTransform,
     PresentModeKhr presentMode,
     SwapchainCreateFlagsKhr flags     = 0,
     int minImageCount                 = 2,
     ImageUsages imageUsage            = ImageUsages.ColorAttachment | ImageUsages.TransferDst,
     CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque,
     int imageArrayLayers              = 1,
     bool clipped = true,
     SwapchainKhr oldSwapchain = null)
 {
     Flags              = flags;
     Surface            = surface;
     ImageUsage         = imageUsage;
     MinImageCount      = minImageCount;
     ImageFormat        = imageFormat;
     ImageColorSpace    = 0;
     ImageExtent        = imageExtent;
     ImageArrayLayers   = imageArrayLayers;
     ImageSharingMode   = 0;
     QueueFamilyIndices = null;
     PreTransform       = preTransform;
     CompositeAlpha     = compositeAlpha;
     PresentMode        = presentMode;
     Clipped            = clipped;
     OldSwapchain       = oldSwapchain;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure.
 /// </summary>
 /// <param name="surface">
 /// The <see cref="SurfaceKhr"/> that the swapchain will present images to.
 /// </param>
 /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param>
 /// <param name="imageExtent">
 /// The size (in pixels) of the swapchain.
 /// <para>
 /// Behavior is platform-dependent when the image extent does not match the surface's <see
 /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>.
 /// </para>
 /// </param>
 /// <param name="minImageCount">
 /// The minimum number of presentable images that the application needs. The platform will
 /// either create the swapchain with at least that many images, or will fail to create the swapchain.
 /// </param>
 /// <param name="imageColorSpace">Color space value specifying the way the swapchain interprets image data.</param>
 /// <param name="imageArrayLayers">
 /// The number of views in a multiview/stereo surface.
 /// <para>For non-stereoscopic-3D applications, this value is 1.</para>
 /// </param>
 /// <param name="imageUsage">A bitmask describing the intended usage of the (acquired) swapchain images.</param>
 /// <param name="imageSharingMode">The sharing mode used for the image(s) of the swapchain.</param>
 /// <param name="queueFamilyIndices">
 /// Queue family indices having access to the image(s) of the swapchain when <see
 /// cref="ImageSharingMode"/> is <see cref="SharingMode.Concurrent"/>.
 /// </param>
 /// <param name="preTransform">
 /// A value describing the transform, relative to the presentation engine's natural
 /// orientation, applied to the image content prior to presentation.
 /// <para>
 /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value
 /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the
 /// presentation engine will transform the image content as part of the presentation operation.
 /// </para>
 /// </param>
 /// <param name="compositeAlpha">
 /// A bitmask indicating the alpha compositing mode to use when this surface is composited
 /// together with other surfaces on certain window systems.
 /// </param>
 /// <param name="presentMode">
 /// The presentation mode the swapchain will use.
 /// <para>
 /// A swapchain's present mode determines how incoming present requests will be processed and
 /// queued internally.
 /// </para>
 /// </param>
 /// <param name="clipped">
 /// Indicates whether the Vulkan implementation is allowed to discard rendering operations
 /// that affect regions of the surface which are not visible.</param>
 /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param>
 public SwapchainCreateInfoKhr(
     SurfaceKhr surface,
     Format imageFormat,
     Extent2D imageExtent,
     int minImageCount                 = 2,
     ColorSpaceKhr imageColorSpace     = ColorSpaceKhr.SRgbNonlinear,
     int imageArrayLayers              = 1,
     ImageUsages imageUsage            = ImageUsages.ColorAttachment | ImageUsages.TransferDst,
     SharingMode imageSharingMode      = SharingMode.Exclusive,
     int[] queueFamilyIndices          = null,
     SurfaceTransformsKhr preTransform = SurfaceTransformsKhr.Identity,
     CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque,
     PresentModeKhr presentMode        = PresentModeKhr.Fifo,
     bool clipped = true,
     SwapchainKhr oldSwapchain = null)
 {
     Flags              = SwapchainCreateFlagsKhr.None;
     Surface            = surface;
     MinImageCount      = minImageCount;
     ImageFormat        = imageFormat;
     ImageColorSpace    = imageColorSpace;
     ImageExtent        = imageExtent;
     ImageArrayLayers   = imageArrayLayers;
     ImageUsage         = imageUsage;
     ImageSharingMode   = imageSharingMode;
     QueueFamilyIndices = queueFamilyIndices;
     PreTransform       = preTransform;
     CompositeAlpha     = compositeAlpha;
     PresentMode        = presentMode;
     Clipped            = clipped;
     OldSwapchain       = oldSwapchain;
 }
Пример #3
0
        internal Window(
            string title,
            INativeWindow nativeWindow,
            SurfaceKhr surface,
            HostDevice hostDevice,
            HostDeviceRequirements deviceRequirements,
            Logger logger = null)
        {
            if (nativeWindow == null)
            {
                throw new ArgumentNullException(nameof(nativeWindow));
            }
            if (surface == null)
            {
                throw new ArgumentNullException(nameof(surface));
            }
            if (hostDevice == null)
            {
                throw new ArgumentNullException(nameof(hostDevice));
            }
            this.title        = title;
            this.nativeWindow = nativeWindow;
            this.surface      = surface;
            this.hostDevice   = hostDevice;
            this.logger       = logger;

            //Subscribe to callbacks for the native window
            nativeWindow.CloseRequested += OnNativeWindowCloseRequested;
            nativeWindow.Resized        += OnNativeWindowResized;

            //Create a logical device (and queues on the device)
            IList <string> enabledExtensions;

            (logicalDevice, graphicsQueue, presentQueue, enabledExtensions) = hostDevice.CreateLogicalDevice(
                surface: surface,
                deviceRequirements: deviceRequirements);
            hasDebugMarkerExtension = enabledExtensions.Contains("VK_EXT_debug_marker");
            if (hasDebugMarkerExtension)
            {
                logger?.Log(nameof(Window), "Enabled debug-markers");
            }

            //Get a presentmode to use
            presentMode = hostDevice.GetPresentMode(surface);
            //Get the surfaceformat to use
            (surfaceFormat, surfaceColorspace) = hostDevice.GetSurfaceFormat(surface);
            //Gets how many swapchain images we should use
            swapchainCount = hostDevice.GetSwapchainCount(surface);

            //Create a command-pool attached to this device
            commandPool = logicalDevice.CreateCommandPool(new CommandPoolCreateInfo(
                                                              queueFamilyIndex: graphicsQueue.FamilyIndex,
                                                              flags: CommandPoolCreateFlags.None
                                                              ));

            //Create the swapchain (images to present to the screen)
            CreateSwapchain(swapchainCount);
            //Synchronization objects are used to sync the rendering and presenting
            CreateSynchronizationObjects();
        }
Пример #4
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)));
        }
        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;
        }
        private PresentModeKhr ChooseSwapPresentMode(PresentModeKhr[] presentModes)
        {
            PresentModeKhr bestMode = PresentModeKhr.Fifo;

            foreach (var availablePresentMode in presentModes)
            {
                if (availablePresentMode == PresentModeKhr.Mailbox)
                {
                    return(availablePresentMode);
                }
                else if (availablePresentMode == PresentModeKhr.Immediate)
                {
                    bestMode = PresentModeKhr.Immediate;
                }
            }

            return(bestMode);
        }
Пример #7
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)));
        }
Пример #8
0
        public static bool TryCreateSwapChain(Instance instance, PhysicalDevice physicalDevice, Device device,
                                              SurfaceKhr surface, uint queue, ref System.Drawing.Size size,
                                              Format format, ColorSpaceKhr colorSpace, PresentModeKhr presentMode,
                                              ref SwapchainKhr swapchain)
        {
            SwapchainCreateInfoKhr swapChainCreateInfo = new SwapchainCreateInfoKhr
            {
                Surface            = surface,
                MinImageCount      = 2,
                ImageFormat        = format,
                ImageColorSpace    = colorSpace,
                ImageExtent        = ToExtent2D(size),
                ImageArrayLayers   = 1,
                ImageUsage         = ImageUsageFlags.ColorAttachment,
                ImageSharingMode   = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queue },
                PreTransform       = SurfaceTransformFlagsKhr.Inherit,
                CompositeAlpha     = CompositeAlphaFlagsKhr.Opaque, // TODO : set this to Ingerit if it can be fixed in Check
                PresentMode        = presentMode,
                Clipped            = false,
                OldSwapchain       = swapchain,
            };

            if (!CheckSwapchainCreateInfo(physicalDevice, swapChainCreateInfo, true))
            {
                return(false);
            }

            size.Width  = (int)swapChainCreateInfo.ImageExtent.Width;
            size.Height = (int)swapChainCreateInfo.ImageExtent.Height;

            SwapchainKhr newSwapchain = device.CreateSwapchainKHR(swapChainCreateInfo);

            if (newSwapchain != null)
            {
                swapchain = newSwapchain;
                return(true);
            }
            return(false);
        }
Пример #9
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,
                };
            }
        }
Пример #10
0
		public void Create(CommandBuffer commandBuffer) {
			var surfaceCapabilities = PhysicalDevice.GetSurfaceCapabilitiesKHR(Surface);
			Extent2D swapChainExtend = new Extent2D {
				Width = surfaceCapabilities.CurrentExtent.Width,
				Height = surfaceCapabilities.CurrentExtent.Height
			};

			var presentModes = PhysicalDevice.GetSurfacePresentModesKHR(Surface);
			PresentModeKhr presentMode = GetBestPresentMode(presentModes);

			var desiredImages = surfaceCapabilities.MinImageCount + 1;
			if (surfaceCapabilities.MaxImageCount > 0 && desiredImages > surfaceCapabilities.MaxImageCount) {
				desiredImages = surfaceCapabilities.MaxImageCount;
			}

			var preTransform = surfaceCapabilities.CurrentTransform;
			if (surfaceCapabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKhr.Identity)) {
				preTransform = SurfaceTransformFlagsKhr.Identity;
			}

			var oldSwapChain = Swapchain;
			var swapChainCreateInfo = new SwapchainCreateInfoKhr {
				Surface = Surface,
				MinImageCount = desiredImages,
				ImageFormat = ColorFormat,
				ImageColorSpace = ColorSpace,
				ImageExtent = swapChainExtend,
				ImageUsage = ImageUsageFlags.ColorAttachment,
				PreTransform = preTransform,
				ImageArrayLayers = 1,
				ImageSharingMode = SharingMode.Exclusive,
				QueueFamilyIndexCount = 0,
				QueueFamilyIndices = null,
				PresentMode = presentMode,
				Clipped = true,

				// Alpha on the window surface should be opaque:
				// If it was not we could create transparent regions of our window which
				// would require support from the Window compositor. You can totally do
				// that if you wanted though ;)
				CompositeAlpha = CompositeAlphaFlagsKhr.Opaque
			};
			Swapchain = Device.CreateSwapchainKHR(swapChainCreateInfo);

			if (oldSwapChain != null) {
				Device.DestroySwapchainKHR(oldSwapChain);
			}

			Images = Device.GetSwapchainImagesKHR(Swapchain).ToList();

			// Create the image views for the swap chain. They will all be single
			// layer, 2D images, with no mipmaps.
			// Check the VkImageViewCreateInfo structure to see other views you
			// can potentially create.
			for (var i = 0; i < Images.Count; i++) {
				var buffer = new SwapChainBuffer();

				var colorAttachmentView = new ImageViewCreateInfo {
					Format = ColorFormat,
					Components = new ComponentMapping {
						R = ComponentSwizzle.R,
						G = ComponentSwizzle.G,
						B = ComponentSwizzle.B,
						A = ComponentSwizzle.A
					},
					SubresourceRange = new ImageSubresourceRange {
						AspectMask = ImageAspectFlags.Color,
						BaseMipLevel = 0,
						LevelCount = 1,
						BaseArrayLayer = 0,
						LayerCount = 1
					},
					ViewType = ImageViewType.View2D
				};
				buffer.Image = Images[i];
				SetImageLayout(commandBuffer, buffer.Image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSrcKhr);
				buffer.View = Device.CreateImageView(colorAttachmentView);
				Buffers.Add(buffer);
			}
		}