예제 #1
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);
        }
        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;
        }
예제 #3
0
        protected void CreateSwapChain()
        {
            format = ChooseFormat(data.formats);
            var presentMode = ChoosePresentMode(data.presentModes);

            extent = ChooseSwapExtent();

            var imageCount = data.surfaceCapabilities.MinImageCount + 1;

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

            var swapChainInfo = new SwapchainCreateInfoKhr
            {
                Surface          = data.surface,
                MinImageCount    = imageCount,
                ImageFormat      = format.Format,
                ImageColorSpace  = format.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ColorAttachment,
                PreTransform     = data.surfaceCapabilities.CurrentTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                PresentMode      = presentMode,
                Clipped          = true
            };
            var indices            = data.queueFamilyIndices;
            var queueFamilyIndices = new uint[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily };

            if (indices.PresentFamily != indices.GraphicsFamily)
            {
                swapChainInfo.ImageSharingMode      = SharingMode.Concurrent;
                swapChainInfo.QueueFamilyIndexCount = (uint)queueFamilyIndices.Length;
                swapChainInfo.QueueFamilyIndices    = queueFamilyIndices;
            }
            else
            {
                swapChainInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            swapchain = device.CreateSwapchainKHR(swapChainInfo);

            images     = device.GetSwapchainImagesKHR(swapchain);
            bufferSize = imageCount;
        }
예제 #4
0
        SwapchainKhr CreateSwapchain(SurfaceKhr surface, 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));
        }
예제 #5
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);
        }
예제 #6
0
 /// <summary>
 /// Create a swapchain.
 /// </summary>
 /// <param name="device">The device to create the swapchain for.</param>
 /// <param name="createInfo">The structure specifying the parameters of the created swapchain.</param>
 /// <param name="allocator">
 /// The allocator used for host memory allocated for the swapchain object when there is no
 /// more specific allocator available.
 /// </param>
 /// <returns>Created swapchain object.</returns>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public static SwapchainKhr CreateSwapchainKhr(this Device device, SwapchainCreateInfoKhr createInfo,
                                               AllocationCallbacks?allocator = null)
 {
     return(new SwapchainKhr(device, ref createInfo, ref allocator));
 }
예제 #7
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}
}}");
        }
예제 #8
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);
        }
예제 #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);
			}
		}