예제 #1
0
 public static VkSurfaceFormatKHR Create(VkFormat format, VkColorSpaceKHR colorSpace)
 {
     return(new VkSurfaceFormatKHR()
     {
         format = format, colorSpace = colorSpace
     });
 }
예제 #2
0
        private SoftwareImage(SoftwareDevice device, VkFormat format, VkExtent3D imageExtent, VkColorSpaceKHR colorSpace, out VkResult result)
        {
            this.m_device          = device;
            this.m_imageFormat     = format;
            this.m_imageExtent     = imageExtent;
            this.m_imageColorSpace = colorSpace;

            Initialize(out result);
        }
예제 #3
0
        private SoftwareImage(SoftwareDevice device, VkSwapchainCreateInfoKHR createInfo, out VkResult result)
        {
            this.m_device = device;

            this.m_imageFormat     = createInfo.imageFormat;
            this.m_imageExtent     = VkExtent3D.Create(createInfo.imageExtent.width, createInfo.imageExtent.height, 1);
            this.m_imageColorSpace = createInfo.imageColorSpace;

            Initialize(out result);
        }
예제 #4
0
        private SoftwareImage(SoftwareDevice device, VkImageCreateInfo pCreateInfo, out VkResult result)
        {
            this.m_device     = device;
            this.m_createInfo = pCreateInfo;

            this.m_imageFormat     = pCreateInfo.format;
            this.m_imageExtent     = pCreateInfo.extent;
            this.m_imageColorSpace = VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;

            Initialize(out result);
        }
예제 #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VkSurfaceFormatKHR"/> struct.
 /// </summary>
 /// <param name="format">Is the <see cref="VkFormat"/> that is compatible with the specified surface.</param>
 /// <param name="colorSpace">Is a presentation <see cref="VkColorSpaceKHR"/> that is compatible with the surface.</param>
 public VkSurfaceFormatKHR(VkFormat format, VkColorSpaceKHR colorSpace)
 {
     this.format     = format;
     this.colorSpace = colorSpace;
 }
예제 #6
0
        public SwapchainKHR(SurfaceKHR surface, Device device, uint minImageCount,
                            uint layerCount, VkImageUsageFlag usageFlag,
                            VkFormat imageFormat, VkColorSpaceKHR colorSpace,
                            VkExtent2D dimensions,
                            VkCompositeAlphaFlagBitsKHR compositeAlpha,
                            VkPresentModeKHR presentMode,
                            bool clipped = true,
                            VkSurfaceTransformFlagBitsKHR transform = VkSurfaceTransformFlagBitsKHR.IdentityBitKhr,
                            VkSharingMode sharing     = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null,
                            SwapchainKHR oldSwapchain = null)
        {
            SurfaceKHR = surface;
            Device     = device;

            {
                var surfSupported = false;
                foreach (var family in Device.Queues.Select(x => x.FamilyIndex).Distinct())
                {
                    if (PhysicalDevice.Handle.GetPhysicalDeviceSurfaceSupportKHR(family, SurfaceKHR.Handle))
                    {
                        surfSupported = true;
                        break;
                    }
                }
                if (!surfSupported)
                {
                    throw new NotSupportedException($"No queues on device support the surface");
                }
            }

            _sharingQueueInfo = sharedQueueFamily;

            unsafe
            {
                if (sharing == VkSharingMode.Concurrent)
                {
                    Debug.Assert(sharedQueueFamily != null);
                }
                var hasPinnedSharedQueue    = sharedQueueFamily != null && sharedQueueFamily.Length > 0;
                var pinnedSharedQueueFamily = hasPinnedSharedQueue
                    ? GCHandle.Alloc(sharedQueueFamily, GCHandleType.Pinned)
                    : default(GCHandle);
                try
                {
                    var info = new VkSwapchainCreateInfoKHR()
                    {
                        SType                 = VkStructureType.SwapchainCreateInfoKhr,
                        PNext                 = IntPtr.Zero,
                        Flags                 = 0, // reserved VkSwapchainCreateFlagBitsKHR
                        Surface               = surface.Handle,
                        MinImageCount         = minImageCount,
                        ImageFormat           = imageFormat,
                        ImageColorSpace       = colorSpace,
                        ImageExtent           = dimensions,
                        ImageArrayLayers      = layerCount,
                        ImageUsage            = usageFlag,
                        ImageSharingMode      = sharing,
                        QueueFamilyIndexCount = (uint)(sharedQueueFamily?.Length ?? 0),
                        PQueueFamilyIndices   = hasPinnedSharedQueue
                            ? (uint *)Marshal.UnsafeAddrOfPinnedArrayElement(sharedQueueFamily, 0).ToPointer()
                            : (uint *)0,
                        PreTransform   = transform,
                        CompositeAlpha = compositeAlpha,
                        PresentMode    = presentMode,
                        Clipped        = clipped,
                        OldSwapchain   = oldSwapchain?.Handle ?? VkSwapchainKHR.Null
                    };
                    _info  = info;
                    Handle = Device.Handle.CreateSwapchainKHR(&info, Instance.AllocationCallbacks);
                    if (oldSwapchain != null)
                    {
                        foreach (var img in oldSwapchain._swapchainImages)
                        {
                            img.Dispose();
                        }
                        oldSwapchain.Dispose();
                    }
                }
                finally
                {
                    if (hasPinnedSharedQueue)
                    {
                        pinnedSharedQueueFamily.Free();
                    }
                }
            }

            var images = Device.Handle.GetSwapchainImagesKHR(Handle);

            _swapchainImages.Clear();
            _swapchainImages.Capacity = images.Length;
            foreach (var img in images)
            {
                _swapchainImages.Add(new SwapchainImage(this, img));
            }
        }
예제 #7
0
 public SwapchainKHRBuilder RequiredFormats(VkColorSpaceKHR colorSpace, params VkFormat[] formats)
 {
     _requiredFormats.Add(new KeyValuePair <VkColorSpaceKHR, VkFormat[]>(colorSpace, formats));
     return(this);
 }
예제 #8
0
        public void CreateSwapChain()
        {
            var PhysicalDevice = NativeDevice.NativeAdapter.NativePhysicalDevice;

            var width = Parameters.BackBufferWidth;

            var height = Parameters.BackBufferHeight;

            var vsync = Parameters.Settings.VSync;


            // Get available queue family properties
            uint queueCount;

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null);
            VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount];

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps);



            // 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 & VkQueueFlags.Graphics) != 0)
                {
                    if (graphicsQueueNodeIndex == uint.MaxValue)
                    {
                        graphicsQueueNodeIndex = i;
                    }


                    if (supportsPresent[i] == 1)
                    {
                        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] == 1)
                    {
                        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!");
            }



            // Get list of supported Surface formats
            uint formatCount;

            vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, null);
            VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount];

            vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, Surface, &formatCount, surfaceFormats);



            // 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))
            {
                VkColorFormat = 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;

                List <VkSurfaceFormatKHR> Formats = new List <VkSurfaceFormatKHR>();

                for (int i = 0; i < formatCount; i++)
                {
                    Formats.Add(surfaceFormats[i]);
                }



                foreach (var surfaceFormat in Formats)
                {
                    if (surfaceFormat.format == VkFormat.B8g8r8a8Unorm)
                    {
                        VkColorFormat        = 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)
                {
                    VkColorFormat = surfaceFormats[0].format;
                    ColorSpace    = surfaceFormats[0].colorSpace;
                }
            }


            // Get physical Device Surface properties and formats
            VkSurfaceCapabilitiesKHR surfCaps;

            vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PhysicalDevice, Surface, &surfCaps);



            // Get available present modes
            uint presentModeCount;

            vkGetPhysicalDeviceSurfacePresentModesKHR(PhysicalDevice, Surface, &presentModeCount, null);
            VkPresentModeKHR *presentModes = stackalloc VkPresentModeKHR[(int)presentModeCount];

            vkGetPhysicalDeviceSurfacePresentModesKHR(PhysicalDevice, Surface, &presentModeCount, (VkPresentModeKHR *)presentModes);



            VkExtent2D swapchainExtent;

            // If width (and height) equals the special value 0xFFFFFFFF, the size of the Surface will be set by the swapchain
            if (surfCaps.currentExtent.width == unchecked ((uint)-1))
            {
                // If the Surface size is undefined, the size is set to
                // the size of the Images requested.
                swapchainExtent.width  = (uint)width;
                swapchainExtent.height = (uint)height;
            }
            else
            {
                // If the Surface size is defined, the swap chain size must match
                swapchainExtent = surfCaps.currentExtent;
                width           = (int)surfCaps.currentExtent.width;
                height          = (int)surfCaps.currentExtent.height;
            }


            // Select a present mode for the swapchain

            // The VK_PRESENT_MODE_FIFO_KHR mode must always be present as per spec
            // This mode waits for the vertical blank ("v-sync")
            VkPresentModeKHR swapchainPresentMode = VkPresentModeKHR.FifoKHR;

            // If v-sync is not requested, try to find a mailbox mode
            // It's the lowest latency non-tearing present mode available
            if (!vsync)
            {
                for (uint i = 0; i < presentModeCount; i++)
                {
                    if (presentModes[i] == VkPresentModeKHR.MailboxKHR)
                    {
                        swapchainPresentMode = VkPresentModeKHR.MailboxKHR;
                        break;
                    }
                    if ((swapchainPresentMode != VkPresentModeKHR.MailboxKHR) && (presentModes[i] == VkPresentModeKHR.ImmediateKHR))
                    {
                        swapchainPresentMode = VkPresentModeKHR.ImmediateKHR;
                    }
                }
            }

            // Determine the number of Images
            uint desiredNumberOfSwapchainImages = surfCaps.minImageCount + 1;

            if ((surfCaps.maxImageCount > 0) && (desiredNumberOfSwapchainImages > surfCaps.maxImageCount))
            {
                desiredNumberOfSwapchainImages = surfCaps.maxImageCount;
            }


            // Find the transformation of the Surface
            VkSurfaceTransformFlagsKHR preTransform;

            if ((surfCaps.supportedTransforms & VkSurfaceTransformFlagsKHR.IdentityKHR) != 0)
            {
                // We prefer a non-rotated transform
                preTransform = VkSurfaceTransformFlagsKHR.IdentityKHR;
            }

            else
            {
                preTransform = surfCaps.currentTransform;
            }


            VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR()
            {
                sType           = VkStructureType.SwapchainCreateInfoKHR,
                pNext           = null,
                surface         = Surface,
                minImageCount   = desiredNumberOfSwapchainImages,
                imageFormat     = VkColorFormat,
                imageColorSpace = ColorSpace,
                imageExtent     = new VkExtent2D()
                {
                    width  = swapchainExtent.width,
                    height = swapchainExtent.height
                },
                imageUsage            = VkImageUsageFlags.ColorAttachment,
                preTransform          = preTransform,
                imageArrayLayers      = 1,
                imageSharingMode      = VkSharingMode.Exclusive,
                queueFamilyIndexCount = 0,
                pQueueFamilyIndices   = null,
                presentMode           = swapchainPresentMode,
                oldSwapchain          = SwapChain,

                // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area
                clipped        = True,
                compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR,
            };


            // Set additional usage flag for blitting from the swapchain Images if supported
            VkFormatProperties formatProps;

            vkGetPhysicalDeviceFormatProperties(PhysicalDevice, VkColorFormat, out formatProps);
            if ((formatProps.optimalTilingFeatures & VkFormatFeatureFlags.BlitDst) != 0)
            {
                swapchainCI.imageUsage |= VkImageUsageFlags.TransferSrc;
            }


            VkSwapchainKHR swapChain;

            vkCreateSwapchainKHR(NativeDevice.Device, &swapchainCI, null, &swapChain);
            SwapChain = swapChain;


            //vkDestroySwapchainKHR(NativeDevice.Device, SwapChain, null);



            uint imageCount;

            vkGetSwapchainImagesKHR(NativeDevice.Device, SwapChain, &imageCount, null);
            VkImage *VkImages = stackalloc VkImage[(int)imageCount];

            vkGetSwapchainImagesKHR(NativeDevice.Device, swapChain, &imageCount, VkImages);



            Images = new List <VkImage>();

            for (int i = 0; i < imageCount; i++)
            {
                Images.Add(VkImages[i]);
            }
        }
예제 #9
0
        public void CreateSwapChain()
        {
            VkPhysicalDevice PhysicalDevice = NativeDevice.NativeAdapter.handle;

            int width = Parameters.Width;

            int height = Parameters.Height;

            bool vsync = false;


            // Get available queue family properties
            uint queueCount;

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null);
            VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount];

            vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps);



            // 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, out 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 & VkQueueFlags.Graphics) != 0)
                {
                    if (graphicsQueueNodeIndex is uint.MaxValue)
                    {
                        graphicsQueueNodeIndex = i;
                    }

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

            if (presentQueueNodeIndex is 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 is uint.MaxValue || presentQueueNodeIndex is 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!");
            }



            // Get list of supported Surface formats
            uint formatCount;

            vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, null);
            VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount];

            vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, surfaceFormats);



            // 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 is 1) && (surfaceFormats[0].format is VkFormat.Undefined))
            {
                color_format = VkFormat.B8G8R8A8UNorm;
                color_space  = surfaceFormats[0].colorSpace;
            }