internal static SwapchainKhr[] CreateSharedKhr(Device parent, SwapchainCreateInfoKhr[] createInfos,
                                                       ref AllocationCallbacks?allocator)
        {
            int count             = createInfos?.Length ?? 0;
            var nativeCreateInfos = stackalloc SwapchainCreateInfoKhr.Native[count];

            for (int i = 0; i < count; i++)
            {
                createInfos[i].ToNative(out nativeCreateInfos[i]);
            }

            AllocationCallbacks.Native nativeAllocator;
            allocator?.ToNative(&nativeAllocator);

            long * handles = stackalloc long[count];
            Result result  = vkCreateSharedSwapchainsKHR(parent, count, nativeCreateInfos,
                                                         allocator.HasValue ? &nativeAllocator : null, handles);

            for (int i = 0; i < count; i++)
            {
                nativeCreateInfos[i].Free();
            }
            VulkanException.ThrowForInvalidResult(result);

            var swapchains = new SwapchainKhr[count];

            for (int i = 0; i < count; i++)
            {
                swapchains[i] = new SwapchainKhr(parent, handles[i], ref allocator);
            }
            return(swapchains);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure.
 /// </summary>
 /// <param name="surface">
 /// The <see cref="SurfaceKhr"/> that the swapchain will present images to.
 /// </param>
 /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param>
 /// <param name="imageExtent">
 /// The size (in pixels) of the swapchain.
 /// <para>
 /// Behavior is platform-dependent when the image extent does not match the surface's <see
 /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>.
 /// </para>
 /// </param>
 /// <param name="minImageCount">
 /// The minimum number of presentable images that the application needs. The platform will
 /// either create the swapchain with at least that many images, or will fail to create the swapchain.
 /// </param>
 /// <param name="imageColorSpace">Color space value specifying the way the swapchain interprets image data.</param>
 /// <param name="imageArrayLayers">
 /// The number of views in a multiview/stereo surface.
 /// <para>For non-stereoscopic-3D applications, this value is 1.</para>
 /// </param>
 /// <param name="imageUsage">A bitmask describing the intended usage of the (acquired) swapchain images.</param>
 /// <param name="imageSharingMode">The sharing mode used for the image(s) of the swapchain.</param>
 /// <param name="queueFamilyIndices">
 /// Queue family indices having access to the image(s) of the swapchain when <see
 /// cref="ImageSharingMode"/> is <see cref="SharingMode.Concurrent"/>.
 /// </param>
 /// <param name="preTransform">
 /// A value describing the transform, relative to the presentation engine's natural
 /// orientation, applied to the image content prior to presentation.
 /// <para>
 /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value
 /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the
 /// presentation engine will transform the image content as part of the presentation operation.
 /// </para>
 /// </param>
 /// <param name="compositeAlpha">
 /// A bitmask indicating the alpha compositing mode to use when this surface is composited
 /// together with other surfaces on certain window systems.
 /// </param>
 /// <param name="presentMode">
 /// The presentation mode the swapchain will use.
 /// <para>
 /// A swapchain's present mode determines how incoming present requests will be processed and
 /// queued internally.
 /// </para>
 /// </param>
 /// <param name="clipped">
 /// Indicates whether the Vulkan implementation is allowed to discard rendering operations
 /// that affect regions of the surface which are not visible.</param>
 /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param>
 public SwapchainCreateInfoKhr(
     SurfaceKhr surface,
     Format imageFormat,
     Extent2D imageExtent,
     int minImageCount                 = 2,
     ColorSpaceKhr imageColorSpace     = ColorSpaceKhr.SRgbNonlinear,
     int imageArrayLayers              = 1,
     ImageUsages imageUsage            = ImageUsages.ColorAttachment | ImageUsages.TransferDst,
     SharingMode imageSharingMode      = SharingMode.Exclusive,
     int[] queueFamilyIndices          = null,
     SurfaceTransformsKhr preTransform = SurfaceTransformsKhr.Identity,
     CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque,
     PresentModeKhr presentMode        = PresentModeKhr.Fifo,
     bool clipped = true,
     SwapchainKhr oldSwapchain = null)
 {
     Flags              = SwapchainCreateFlagsKhr.None;
     Surface            = surface;
     MinImageCount      = minImageCount;
     ImageFormat        = imageFormat;
     ImageColorSpace    = imageColorSpace;
     ImageExtent        = imageExtent;
     ImageArrayLayers   = imageArrayLayers;
     ImageUsage         = imageUsage;
     ImageSharingMode   = imageSharingMode;
     QueueFamilyIndices = queueFamilyIndices;
     PreTransform       = preTransform;
     CompositeAlpha     = compositeAlpha;
     PresentMode        = presentMode;
     Clipped            = clipped;
     OldSwapchain       = oldSwapchain;
 }
Exemple #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SwapchainCreateInfoKhr"/> structure.
 /// </summary>
 /// <param name="surface">
 /// The <see cref="SurfaceKhr"/> that the swapchain will present images to.
 /// </param>
 /// <param name="imageExtent">
 /// The size (in pixels) of the swapchain.
 /// <para>
 /// Behavior is platform-dependent when the image extent does not match the surface's <see
 /// cref="SurfaceCapabilitiesKhr.CurrentExtent"/> as returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>.
 /// </para>
 /// </param>
 /// <param name="preTransform">
 /// A bitmask describing the transform, relative to the presentation engine's natural
 /// orientation, applied to the image content prior to presentation.
 /// <para>
 /// If it does not match the <see cref="SurfaceCapabilitiesKhr.CurrentTransform"/> value
 /// returned by <see cref="PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr"/>, the
 /// presentation engine will transform the image content as part of the presentation operation.
 /// </para>
 /// </param>
 /// <param name="imageUsage">
 /// A bitmask indicating how the application will use the swapchain's presentable images.
 /// </param>
 /// <param name="flags">A bitmask indicating parameters of swapchain creation.</param>
 /// <param name="minImageCount">
 /// The minimum number of presentable images that the application needs. The platform will
 /// either create the swapchain with at least that many images, or will fail to create the swapchain.
 /// </param>
 /// <param name="imageFormat">A format that is valid for swapchains on the specified surface.</param>
 /// <param name="compositeAlpha">
 /// A bitmask indicating the alpha compositing mode to use when this surface is composited
 /// together with other surfaces on certain window systems.
 /// </param>
 /// <param name="imageArrayLayers">
 /// The number of views in a multiview/stereo surface. For non-stereoscopic-3D applications,
 /// this value is 1.
 /// </param>
 /// <param name="presentMode">
 /// The presentation mode the swapchain will use.
 /// <para>
 /// A swapchain's present mode determines how incoming present requests will be processed and
 /// queued internally.
 /// </para>
 /// </param>
 /// <param name="clipped">
 /// Indicates whether the Vulkan implementation is allowed to discard rendering operations
 /// that affect regions of the surface which are not visible.
 /// </param>
 /// <param name="oldSwapchain">Existing swapchain to replace, if any.</param>
 public SwapchainCreateInfoKhr(
     SurfaceKhr surface,
     Format imageFormat,
     Extent2D imageExtent,
     SurfaceTransformsKhr preTransform,
     PresentModeKhr presentMode,
     SwapchainCreateFlagsKhr flags     = 0,
     int minImageCount                 = 2,
     ImageUsages imageUsage            = ImageUsages.ColorAttachment | ImageUsages.TransferDst,
     CompositeAlphasKhr compositeAlpha = CompositeAlphasKhr.Opaque,
     int imageArrayLayers              = 1,
     bool clipped = true,
     SwapchainKhr oldSwapchain = null)
 {
     Flags              = flags;
     Surface            = surface;
     ImageUsage         = imageUsage;
     MinImageCount      = minImageCount;
     ImageFormat        = imageFormat;
     ImageColorSpace    = 0;
     ImageExtent        = imageExtent;
     ImageArrayLayers   = imageArrayLayers;
     ImageSharingMode   = 0;
     QueueFamilyIndices = null;
     PreTransform       = preTransform;
     CompositeAlpha     = compositeAlpha;
     PresentMode        = presentMode;
     Clipped            = clipped;
     OldSwapchain       = oldSwapchain;
 }
        /// <summary>
        /// Queue an image for presentation.
        /// </summary>
        /// <param name="queue">
        /// The queue that is capable of presentation to the target surface's platform on the same
        /// device as the image's swapchain.
        /// </param>
        /// <param name="waitSemaphore">Semaphore to wait for before presenting.</param>
        /// <param name="swapchain">Valid swapchain handle.</param>
        /// <param name="imageIndex">Index into the array of swapchain's presentable images.</param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public static void PresentKhr(this Queue queue, Semaphore waitSemaphore, SwapchainKhr swapchain, int imageIndex)
        {
            long waitSemaphoreHandle = waitSemaphore;
            long swapchainHandle     = swapchain;
            var  nativePresentInfo   = new PresentInfoKhr.Native
            {
                Type = StructureType.PresentInfoKhr,
                WaitSemaphoreCount = waitSemaphoreHandle == 0 ? 0 : 1,
                WaitSemaphores     = &waitSemaphoreHandle,
                SwapchainCount     = swapchainHandle == 0 ? 0 : 1,
                Swapchains         = &swapchainHandle,
                ImageIndices       = &imageIndex
            };

            Result result = vkQueuePresentKHR(queue, &nativePresentInfo);

            VulkanException.ThrowForInvalidResult(result);
        }
 private static vkGetSwapchainStatusKHRDelegate vkGetSwapchainStatusKHR(SwapchainKhr swapchain) => swapchain.Parent.GetProc <vkGetSwapchainStatusKHRDelegate>(nameof(vkGetSwapchainStatusKHR));
Exemple #6
0
        private void rebuildSwapchain()
        {
            var sCaps = VkKhr.PhysicalDeviceExtensions.GetSurfaceCapabilitiesKhr(_vkPhysicalDevice, Surface);

            // Calculate the size of the images
            if (sCaps.CurrentExtent.Width != Int32.MaxValue)             // We have to use the given size
            {
                Extent = sCaps.CurrentExtent;
            }
            else             // We can choose an extent, but we will just make it the size of the window
            {
                Extent = Point.Max(sCaps.MinImageExtent, Point.Min(sCaps.MaxImageExtent, _window.Size));
            }

            // Calculate the number of images
            int imCount = sCaps.MinImageCount + 1;

            if (sCaps.MaxImageCount != 0)
            {
                imCount = Math.Min(imCount, sCaps.MaxImageCount);
            }
            _syncObjects.MaxInflightFrames = (uint)Math.Min(imCount, MAX_INFLIGHT_FRAMES);

            // Create the swapchain
            var oldSwapChain = _swapChain;

            VkKhr.SwapchainCreateInfoKhr cInfo = new VkKhr.SwapchainCreateInfoKhr(
                Surface,
                _surfaceFormat.Format,
                Extent,
                minImageCount: imCount,
                imageColorSpace: _surfaceFormat.ColorSpace,
                imageUsage: Vk.ImageUsages.ColorAttachment | Vk.ImageUsages.TransferDst,
                presentMode: _presentMode,
                oldSwapchain: oldSwapChain
                );
            _swapChain = VkKhr.DeviceExtensions.CreateSwapchainKhr(_vkDevice, cInfo);

            // Destroy the old swapchain
            oldSwapChain?.Dispose();

            // Get the new swapchain images
            var imgs = _swapChain.GetImages();

            _swapChainImages = new SwapchainImage[imgs.Length];
            imgs.ForEach((img, idx) => {
                Vk.ImageViewCreateInfo vInfo = new Vk.ImageViewCreateInfo(
                    _surfaceFormat.Format,
                    DEFAULT_SUBRESOURCE_RANGE,
                    viewType: Vk.ImageViewType.Image2D,
                    components: default
                    );
                var view = img.CreateView(vInfo);
                _swapChainImages[idx] = new SwapchainImage {
                    Image           = img, View = view,
                    TransferBarrier = new Vk.ImageMemoryBarrier(
                        img,
                        new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1),
                        Vk.Accesses.ColorAttachmentRead,
                        Vk.Accesses.TransferWrite,
                        Vk.ImageLayout.PresentSrcKhr,
                        Vk.ImageLayout.TransferDstOptimal
                        ),
                    PresentBarrier = new Vk.ImageMemoryBarrier(
                        img,
                        new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1),
                        Vk.Accesses.TransferWrite,
                        Vk.Accesses.ColorAttachmentRead,
                        Vk.ImageLayout.TransferDstOptimal,
                        Vk.ImageLayout.PresentSrcKhr
                        )
                };
            });

            // Perform the initial layout transitions to present mode
            _commandBuffer.Begin(ONE_TIME_SUBMIT);
            var imb = new Vk.ImageMemoryBarrier(null, new Vk.ImageSubresourceRange(Vk.ImageAspects.Color, 0, 1, 0, 1),
                                                Vk.Accesses.TransferWrite, Vk.Accesses.ColorAttachmentRead, Vk.ImageLayout.Undefined, Vk.ImageLayout.PresentSrcKhr);

            _commandBuffer.CmdPipelineBarrier(Vk.PipelineStages.AllCommands, Vk.PipelineStages.AllCommands,
                                              imageMemoryBarriers: _swapChainImages.Select(sci => { imb.Image = sci.Image; return(imb); }).ToArray());
            _commandBuffer.End();
            _presentQueue.Submit(new Vk.SubmitInfo(commandBuffers: new[] { _commandBuffer }), _blitFence);
            _blitFence.Wait();             // Do not reset

            // Report
            LDEBUG($"Presentation swapchain rebuilt @ {Extent} " +
                   $"(F:{_surfaceFormat.Format}:{_surfaceFormat.ColorSpace==VkKhr.ColorSpaceKhr.SRgbNonlinear} I:{_swapChainImages.Length}:{_syncObjects.MaxInflightFrames}).");
            Dirty = false;
        }
 /// <summary>
 /// Create multiple swapchains that share presentable images.
 /// <para>
 /// Is similar to <see cref="CreateSwapchainKhr"/>, except that it takes an array of <see
 /// cref="SwapchainCreateInfoKhr"/> structures, and returns an array of swapchain objects.
 /// </para>
 /// <para>
 /// The swapchain creation parameters that affect the properties and number of presentable
 /// images must match between all the swapchains.If the displays used by any of the
 /// swapchains do not use the same presentable image layout or are incompatible in a way that
 /// prevents sharing images, swapchain creation will fail with the result code <see
 /// cref="Result.ErrorIncompatibleDisplayKhr"/>. If any error occurs, no swapchains will be
 /// created. Images presented to multiple swapchains must be re-acquired from all of them
 /// before transitioning away from <see cref="ImageLayout.PresentSrcKhr"/>. After destroying
 /// one or more of the swapchains, the remaining swapchains and the presentable images can
 /// continue to be used.
 /// </para>
 /// </summary>
 /// <param name="device">The device to create the swapchains for.</param>
 /// <param name="createInfos">Structures specifying the parameters of the created swapchains.</param>
 /// <param name="allocator">
 /// The allocator used for host memory allocated for the swapchain objects when there is no
 /// more specific allocator available.
 /// </param>
 /// <returns>The created swapchain objects.</returns>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public static SwapchainKhr[] CreateSharedSwapchainsKhr(this Device device,
                                                        SwapchainCreateInfoKhr[] createInfos, AllocationCallbacks?allocator = null)
 {
     return(SwapchainKhr.CreateSharedKhr(device, createInfos, ref allocator));
 }