Esempio n. 1
0
        protected VkSwapchainKHR CreateSwapchain(VkDevice device, VkSurfaceKHR surface,
                                                 VkSurfaceFormatKHR surfaceFormat, VkSurfaceCapabilitiesKHR surfaceCapabilities)
        {
            var compositeAlpha = surfaceCapabilities.supportedCompositeAlpha.HasFlag(
                VkCompositeAlphaFlagBitsKHR.InheritKHR)
                ? VkCompositeAlphaFlagBitsKHR.InheritKHR
                : VkCompositeAlphaFlagBitsKHR.OpaqueKHR;
            UInt32 index = 0;
            var    info  = new VkSwapchainCreateInfoKHR {
                sType = VkStructureType.SwapchainCreateInfoKHR
            };

            info.surface            = surface;
            info.minImageCount      = surfaceCapabilities.minImageCount;
            info.imageFormat        = surfaceFormat.format;
            info.imageColorSpace    = surfaceFormat.colorSpace;
            info.imageExtent        = surfaceCapabilities.currentExtent;
            info.imageUsage         = VkImageUsageFlagBits.ColorAttachment;
            info.preTransform       = VkSurfaceTransformFlagBitsKHR.IdentityKHR;
            info.imageArrayLayers   = 1;
            info.imageSharingMode   = VkSharingMode.Exclusive;
            info.queueFamilyIndices = index;
            info.presentMode        = VkPresentModeKHR.FifoKHR;
            info.compositeAlpha     = compositeAlpha;
            //return device.CreateSwapchainKHR(ref info, null);
            VkSwapchainKHR swapchain;

            vkAPI.vkCreateSwapchainKHR(device, &info, null, &swapchain).Check();

            return(swapchain);
        }
Esempio n. 2
0
        internal void SetNewSwapchain(
            VkSwapchainKHR deviceSwapchain,
            uint width,
            uint height,
            VkSurfaceFormatKHR surfaceFormat,
            VkExtent2D swapchainExtent)
        {
            _desiredWidth  = width;
            _desiredHeight = height;

            // Get the images
            uint     scImageCount = 0;
            VkResult result       = vkGetSwapchainImagesKHR(_gd.Device, deviceSwapchain, ref scImageCount, null);

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

            _scImageFormat = surfaceFormat.format;
            _scExtent      = swapchainExtent;

            CreateDepthTexture();
            CreateFramebuffers();

            _outputDescription = OutputDescription.CreateFromFramebuffer(this);
        }
Esempio n. 3
0
        static void GetSwapchainFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
        {
            uint formatCount = 0;

            vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, null);
            VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[formatCount];

            fixed(VkSurfaceFormatKHR *ptr = &formats[0])
            Assert(vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, ptr));



            for (int i = 0; i < formatCount; i++)
            {
                Console.WriteLine($"Format {formats[i].format} {formats[i].colorSpace} is available.");
                for (int k = 0; k < UNORM_FORMATS.Length; k++)
                {
                    if (formats[i].format == UNORM_FORMATS[k])
                    {
                        surfaceFormat = formats[i];
                        return;
                    }
                }
            }

            surfaceFormat = formats[0];//Fallback
        }
Esempio n. 4
0
        protected VkRenderPass CreateRenderPass(VkDevice device, VkSurfaceFormatKHR surfaceFormat)
        {
            var attDesc = new VkAttachmentDescription(surfaceFormat.format, VkSampleCountFlagBits._1,
                                                      VkAttachmentLoadOp.Clear, VkAttachmentStoreOp.Store,
                                                      VkAttachmentLoadOp.DontCare, VkAttachmentStoreOp.DontCare,
                                                      VkImageLayout.Undefined, VkImageLayout.PresentSrcKHR, 0);
            var subpassDesc = new VkSubpassDescription(VkPipelineBindPoint.Graphics);

            subpassDesc.colorAttachments = new VkAttachmentReference(VkImageLayout.ColorAttachmentOptimal, 0);
            var info = new VkRenderPassCreateInfo {
                sType = VkStructureType.RenderPassCreateInfo
            };

            info.attachments = attDesc;
            info.subpasses   = subpassDesc;

            //return device.CreateRenderPass(ref info);
            VkRenderPass renderPass;

            vkAPI.vkCreateRenderPass(device, &info, null, &renderPass).Check();

            info.Free();
            subpassDesc.Free();

            return(renderPass);
        }
Esempio n. 5
0
        public Swapchain(GraphicsDevice device, Window window)
        {
            Device = device;
            Window = window;

            SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(device.PhysicalDevice, device._surface);

            VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats);
            VkPresentModeKHR   presentMode   = ChooseSwapPresentMode(swapChainSupport.PresentModes);

            _extent = ChooseSwapExtent(swapChainSupport.Capabilities);

            CreateRenderPass(surfaceFormat.format);

            uint imageCount = swapChainSupport.Capabilities.minImageCount + 1;

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

            var createInfo = new VkSwapchainCreateInfoKHR
            {
                sType            = VkStructureType.SwapchainCreateInfoKHR,
                surface          = device._surface,
                minImageCount    = imageCount,
                imageFormat      = surfaceFormat.format,
                imageColorSpace  = surfaceFormat.colorSpace,
                imageExtent      = _extent,
                imageArrayLayers = 1,
                imageUsage       = VkImageUsageFlags.ColorAttachment,
                imageSharingMode = VkSharingMode.Exclusive,
                preTransform     = swapChainSupport.Capabilities.currentTransform,
                compositeAlpha   = VkCompositeAlphaFlagsKHR.Opaque,
                presentMode      = presentMode,
                clipped          = true,
                oldSwapchain     = VkSwapchainKHR.Null
            };

            vkCreateSwapchainKHR(device.VkDevice, &createInfo, null, out Handle).CheckResult();
            var swapChainImages = vkGetSwapchainImagesKHR(device.VkDevice, Handle);

            _swapChainImageViews = new VkImageView[swapChainImages.Length];
            _framebuffers        = new VkFramebuffer[swapChainImages.Length];

            for (var i = 0; i < swapChainImages.Length; i++)
            {
                var viewCreateInfo = new VkImageViewCreateInfo(
                    swapChainImages[i],
                    VkImageViewType.Image2D,
                    surfaceFormat.format,
                    VkComponentMapping.Identity,
                    new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1)
                    );

                vkCreateImageView(Device.VkDevice, &viewCreateInfo, null, out _swapChainImageViews[i]).CheckResult();
                vkCreateFramebuffer(Device.VkDevice, RenderPass, new[] { _swapChainImageViews[i] }, (uint)_extent.Width, (uint)_extent.Height, 1u, out _framebuffers[i]);
            }
        }
Esempio n. 6
0
        public SoftwareFormSurface(SoftwareInstance instance, VkWin32SurfaceCreateInfoKHR createInfo)
        {
            this.m_Formats = new List <VkSurfaceFormatKHR>()
            {
                VkSurfaceFormatKHR.Create(VkFormat.VK_FORMAT_B8G8R8A8_UNORM, VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
            };

            this.m_PresentModes = new List <VkPresentModeKHR>()
            {
                VkPresentModeKHR.VK_PRESENT_MODE_IMMEDIATE_KHR
            };

            this.m_instance   = instance;
            this.m_createInfo = createInfo;

            foreach (Form form in Application.OpenForms)
            {
                if (form.Handle == createInfo.hwnd)
                {
                    m_Form = form;
                }
            }

            if (m_Form == null)
            {
                throw new ArgumentException(string.Format("Form not found for the handle informed on the field {0}.{1}", nameof(VkWin32SurfaceCreateInfoKHR), nameof(VkWin32SurfaceCreateInfoKHR.hwnd)));
            }

            var m_OriginalExtents = VkExtent2D.Create(GetWidth(), GetHeight());

            m_CurrentSurfaceExtents = m_OriginalExtents;

            this.m_Capabilities = new VkSurfaceCapabilitiesKHR();

            this.m_Capabilities.currentExtent  = m_OriginalExtents;
            this.m_Capabilities.maxImageExtent = m_OriginalExtents;
            this.m_Capabilities.minImageExtent = m_OriginalExtents;

            this.m_Capabilities.minImageCount = 1;
            this.m_Capabilities.maxImageCount = 8;

            this.m_Capabilities.maxImageArrayLayers = 1;

            this.m_Capabilities.supportedTransforms = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
            this.m_Capabilities.currentTransform    = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;

            this.m_Capabilities.supportedCompositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

            this.m_Capabilities.supportedUsageFlags = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            this.m_SurfacePresentMode = FormSurfacePresentMode.DibBitmapBitBlt;

            InternalResize();

            m_Form.Resize += Form_Resize;
        }
Esempio n. 7
0
        public VkSurfaceFormatKHR [] GetSurfaceFormats(VkSurfaceKHR surf)
        {
            vkGetPhysicalDeviceSurfaceFormatsKHR(phy, surf, out uint count, IntPtr.Zero);
            VkSurfaceFormatKHR [] formats = new VkSurfaceFormatKHR [count];

            vkGetPhysicalDeviceSurfaceFormatsKHR(phy, surf, out count, formats.Pin());
            formats.Unpin();

            return(formats);
        }
Esempio n. 8
0
        protected VkFramebuffer[] CreateFramebuffers(VkDevice device, VkImage[] images,
                                                     VkSurfaceFormatKHR surfaceFormat, VkRenderPass renderPass,
                                                     VkSurfaceCapabilitiesKHR surfaceCapabilities)
        {
            var displayViews = new VkImageView[images.Length];
            var viewInfo     = new VkImageViewCreateInfo {
                sType = VkStructureType.ImageViewCreateInfo
            };

            viewInfo.viewType   = VkImageViewType._2d;
            viewInfo.format     = surfaceFormat.format;
            viewInfo.components = new VkComponentMapping {
                r = VkComponentSwizzle.R,
                g = VkComponentSwizzle.G,
                b = VkComponentSwizzle.B,
                a = VkComponentSwizzle.A
            };
            viewInfo.subresourceRange = new VkImageSubresourceRange {
                aspectMask = VkImageAspectFlagBits.Color,
                levelCount = 1,
                layerCount = 1
            };
            for (int i = 0; i < images.Length; i++)
            {
                viewInfo.image = images[i];
                //displayViews[i] = device.CreateImageView(ref info);
                VkImageView view;
                vkAPI.vkCreateImageView(device, &viewInfo, null, &view).Check();
                displayViews[i] = view;
            }

            var framebuffers = new VkFramebuffer[images.Length];
            var fbInfo       = new VkFramebufferCreateInfo {
                sType = VkStructureType.FramebufferCreateInfo
            };

            fbInfo.layers     = 1;
            fbInfo.renderPass = renderPass;
            fbInfo.width      = surfaceCapabilities.currentExtent.width;
            fbInfo.height     = surfaceCapabilities.currentExtent.height;
            for (int i = 0; i < images.Length; i++)
            {
                fbInfo.attachments = displayViews[i];
                //framebuffers[i] = device.CreateFramebuffer(ref info);
                VkFramebuffer framebuffer;
                vkAPI.vkCreateFramebuffer(device, &fbInfo, null, &framebuffer).Check();
                framebuffers[i] = framebuffer;
            }

            fbInfo.Free();

            return(framebuffers);
        }
Esempio n. 9
0
            private void CreateSwapchain()
            {
                SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(physicalDevice, surface);

                VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats);
                VkPresentModeKHR   presentMode   = ChooseSwapPresentMode(swapChainSupport.PresentModes);
                var extent = ChooseSwapExtent(swapChainSupport.Capabilities);

                uint imageCount = swapChainSupport.Capabilities.minImageCount + 1;

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

                var createInfo = new VkSwapchainCreateInfoKHR
                {
                    sType            = VkStructureType.SwapchainCreateInfoKHR,
                    surface          = surface,
                    minImageCount    = imageCount,
                    imageFormat      = surfaceFormat.format,
                    imageColorSpace  = surfaceFormat.colorSpace,
                    imageExtent      = extent,
                    imageArrayLayers = 1,
                    imageUsage       = VkImageUsageFlags.ColorAttachment,
                    imageSharingMode = VkSharingMode.Exclusive,
                    preTransform     = swapChainSupport.Capabilities.currentTransform,
                    compositeAlpha   = VkCompositeAlphaFlagsKHR.OpaqueKHR,
                    presentMode      = presentMode,
                    clipped          = true,
                    oldSwapchain     = VkSwapchainKHR.Null
                };

                vkCreateSwapchainKHR(device, &createInfo, null, out swapchain).CheckResult();
                var swapChainImages = vkGetSwapchainImagesKHR(device, swapchain);

                swapChainImageViews = new VkImageView[swapChainImages.Length];

                for (var i = 0; i < swapChainImages.Length; i++)
                {
                    var viewCreateInfo = new VkImageViewCreateInfo(
                        swapChainImages[i],
                        VkImageViewType.Image2D,
                        surfaceFormat.format,
                        VkComponentMapping.Identity,
                        new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1)
                        );

                    vkCreateImageView(device, &viewCreateInfo, null, out swapChainImageViews[i]).CheckResult();
                }
            }
Esempio n. 10
0
    public static ReadOnlySpan <VkSurfaceFormatKHR> vkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
    {
        int surfaceFormatCount = 0;

        vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, null).CheckResult();

        ReadOnlySpan <VkSurfaceFormatKHR> surfaceFormats = new VkSurfaceFormatKHR[surfaceFormatCount];

        fixed(VkSurfaceFormatKHR *surfaceFormatsPtr = surfaceFormats)
        {
            vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &surfaceFormatCount, surfaceFormatsPtr).CheckResult();
        }

        return(surfaceFormats);
    }
Esempio n. 11
0
        public VkSurfaceFormatKHR[] GetPhysicalDeviceSurfaceFormatsKHR(VkSurfaceKHR surface)
        {
            unsafe
            {
                VkSurfaceFormatKHR[] props;
                uint count = 0;
                do
                {
                    props = new VkSurfaceFormatKHR[count];

                    fixed(VkSurfaceFormatKHR *pptr = props)
                    VkException.Check(vkGetPhysicalDeviceSurfaceFormatsKHR(this, surface, &count, pptr));
                } while (props.Length != count);

                return(props);
            }
        }
Esempio n. 12
0
        private VkSurfaceFormatKHR chooseSwapSurfaceFormat(VkSurfaceFormatKHR[] availableFormats)
        {
            if (availableFormats.Length == 1 && availableFormats[0].format == VkFormat.VK_FORMAT_UNDEFINED)
            {
                return(VkSurfaceFormatKHR.Create(VkFormat.VK_FORMAT_B8G8R8A8_UNORM, VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR));
            }

            foreach (var availableFormat in availableFormats)
            {
                if (availableFormat.format == VkFormat.VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
                {
                    return(availableFormat);
                }
            }

            return(availableFormats[0]);
        }
Esempio n. 13
0
        private static VkSurfaceFormatKHR ChooseSwapSurfaceFormat(IReadOnlyList <VkSurfaceFormatKHR> availableFormats)
        {
            var preferred = new VkSurfaceFormatKHR
            {
                Format     = VkFormat.B8G8R8A8_UNORM,
                ColorSpace = VkColorSpaceKHR.SRGB_NONLINEAR_KHR
            };

            if (availableFormats.Count == 1 && availableFormats[0].Format == VkFormat.Undefined)
            {
                return(preferred);
            }
            if (availableFormats.Any(x => x.Format == preferred.Format && x.ColorSpace == preferred.ColorSpace))
            {
                return(preferred);
            }
            return(availableFormats.First());
        }
Esempio n. 14
0
        VkSurfaceFormatKHR ChooseSwapSurfaceFormat(List <VkSurfaceFormatKHR> formats)
        {
            if (formats.Count == 1 && formats[0].format == VkFormat.Undefined)
            {
                var result = new VkSurfaceFormatKHR();
                result.format     = VkFormat.B8G8R8A8_Unorm;
                result.colorSpace = VkColorSpaceKHR.SrgbNonlinearKhr;
                return(result);
            }

            foreach (var f in formats)
            {
                if (f.format == VkFormat.B8G8R8A8_Unorm && f.colorSpace == VkColorSpaceKHR.SrgbNonlinearKhr)
                {
                    return(f);
                }
            }

            return(formats[0]);
        }
Esempio n. 15
0
        protected VkSurfaceFormatKHR SelectFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface)
        {
            VkSurfaceFormatKHR[] formats;
            //physicalDevice.GetSurfaceFormatsKHR(surface, out formats);
            {
                UInt32 count;
                vkAPI.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, null).Check();
                formats = new VkSurfaceFormatKHR[count];
                fixed(VkSurfaceFormatKHR *pointer = formats)
                {
                    vkAPI.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &count, pointer).Check();
                }
            }
            foreach (var f in formats)
            {
                if (f.format == VkFormat.R8g8b8a8Unorm || f.format == VkFormat.B8g8r8a8Unorm)
                {
                    return(f);
                }
            }

            throw new System.Exception("didn't find the R8G8B8A8Unorm or B8G8R8A8Unorm format");
        }
Esempio n. 16
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();
        }
Esempio n. 17
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);
        }
Esempio n. 18
0
        public unsafe void InitSurface(IntPtr sdlWindow)
        {
            VkResult err;
            // Create the os-specific Surface
            VkWin32SurfaceCreateInfoKHR surfaceCreateInfo = new VkWin32SurfaceCreateInfoKHR();

            surfaceCreateInfo.sType = Win32SurfaceCreateInfoKHR;
            var processHandle = Process.GetCurrentProcess().Handle;//.SafeHandle.DangerousGetHandle();

            surfaceCreateInfo.hinstance = processHandle;
            surfaceCreateInfo.hwnd      = sdlWindow;
            VkSurfaceKHR surface;

            err     = vkCreateWin32SurfaceKHR(Instance, &surfaceCreateInfo, null, &surface);
            Surface = surface;

            // Get available queue family properties
            uint queueCount;

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null);
            Debug.Assert(queueCount >= 1);

            var queueProps = new VkQueueFamilyProperties[queueCount];

            fixed(VkQueueFamilyProperties *pointer = queueProps)
            {
                vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, pointer);
            }

            // Iterate over each queue to learn whether it supports presenting:
            // Find a queue with present support
            // Will be used to present the swap chain Images to the windowing system
            VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount];

            for (uint i = 0; i < queueCount; i++)
            {
                vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, Surface, &supportsPresent[i]);
            }

            // Search for a graphics and a present queue in the array of queue
            // families, try to find one that supports both
            uint graphicsQueueNodeIndex = uint.MaxValue;
            uint presentQueueNodeIndex  = uint.MaxValue;

            for (uint i = 0; i < queueCount; i++)
            {
                if ((queueProps[i].queueFlags & VkQueueFlagBits.Graphics) != 0)
                {
                    if (graphicsQueueNodeIndex == uint.MaxValue)
                    {
                        graphicsQueueNodeIndex = i;
                    }

                    if (supportsPresent[i] == true)
                    {
                        graphicsQueueNodeIndex = i;
                        presentQueueNodeIndex  = i;
                        break;
                    }
                }
            }

            if (presentQueueNodeIndex == uint.MaxValue)
            {
                // If there's no queue that supports both present and graphics
                // try to find a separate present queue
                for (uint i = 0; i < queueCount; ++i)
                {
                    if (supportsPresent[i] == true)
                    {
                        presentQueueNodeIndex = i;
                        break;
                    }
                }
            }

            // Exit if either a graphics or a presenting queue hasn't been found
            if (graphicsQueueNodeIndex == uint.MaxValue || presentQueueNodeIndex == uint.MaxValue)
            {
                throw new InvalidOperationException("Could not find a graphics and/or presenting queue!");
            }

            // todo : Add support for separate graphics and presenting queue
            if (graphicsQueueNodeIndex != presentQueueNodeIndex)
            {
                throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!");
            }

            QueueNodeIndex = graphicsQueueNodeIndex;

            // Get list of supported Surface formats
            uint formatCount;

            err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null);
            Debug.Assert(err == VkResult.Success);
            Debug.Assert(formatCount > 0);

            var surfaceFormats = new VkSurfaceFormatKHR[formatCount];

            fixed(VkSurfaceFormatKHR *pointer = surfaceFormats)
            {
                err = vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, pointer);
                Debug.Assert(err == VkResult.Success);
            }

            // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED,
            // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM
            if ((formatCount == 1) && (surfaceFormats[0].format == VkFormat.Undefined))
            {
                ColorFormat = VkFormat.B8g8r8a8Unorm;
                ColorSpace  = surfaceFormats[0].colorSpace;
            }
            else
            {
                // iterate over the list of available Surface format and
                // check for the presence of VK_FORMAT_B8G8R8A8_UNORM
                bool found_B8G8R8A8_UNORM = false;
                foreach (var surfaceFormat in surfaceFormats)
                {
                    if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm)
                    {
                        ColorFormat          = surfaceFormat.format;
                        ColorSpace           = surfaceFormat.colorSpace;
                        found_B8G8R8A8_UNORM = true;
                        break;
                    }
                }

                // in case VK_FORMAT_B8G8R8A8_UNORM is not available
                // select the first available color format
                if (!found_B8G8R8A8_UNORM)
                {
                    ColorFormat = surfaceFormats[0].format;
                    ColorSpace  = surfaceFormats[0].colorSpace;
                }
            }
        }
Esempio n. 19
0
        public unsafe Swapchain(Device device, NativeWindow window)
        {
            _device = device;
            _window = window;

            //get present queue
            _presentQueueFamily = GetQueueFamilyWithPresentationSupport(
                device,
                window
                );

            //get surface capabilities
            _surfaceCapabilities = GetSurfaceCapabilities(
                device,
                window
                );

            //get surface format support
            _supportedSurfaceFormats = GetSupportedSurfaceFormats(
                device,
                window
                );

            //get present mode support
            _supportedPresentModes = GetSupportedPresentModes(
                device,
                window
                );

            //choose best surface format
            #region Surface Format

            if (
                _supportedSurfaceFormats.Count == 1 &&
                _supportedSurfaceFormats[0].format == VkFormat.Undefined
                )
            {
                _surfaceFormat = new VkSurfaceFormatKHR
                {
                    colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR,
                    format     = VkFormat.R8g8b8Unorm
                };
            }
            else
            {
                bool choosenFormat = false;
                foreach (var format in _supportedSurfaceFormats)
                {
                    if (
                        format.format == VkFormat.R8g8b8Unorm &&
                        format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR
                        )
                    {
                        _surfaceFormat = format;
                        choosenFormat  = true;
                        break;
                    }
                }
                if (choosenFormat == false)
                {
                    _surfaceFormat = _supportedSurfaceFormats[0];
                }
            }

            #endregion

            #region Surface Present Mode

            _surfacePresentMode = VkPresentModeKHR.FifoKHR;
            foreach (var presentMode in _supportedPresentModes)
            {
                if (presentMode == VkPresentModeKHR.MailboxKHR)
                {
                    _surfacePresentMode = presentMode;
                    break;
                }
                else if (presentMode == VkPresentModeKHR.ImmediateKHR)
                {
                    _surfacePresentMode = presentMode;
                }
            }

            #endregion

            #region Surface Extent

            if (_surfaceCapabilities.currentExtent.width != uint.MaxValue)
            {
                _surfaceExtent = _surfaceCapabilities.currentExtent;
            }
            else
            {
                _surfaceExtent = new VkExtent2D
                {
                    width = Math.Clamp(
                        Convert.ToUInt32(window.Width),
                        _surfaceCapabilities.minImageExtent.width,
                        _surfaceCapabilities.maxImageExtent.width
                        ),
                    height = Math.Clamp(
                        Convert.ToUInt32(window.Height),
                        _surfaceCapabilities.minImageExtent.height,
                        _surfaceCapabilities.maxImageExtent.height
                        )
                };
            }

            #endregion

            #region Images Count

            var imagesCount = _surfaceCapabilities.minImageCount + 1;
            if (_surfaceCapabilities.maxImageCount > 0)
            {
                if (imagesCount > _surfaceCapabilities.maxImageCount)
                {
                    imagesCount = Math.Min(_surfaceCapabilities.maxImageCount, 2);
                }
            }

            #endregion

            var queueFamilyIndices = new NativeList <uint>();
            foreach (var queueFamily in device.QueueFamilies)
            {
                queueFamilyIndices.Add(queueFamily.Index);
            }

            var swapchainInfo = new VkSwapchainCreateInfoKHR
            {
                sType            = VkStructureType.SwapchainCreateInfoKHR,
                compositeAlpha   = VkCompositeAlphaFlagsKHR.OpaqueKHR,
                minImageCount    = imagesCount,
                imageFormat      = _surfaceFormat.format,
                imageColorSpace  = _surfaceFormat.colorSpace,
                imageExtent      = _surfaceExtent,
                imageArrayLayers = 1,
                imageUsage       = (
                    VkImageUsageFlags.ColorAttachment |
                    VkImageUsageFlags.TransferDst
                    ),
                imageSharingMode      = VkSharingMode.Concurrent,
                preTransform          = _surfaceCapabilities.currentTransform,
                presentMode           = _surfacePresentMode,
                surface               = window.Surface,
                clipped               = true,
                queueFamilyIndexCount = queueFamilyIndices.Count,
                pQueueFamilyIndices   = (uint *)queueFamilyIndices.Data.ToPointer()
            };

            VkSwapchainKHR swapchain;
            if (VulkanNative.vkCreateSwapchainKHR(
                    device.Handle,
                    &swapchainInfo,
                    null,
                    &swapchain
                    ) != VkResult.Success)
            {
                throw new Exception("failed to create swapchain");
            }
            _handle = swapchain;

            SetupSwapchainImages();
        }
Esempio n. 20
0
        public void Init(IntPtr hwnd, IntPtr processHandle)
        {
            if (this.isInitialized)
            {
                return;
            }

            this.instance = InitInstance();
            InitDebugCallback(this.instance);
            this.surface          = InitSurface(this.instance, hwnd, processHandle);
            this.vkPhysicalDevice = InitPhysicalDevice(this.instance);
            VkSurfaceFormatKHR surfaceFormat = SelectFormat(this.vkPhysicalDevice, this.surface);

            this.device = CreateDevice(this.vkPhysicalDevice, this.surface);

            this.vkQueue = this.device.GetQueue(0, 0);

            VkSurfaceCapabilitiesKHR surfaceCapabilities;

            //this.vkPhysicalDevice.GetSurfaceCapabilitiesKhr(this.vkSurface, out surfaceCapabilities);
            vkAPI.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(this.vkPhysicalDevice, this.surface, &surfaceCapabilities).Check();

            this.swapchain = CreateSwapchain(this.device, this.surface, surfaceFormat, surfaceCapabilities);

            this.vkImages = this.device.GetSwapchainImages(this.swapchain);

            this.renderPass = CreateRenderPass(this.device, surfaceFormat);

            this.framebuffers = CreateFramebuffers(this.device, this.vkImages, surfaceFormat, this.renderPass, surfaceCapabilities);

            this.vkFence     = this.device.CreateFence();
            this.vkSemaphore = this.device.CreateSemaphore();

            // buffers for vertex data.
            VkBuffer vertexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Vertices, VkBufferUsageFlagBits.VertexBuffer, typeof(float));

            VkBuffer indexBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, Indexes, VkBufferUsageFlagBits.IndexBuffer, typeof(short));

            var uniformBufferData = new AreaUniformBuffer(1, 1);

            this.originalWidth  = 1; this.width = this.originalWidth;
            this.originalHeight = 1; this.height = this.originalHeight;

            this.uniformBuffer = CreateBuffer(this.vkPhysicalDevice, this.device, uniformBufferData, VkBufferUsageFlagBits.UniformBuffer, typeof(AreaUniformBuffer));

            this.descriptorSetLayout = CreateDescriptorSetLayout(this.device);

            this.vkPipelineLayout = CreatePipelineLayout(this.device, this.descriptorSetLayout);

            VkPipeline pipeline = CreatePipeline(this.device, surfaceCapabilities, this.renderPass, this.vkPipelineLayout);

            this.descriptorSet = CreateDescriptorSet(this.device, this.descriptorSetLayout);

            UpdateDescriptorSets(this.device, this.uniformBuffer, this.descriptorSet);

            this.commandBuffers = CreateCommandBuffers(
                this.device, this.renderPass, surfaceCapabilities,
                this.vkImages, this.framebuffers, pipeline,
                vertexBuffer, indexBuffer, (uint)Indexes.Length,
                this.vkPipelineLayout, this.descriptorSet);

            this.isInitialized = true;
        }
Esempio n. 21
0
        private void CreateSwapChain()
        {
            var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface);

            VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = ChooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.minImageCount + 1;

            if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
            {
                imageCount = Math.Min(imageCount, swapChainSupport.capabilities.maxImageCount);
            }

            var createInfo = new VkSwapchainCreateInfoKHR()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
                surface          = vkSurface,
                minImageCount    = imageCount,
                imageFormat      = surfaceFormat.format,
                imageColorSpace  = surfaceFormat.colorSpace,
                imageExtent      = extent,
                imageArrayLayers = 1,
                imageUsage       = VkImageUsageFlagBits.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
                preTransform     = swapChainSupport.capabilities.currentTransform,
                compositeAlpha   = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
                presentMode      = presentMode,
                clipped          = true,
            };

            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            uint *QueueFamilyIndicesPtr = stackalloc uint[]
            {
                (uint)indices.GraphicsFamily,
                (uint)indices.PresentFamily,
            };

            if (indices.GraphicsFamily != indices.PresentFamily)
            {
                createInfo.imageSharingMode    = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.pQueueFamilyIndices = QueueFamilyIndicesPtr;
            }
            else
            {
                createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
            }

            VkSwapchainKHR newSwapChain;
            var            result = VulkanNative.vkCreateSwapchainKHR(vkDevice, &createInfo, null, &newSwapChain);

            vkSwapChain = newSwapChain;
            Helpers.CheckErrors(result);

            VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, null);
            VkImage *images = stackalloc VkImage[(int)imageCount];

            result = VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, images);
            Helpers.CheckErrors(result);

            vkSwapChainImages = new VkImage[imageCount];
            for (int i = 0; i < imageCount; i++)
            {
                vkSwapChainImages[i] = images[i];
            }

            vkSwapChainImageFormat = surfaceFormat.format;
            vkSwapChainExtent      = extent;
        }
        private void CreateSwapChain()
        {
            // Create SwapChain
            SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice);

            VkSurfaceFormatKHR surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = this.ChooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = this.ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.minImageCount + 1;

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

            VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR();

            createInfo.sType            = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
            createInfo.surface          = surface;
            createInfo.minImageCount    = imageCount;
            createInfo.imageFormat      = surfaceFormat.format;
            createInfo.imageColorSpace  = surfaceFormat.colorSpace;
            createInfo.imageExtent      = extent;
            createInfo.imageArrayLayers = 1;
            createInfo.imageUsage       = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            QueueFamilyIndices indices = this.FindQueueFamilies(this.physicalDevice);
            uint *queueFamilyIndices   = stackalloc uint[] { indices.graphicsFamily.Value, indices.presentFamily.Value };

            if (indices.graphicsFamily != indices.presentFamily)
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.queueFamilyIndexCount = 2;
                createInfo.pQueueFamilyIndices   = queueFamilyIndices;
            }
            else
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
                createInfo.queueFamilyIndexCount = 0;    //Optional
                createInfo.pQueueFamilyIndices   = null; //Optional
            }
            createInfo.preTransform   = swapChainSupport.capabilities.currentTransform;
            createInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
            createInfo.presentMode    = presentMode;
            createInfo.clipped        = true;
            createInfo.oldSwapchain   = 0;

            fixed(VkSwapchainKHR *swapChainPtr = &swapChain)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateSwapchainKHR(device, &createInfo, null, swapChainPtr));
            }

            // SwapChain Images
            VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, null);
            this.swapChainImages = new VkImage[imageCount];
            fixed(VkImage *swapChainImagesPtr = &this.swapChainImages[0])
            {
                VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImagesPtr);
            }

            this.swapChainImageFormat = surfaceFormat.format;
            this.swapChainExtent      = extent;
        }
Esempio n. 23
0
        private static uint RateDevice(IntPtr physDevice)
        {
            var devProps = new ManagedPtr <VkPhysicalDeviceProperties>();
            var devFeats = new ManagedPtr <VkPhysicalDeviceFeatures>();

            vkGetPhysicalDeviceProperties(physDevice, devProps);
            vkGetPhysicalDeviceFeatures(physDevice, devFeats);

            var devProps_ = devProps.Value;
            var devFeats_ = devFeats.Value;

            uint score = 0;

            if (devProps_.deviceType == VkPhysicalDeviceType.PhysicalDeviceTypeDiscreteGpu)
            {
                score += 100;
            }

            score += devProps_.limits.maxImageDimension2D;

            if (!devFeats_.multiDrawIndirect)
            {
                return(0);
            }

            if (!devFeats_.tessellationShader)
            {
                return(0);
            }

            if (!ExtensionsSupported(physDevice))
            {
                return(0);
            }

            var caps_ptr = new ManagedPtr <VkSurfaceCapabilitiesKHR>();

            vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDevice, surfaceHndl, caps_ptr);
            var caps = caps_ptr.Value;

            uint fmt_cnt = 0;

            vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surfaceHndl, &fmt_cnt, null);
            var fmts_ptr = new ManagedPtrArray <VkSurfaceFormatKHR>(fmt_cnt);

            vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surfaceHndl, &fmt_cnt, fmts_ptr);
            var fmts = fmts_ptr.Value;

            bool fmt_valid = false;
            VkSurfaceFormatKHR chosen_fmt = new VkSurfaceFormatKHR();

            foreach (var avail_fmt in fmts)
            {
                if (avail_fmt.format == VkFormat.FormatB8g8r8a8Unorm && avail_fmt.colorSpace == VkColorSpaceKHR.ColorSpaceSrgbNonlinearKhr)
                {
                    chosen_fmt = avail_fmt;
                    fmt_valid  = true;
                    break;
                }
            }
            if (!fmt_valid && fmts.Length > 0)
            {
                chosen_fmt = fmts[0];
                fmt_valid  = true;
            }

            uint present_mode_cnt = 0;

            vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surfaceHndl, &present_mode_cnt, null);
            var present_modes = stackalloc VkPresentModeKHR[(int)present_mode_cnt];

            vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surfaceHndl, &present_mode_cnt, present_modes);

            bool             present_valid  = false;
            VkPresentModeKHR chosen_present = VkPresentModeKHR.PresentModeBeginRangeKhr;

            for (int i = 0; i < present_mode_cnt; i++)
            {
                var avail_present = present_modes[i];
                if (avail_present == VkPresentModeKHR.PresentModeMailboxKhr)
                {
                    present_valid  = true;
                    chosen_present = VkPresentModeKHR.PresentModeMailboxKhr;
                }
                else if (avail_present == VkPresentModeKHR.PresentModeFifoRelaxedKhr)
                {
                    present_valid  = true;
                    chosen_present = VkPresentModeKHR.PresentModeFifoRelaxedKhr;
                }
            }
            if (!present_valid)
            {
                present_valid  = true;
                chosen_present = VkPresentModeKHR.PresentModeFifoKhr;
            }
            chosen_present = VkPresentModeKHR.PresentModeImmediateKhr;

            if (!fmt_valid)
            {
                return(0);
            }
            if (!present_valid)
            {
                return(0);
            }

            present_mode = chosen_present;
            surface_fmt  = chosen_fmt;

            return(score);
        }
Esempio n. 24
0
        private void createSwapChain()
        {
            SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);

            VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = chooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = chooseSwapExtent(swapChainSupport.capabilities);

            int imageCount = swapChainSupport.capabilities.minImageCount + 1;

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

            VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR();

            createInfo.sType   = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
            createInfo.surface = surface;

            createInfo.minImageCount    = imageCount;
            createInfo.imageFormat      = surfaceFormat.format;
            createInfo.imageColorSpace  = surfaceFormat.colorSpace;
            createInfo.imageExtent      = extent;
            createInfo.imageArrayLayers = 1;
            createInfo.imageUsage       = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
            var queueFamilyIndices     = new List <int>()
            {
                indices.graphicsFamily, indices.presentFamily
            };

            if (indices.graphicsFamily != indices.presentFamily)
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.queueFamilyIndexCount = queueFamilyIndices.Count;
                createInfo.pQueueFamilyIndices   = queueFamilyIndices.ToArray();
            }
            else
            {
                createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
            }

            createInfo.preTransform   = (VkSurfaceTransformFlagBitsKHR)swapChainSupport.capabilities.currentTransform;
            createInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
            createInfo.presentMode    = presentMode;
            createInfo.clipped        = VkBool32.VK_TRUE;

            createInfo.oldSwapchain = null;

            VkResult result = Vulkan.vkCreateSwapchainKHR(device, createInfo, null, out swapChain);

            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create swap chain!", result);
            }

            swapChainImages = new VkImage[imageCount];
            Vulkan.vkGetSwapchainImagesKHR(device, swapChain, ref imageCount, swapChainImages);

            swapChainImageFormat = surfaceFormat.format;
            swapChainExtent      = extent;
        }