internal SwapchainKhr(Device parent, ref SwapchainCreateInfoKhr createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;
            Format    = createInfo.ImageFormat;

            long handle;

            createInfo.ToNative(out SwapchainCreateInfoKhr.Native nativeCreateInfo);
            Result result = vkCreateSwapchainKHR(Parent, &nativeCreateInfo, NativeAllocator, &handle);

            nativeCreateInfo.Free();
            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Пример #2
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;
        }
Пример #3
0
 /// <summary>
 /// Create a swapchain.
 /// </summary>
 /// <param name="device">The device to create the swapchain for.</param>
 /// <param name="createInfo">The structure specifying the parameters of the created swapchain.</param>
 /// <param name="allocator">
 /// The allocator used for host memory allocated for the swapchain object when there is no
 /// more specific allocator available.
 /// </param>
 /// <returns>Created swapchain object.</returns>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public static SwapchainKhr CreateSwapchainKhr(this Device device, SwapchainCreateInfoKhr createInfo,
                                               AllocationCallbacks?allocator = null)
 {
     return(new SwapchainKhr(device, ref createInfo, ref allocator));
 }