Example #1
0
 public unsafe Swapchain[] CreateSharedSwapchains(SwapchainCreateInfo[] createInfos, AllocationCallbacks allocator)
 {
     var swapchains = new Swapchain[createInfos.Length];
     fixed (SwapchainCreateInfo* __createInfos__ = &createInfos[0])
     fixed (Swapchain* __swapchains__ = &swapchains[0])
     {
         vkCreateSharedSwapchainsKHR(this, (uint)createInfos.Length, __createInfos__, &allocator, __swapchains__).CheckError();
     }
     return swapchains;
 }
        private unsafe void CreateSwapChain()
        {
            var formats = new[] { PixelFormat.B8G8R8A8_UNorm_SRgb, PixelFormat.R8G8B8A8_UNorm_SRgb, PixelFormat.B8G8R8A8_UNorm, PixelFormat.R8G8B8A8_UNorm };

            foreach (var format in formats)
            {
                var nativeFromat = VulkanConvertExtensions.ConvertPixelFormat(format);

                FormatProperties formatProperties;
                GraphicsDevice.NativePhysicalDevice.GetFormatProperties(nativeFromat, out formatProperties);

                if ((formatProperties.OptimalTilingFeatures & FormatFeatureFlags.ColorAttachment) != 0)
                {
                    Description.BackBufferFormat = format;
                    break;
                }
            }

            // Queue
            // TODO VULKAN: Queue family is needed when creating the Device, so here we can just do a sanity check?
            var queueNodeIndex = GraphicsDevice.NativePhysicalDevice.QueueFamilyProperties.
                Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && GraphicsDevice.NativePhysicalDevice.GetSurfaceSupport((uint)index, surface)).
                Select((properties, index) => index).First();

            // Surface format
            var backBufferFormat = VulkanConvertExtensions.ConvertPixelFormat(Description.BackBufferFormat);

            var surfaceFormats = GraphicsDevice.NativePhysicalDevice.GetSurfaceFormats(surface);
            if ((surfaceFormats.Length != 1 || surfaceFormats[0].Format != Format.Undefined) &&
                !surfaceFormats.Any(x => x.Format == backBufferFormat))
            {
                backBufferFormat = surfaceFormats[0].Format;
            }

            // Create swapchain
            SurfaceCapabilities surfaceCapabilities;
            GraphicsDevice.NativePhysicalDevice.GetSurfaceCapabilities(surface, out surfaceCapabilities);

            // Buffer count
            uint desiredImageCount = Math.Max(surfaceCapabilities.MinImageCount, 2);
            if (surfaceCapabilities.MaxImageCount > 0 && desiredImageCount > surfaceCapabilities.MaxImageCount)
            {
                desiredImageCount = surfaceCapabilities.MaxImageCount;
            }

            // Transform
            SurfaceTransformFlags preTransform;
            if ((surfaceCapabilities.SupportedTransforms & SurfaceTransformFlags.Identity) != 0)
            {
                preTransform = SurfaceTransformFlags.Identity;
            }
            else
            {
                preTransform = surfaceCapabilities.CurrentTransform;
            }

            // Find present mode
            var presentModes = GraphicsDevice.NativePhysicalDevice.GetSurfacePresentModes(surface);
            var swapChainPresentMode = PresentMode.Fifo; // Always supported
            foreach (var presentMode in presentModes)
            {
                // TODO VULKAN: Handle PresentInterval.Two
                if (Description.PresentationInterval == PresentInterval.Immediate)
                {
                    // Prefer mailbox to immediate
                    if (presentMode == PresentMode.Immediate)
                    {
                        swapChainPresentMode = PresentMode.Immediate;
                    }
                    else if (presentMode == PresentMode.Mailbox)
                    {
                        swapChainPresentMode = PresentMode.Mailbox;
                        break;
                    }
                }
            }

            // Create swapchain
            var swapchainCreateInfo = new SwapchainCreateInfo
            {
                StructureType = StructureType.SwapchainCreateInfo,
                Surface = surface,
                ImageArrayLayers = 1,
                ImageSharingMode = SharingMode.Exclusive,
                ImageExtent = new Extent2D((uint)Description.BackBufferWidth, (uint)Description.BackBufferHeight),
                ImageFormat = backBufferFormat,
                ImageColorSpace = Description.ColorSpace == ColorSpace.Gamma ? SharpVulkan.ColorSpace.SRgbNonlinear : 0,
                ImageUsage = ImageUsageFlags.ColorAttachment | (surfaceCapabilities.SupportedUsageFlags & ImageUsageFlags.TransferSource), // TODO VULKAN: Use off-screen buffer to emulate
                PresentMode = swapChainPresentMode,
                CompositeAlpha = CompositeAlphaFlags.Opaque,
                MinImageCount = desiredImageCount,
                PreTransform = preTransform,
                OldSwapchain = swapChain,
                Clipped = true
            };
            var newSwapChain = GraphicsDevice.NativeDevice.CreateSwapchain(ref swapchainCreateInfo);

            DestroySwapchain();

            swapChain = newSwapChain;
            CreateBackBuffers();
        }
Example #3
0
        protected virtual void CreateSwapchain()
        {
            // surface format
            var surfaceFormats = physicalDevice.GetSurfaceFormats(surface);
            if (surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined)
            {
                backBufferFormat = Format.B8G8R8A8UNorm;
            }
            else
            {
                backBufferFormat = surfaceFormats[0].Format;
            }

            SurfaceCapabilities surfaceCapabilities;
            physicalDevice.GetSurfaceCapabilities(surface, out surfaceCapabilities);

            // Buffer count
            uint desiredImageCount = surfaceCapabilities.MinImageCount + 1;
            if (surfaceCapabilities.MaxImageCount > 0 && desiredImageCount > surfaceCapabilities.MaxImageCount)
            {
                desiredImageCount = surfaceCapabilities.MaxImageCount;
            }

            // Transform
            SurfaceTransformFlags preTransform;
            if ((surfaceCapabilities.SupportedTransforms & SurfaceTransformFlags.Identity) != 0)
            {
                preTransform = SurfaceTransformFlags.Identity;
            }
            else
            {
                preTransform = surfaceCapabilities.CurrentTransform;
            }

            // Present mode
            var presentModes = physicalDevice.GetSurfacePresentModes(surface);

            var swapChainPresentMode = PresentMode.Fifo;
            if (presentModes.Contains(PresentMode.Mailbox))
                swapChainPresentMode = PresentMode.Mailbox;
            else if (presentModes.Contains(PresentMode.Immediate))
                swapChainPresentMode = PresentMode.Immediate;

            // Create swapchain
            var swapchainCreateInfo = new SwapchainCreateInfo
            {
                StructureType = StructureType.SwapchainCreateInfo,
                Surface = surface,
                ImageSharingMode = SharingMode.Exclusive,
                ImageExtent = new Extent2D((uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
                ImageArrayLayers = 1,
                ImageFormat = backBufferFormat,
                ImageColorSpace = ColorSpace.SRgbNonlinear,
                ImageUsage = ImageUsageFlags.ColorAttachment,
                PresentMode = swapChainPresentMode,
                CompositeAlpha = CompositeAlphaFlags.Opaque,
                MinImageCount = desiredImageCount,
                PreTransform = preTransform,
                Clipped = true
                // OldSwapchain =
            };
            swapchain = device.CreateSwapchain(ref swapchainCreateInfo);

            // Initialize swapchain image layout
            backBuffers = device.GetSwapchainImages(swapchain);
            foreach (var image in backBuffers)
            {
                SetImageLayout(image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSource);
            }
            Flush();
        }
Example #4
0
 public unsafe Swapchain CreateSwapchain(ref SwapchainCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     Swapchain swapchain;
     fixed (SwapchainCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateSwapchainKHR(this, __createInfo__, allocator, &swapchain).CheckError();
     }
     return swapchain;
 }
Example #5
0
 internal static unsafe extern Result vkCreateSwapchainKHR(Device device, SwapchainCreateInfo* createInfo, AllocationCallbacks* allocator, Swapchain* swapchain);
Example #6
0
 internal static unsafe extern Result vkCreateSharedSwapchainsKHR(Device device, uint swapchainCount, SwapchainCreateInfo* createInfos, AllocationCallbacks* allocator, Swapchain* swapchains);