Exemplo n.º 1
0
        private void CreateSwapchain(uint width, uint height)
        {
            _currentImageIndex = 0;
            uint surfaceFormatCount = 0;

            vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, null);
            VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[surfaceFormatCount];
            vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, out formats[0]);

            VkSurfaceFormatKHR surfaceFormat = new VkSurfaceFormatKHR();

            if (formats.Length == 1 && formats[0].format == VkFormat.Undefined)
            {
                surfaceFormat = new VkSurfaceFormatKHR {
                    colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.B8g8r8a8Unorm
                };
            }
            else
            {
                foreach (VkSurfaceFormatKHR format in formats)
                {
                    if (format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR && format.format == VkFormat.B8g8r8a8Unorm)
                    {
                        surfaceFormat = format;
                        break;
                    }
                }
                if (surfaceFormat.format == VkFormat.Undefined)
                {
                    surfaceFormat = formats[0];
                }
            }

            uint presentModeCount = 0;

            vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, null);
            VkPresentModeKHR[] presentModes = new VkPresentModeKHR[presentModeCount];
            vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, out presentModes[0]);

            VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR;

            if (presentModes.Contains(VkPresentModeKHR.MailboxKHR))
            {
                presentMode = VkPresentModeKHR.MailboxKHR;
            }
            else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR))
            {
                presentMode = VkPresentModeKHR.ImmediateKHR;
            }

            vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_gd.PhysicalDevice, _surface, out VkSurfaceCapabilitiesKHR surfaceCapabilities);
            uint imageCount = surfaceCapabilities.minImageCount + 1;

            VkSwapchainCreateInfoKHR swapchainCI = VkSwapchainCreateInfoKHR.New();

            swapchainCI.surface         = _surface;
            swapchainCI.presentMode     = presentMode;
            swapchainCI.imageFormat     = surfaceFormat.format;
            swapchainCI.imageColorSpace = surfaceFormat.colorSpace;
            swapchainCI.imageExtent     = new VkExtent2D {
                width = (uint)width, height = (uint)height
            };
            swapchainCI.minImageCount    = imageCount;
            swapchainCI.imageArrayLayers = 1;
            swapchainCI.imageUsage       = VkImageUsageFlags.ColorAttachment;

            FixedArray2 <uint> queueFamilyIndices = new FixedArray2 <uint>(_gd.GraphicsQueueIndex, _gd.PresentQueueIndex);

            if (_gd.GraphicsQueueIndex != _gd.PresentQueueIndex)
            {
                swapchainCI.imageSharingMode      = VkSharingMode.Concurrent;
                swapchainCI.queueFamilyIndexCount = 2;
                swapchainCI.pQueueFamilyIndices   = &queueFamilyIndices.First;
            }
            else
            {
                swapchainCI.imageSharingMode      = VkSharingMode.Exclusive;
                swapchainCI.queueFamilyIndexCount = 0;
            }

            swapchainCI.preTransform   = surfaceCapabilities.currentTransform;
            swapchainCI.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR;
            swapchainCI.clipped        = true;

            VkSwapchainKHR oldSwapchain = _swapchain;

            swapchainCI.oldSwapchain = oldSwapchain;

            VkResult result = vkCreateSwapchainKHR(_gd.Device, ref swapchainCI, null, out _swapchain);

            CheckResult(result);
            if (oldSwapchain != VkSwapchainKHR.Null)
            {
                vkDestroySwapchainKHR(_gd.Device, oldSwapchain, null);
            }

            // Get the images
            uint scImageCount = 0;

            result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, null);
            CheckResult(result);
            if (_scImages == null)
            {
                _scImages = new VkImage[(int)scImageCount];
            }
            result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, out _scImages[0]);
            CheckResult(result);

            _scImageFormat = surfaceFormat.format;
            _scExtent      = swapchainCI.imageExtent;

            CreateDepthTexture();
            CreateFramebuffers();
        }
Exemplo n.º 2
0
        private VkSwapchainKHR CreateSwapchain()
        {
            VkSurfaceCapabilitiesKHR capabilities;

            vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Context.PhysicalDevice, Surface, out capabilities).CheckResult();

            uint count;

            vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, null);

            VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[(int)count];

            fixed(VkSurfaceFormatKHR *formatsPtr = formats)
            vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, formatsPtr).CheckResult();

            vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, null).CheckResult();

            VkPresentModeKHR[] presentModes = new VkPresentModeKHR[count];

            fixed(VkPresentModeKHR *presentModesPtr = presentModes)
            vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, presentModesPtr).CheckResult();

            VkFormat format = formats.Length == 1 && formats[0].format == VkFormat.Undefined
                ? VkFormat.B8G8R8A8UNorm
                : formats[0].format;
            VkPresentModeKHR presentMode =
                presentModes.Contains(VkPresentModeKHR.Mailbox) ? VkPresentModeKHR.Mailbox :
                presentModes.Contains(VkPresentModeKHR.FifoRelaxed) ? VkPresentModeKHR.FifoRelaxed :
                presentModes.Contains(VkPresentModeKHR.Fifo) ? VkPresentModeKHR.Fifo :
                VkPresentModeKHR.Immediate;

            SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(Context.PhysicalDevice, Surface);
            VkSurfaceFormatKHR      surfaceFormat    = ChooseSwapSurfaceFormat(swapChainSupport.Formats);

            uint imageCount = swapChainSupport.Capabilities.minImageCount + 1;

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

            SwapchainFormat = format;

            VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR()
            {
                sType                 = VkStructureType.SwapchainCreateInfoKHR,
                pNext                 = null,
                surface               = Surface,
                minImageCount         = imageCount,
                imageFormat           = format,
                imageColorSpace       = surfaceFormat.colorSpace,
                imageExtent           = capabilities.currentExtent,
                imageUsage            = VkImageUsageFlags.ColorAttachment,
                preTransform          = capabilities.currentTransform,
                imageArrayLayers      = 1,
                imageSharingMode      = VkSharingMode.Exclusive,
                queueFamilyIndexCount = 0,
                pQueueFamilyIndices   = null,
                presentMode           = presentMode,

                //oldSwapchain = SwapChain,

                // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area
                clipped        = true,
                compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque,
            };
            VkSwapchainKHR SwapChain;

            vkCreateSwapchainKHR(Context.Device, &swapchainCI, null, out SwapChain).CheckResult();

            return(SwapChain);
        }