Exemple #1
0
        public void InitializeVulkan()
        {
            var devices = Instance.EnumeratePhysicalDevices();
            var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr {
                Window = aNativeWindow
            });
            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }
            };
            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };
            var physicalDevice = devices [0];

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat       = SelectFormat(physicalDevice, surface);

            swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat);
            var images       = device.GetSwapchainImagesKHR(swapchain);
            var renderPass   = CreateRenderPass(surfaceFormat);
            var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass);

            commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities);
            var fenceInfo = new FenceCreateInfo();

            fences = new Fence [] { device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Exemple #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BindImageMemorySwapchainInfoKhx"/> structure.
 /// </summary>
 /// <param name="swapchain">Is <c>null</c> or a <see cref="SwapchainKhr"/> handle.</param>
 /// <param name="imageIndex">An image index within <see cref="Swapchain"/>.</param>
 /// <param name="next">
 /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure.
 /// </param>
 public BindImageMemorySwapchainInfoKhx(SwapchainKhr swapchain, int imageIndex, IntPtr next = default(IntPtr))
 {
     Type       = StructureType.BindImageMemorySwapchainInfoKhx;
     Next       = next;
     Swapchain  = swapchain;
     ImageIndex = imageIndex;
 }
        /// <summary>
        /// Query the current value of a surface counter.
        /// <para>
        /// The requested counters become active when the first presentation command for the
        /// associated swapchain is processed by the presentation engine.
        /// </para>
        /// </summary>
        /// <param name="swapchain">The swapchain from which to query the counter value.</param>
        /// <param name="counter">The counter to query.</param>
        /// <returns>The current value of the counter.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public static long GetCounterExt(this SwapchainKhr swapchain, SurfaceCountersExt counter)
        {
            long   counterValue;
            Result result = vkGetSwapchainCounterEXT(swapchain.Parent, swapchain, counter, &counterValue);

            VulkanException.ThrowForInvalidResult(result);
            return(counterValue);
        }
        /// <summary>
        /// Obtain the RC duration of the PE's display.
        /// </summary>
        /// <param name="swapchain">The swapchain to obtain the refresh duration for.</param>
        /// <returns>An instance of the <see cref="RefreshCycleDurationGoogle"/> structure.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public static RefreshCycleDurationGoogle GetRefreshCycleDurationGoogle(this SwapchainKhr swapchain)
        {
            RefreshCycleDurationGoogle properties;
            Result result = vkGetRefreshCycleDurationGOOGLE(swapchain)(swapchain.Parent, swapchain, &properties);

            VulkanException.ThrowForInvalidResult(result);
            return(properties);
        }
Exemple #5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AcquireNextImageInfoKhx"/> structure.
 /// </summary>
 /// <param name="swapchain">
 /// The <see cref="SwapchainKhr"/> from which an image is being acquired.
 /// </param>
 /// <param name="timeout">
 /// Indicates how long the function waits, in nanoseconds, if no image is available.
 /// </param>
 /// <param name="semaphore">A <see cref="Semaphore"/> to signal.</param>
 /// <param name="fence">A <see cref="Fence"/> to signal.</param>
 /// <param name="deviceMask">
 /// A mask of physical devices for which the swapchain image will be ready to use when the
 /// semaphore or fence is signaled.
 /// </param>
 /// <param name="next">
 /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure.
 /// </param>
 public AcquireNextImageInfoKhx(SwapchainKhr swapchain, long timeout,
                                Semaphore semaphore = null, Fence fence = null, int deviceMask = 0, IntPtr next = default(IntPtr))
 {
     Type       = StructureType.AcquireNextImageInfoKhx;
     Swapchain  = swapchain;
     Timeout    = timeout;
     Semaphore  = semaphore;
     Fence      = fence;
     DeviceMask = deviceMask;
     Next       = next;
 }
Exemple #6
0
        private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface)
        {
            var  queueFamilyProperties = physDev.GetQueueFamilyProperties();
            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new[] { 1.0f },
                QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_swapchain",
                },
                QueueCreateInfos = new[] { queueInfo }
            };

            _device = physDev.CreateDevice(deviceInfo);

            _queue = _device.GetQueue(0, 0);
            _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectSurfaceFormat(physDev, surface);

            _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat);
            _images       = _device.GetSwapchainImagesKHR(_swapchainKhr);
            _renderPass   = CreateRenderPass(surfaceFormat);
            _framebuffers = CreateFramebuffers(_images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            _fence = _device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore      = _device.CreateSemaphore(semaphoreInfo);
            _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities);
        }
        private void CreateSwapChain()
        {
            var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface);

            SurfaceFormatKhr surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats);
            PresentModeKhr   presentMode   = ChooseSwapPresentMode(swapChainSupport.presentModes);
            Extent2D         extent        = ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.MinImageCount + 1;

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

            var createInfo = new SwapchainCreateInfoKhr()
            {
                MinImageCount    = imageCount,
                ImageFormat      = surfaceFormat.Format,
                ImageColorSpace  = surfaceFormat.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ColorAttachment,
                PreTransform     = swapChainSupport.capabilities.CurrentTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                PresentMode      = presentMode,
                Surface          = vkSurface,
            };

            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            if (indices.GraphicsFamily != indices.PresentFamily)
            {
                createInfo.ImageSharingMode   = SharingMode.Concurrent;
                createInfo.QueueFamilyIndices = new[]
                {
                    (uint)indices.GraphicsFamily,
                    (uint)indices.PresentFamily,
                };
            }
            else
            {
                createInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            vkSwapChain            = vkDevice.CreateSwapchainKHR(createInfo);
            vkSwapChainImages      = vkDevice.GetSwapchainImagesKHR(vkSwapChain);
            vkSwapChainImageFormat = surfaceFormat.Format;
            vkSwapChainExtent      = extent;
        }
Exemple #8
0
        internal void Build()
        {
            GraphicsCommandPool?.Reset();
            ComputeCommandPool?.Reset();

            ImageAvailableSemaphore?.Dispose();
            RenderingFinishedSemaphore?.Dispose();
            Swapchain?.Dispose();

            ImageAvailableSemaphore    = ToDispose(Device.CreateSemaphore());
            RenderingFinishedSemaphore = ToDispose(Device.CreateSemaphore());

            Swapchain = ToDispose(VKHelper.CreateSwapchain(this));
            CacheSwapchainImages();
        }
        /// <summary>
        /// Obtain timing of a previously-presented image.
        /// <para>
        /// The implementation will maintain a limited amount of history of timing information about
        /// previous presents.
        /// </para>
        /// <para>
        /// Because of the asynchronous nature of the presentation engine, the timing information for
        /// a given <see cref="QueueExtensions.PresentKhr(Queue, Semaphore, SwapchainKhr, int)"/>
        /// command will become available some time later.
        /// </para>
        /// <para>These time values can be asynchronously queried, and will be returned if available.</para>
        /// <para>
        /// All time values are in nanoseconds, relative to a monotonically-increasing clock (e.g.
        /// `CLOCK_MONOTONIC` (see clock_gettime(2)) on Android and Linux).
        /// </para>
        /// </summary>
        /// <param name="swapchain">
        /// The swapchain to obtain presentation timing information duration for.
        /// </param>
        /// <returns>An array of <see cref="PastPresentationTimingGoogle"/> structures.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public static PastPresentationTimingGoogle[] GetPastPresentationTimingGoogle(this SwapchainKhr swapchain)
        {
            int    count;
            Result result = vkGetPastPresentationTimingGOOGLE(swapchain)(swapchain.Parent, swapchain, &count, null);

            VulkanException.ThrowForInvalidResult(result);

            var timings = new PastPresentationTimingGoogle[count];

            fixed(PastPresentationTimingGoogle *timingsPtr = timings)
            result = vkGetPastPresentationTimingGOOGLE(swapchain)(swapchain.Parent, swapchain, &count, timingsPtr);

            VulkanException.ThrowForInvalidResult(result);

            return(timings);
        }
Exemple #10
0
        protected void CreateSwapChain()
        {
            format = ChooseFormat(data.formats);
            var presentMode = ChoosePresentMode(data.presentModes);

            extent = ChooseSwapExtent();

            var imageCount = data.surfaceCapabilities.MinImageCount + 1;

            if (data.surfaceCapabilities.MaxImageCount > 0 && imageCount > data.surfaceCapabilities.MaxImageCount)
            {
                imageCount = data.surfaceCapabilities.MaxImageCount;
            }

            var swapChainInfo = new SwapchainCreateInfoKhr
            {
                Surface          = data.surface,
                MinImageCount    = imageCount,
                ImageFormat      = format.Format,
                ImageColorSpace  = format.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ColorAttachment,
                PreTransform     = data.surfaceCapabilities.CurrentTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                PresentMode      = presentMode,
                Clipped          = true
            };
            var indices            = data.queueFamilyIndices;
            var queueFamilyIndices = new uint[] { (uint)indices.GraphicsFamily, (uint)indices.PresentFamily };

            if (indices.PresentFamily != indices.GraphicsFamily)
            {
                swapChainInfo.ImageSharingMode      = SharingMode.Concurrent;
                swapChainInfo.QueueFamilyIndexCount = (uint)queueFamilyIndices.Length;
                swapChainInfo.QueueFamilyIndices    = queueFamilyIndices;
            }
            else
            {
                swapChainInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            swapchain = device.CreateSwapchainKHR(swapChainInfo);

            images     = device.GetSwapchainImagesKHR(swapchain);
            bufferSize = imageCount;
        }
Exemple #11
0
        public void InitializeVulkan()
        {
            var devices = Instance.EnumeratePhysicalDevices();
            var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr {
                Window = aNativeWindow
            });
            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }
            };
            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };
            var physicalDevice = devices [0];

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain = CreateSwapchain(surface, surfaceFormat);
            var images = device.GetSwapchainImagesKHR(swapchain);

            renderPass = CreateRenderPass(surfaceFormat);

            var framebuffers = CreateFramebuffers(images, surfaceFormat);
            var vertexBuffer = CreateBuffer(physicalDevice, Logo.Vertices, BufferUsageFlags.VertexBuffer, typeof(float));
            var indexBuffer  = CreateBuffer(physicalDevice, Logo.Indexes, BufferUsageFlags.IndexBuffer, typeof(short));

            uniformBuffer       = CreateUniformBuffer(physicalDevice);
            descriptorSetLayout = CreateDescriptorSetLayout();
            var pipelines = CreatePipelines();

            descriptorSets = CreateDescriptorSets();
            UpdateDescriptorSets();

            commandBuffers = CreateCommandBuffers(images, framebuffers, pipelines [0], vertexBuffer, indexBuffer, (uint)Logo.Indexes.Length);
            var fenceInfo = new FenceCreateInfo();

            fences = new Fence [] { device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
        public virtual void Initialize(PhysicalDevice physicalDevice, SurfaceKhr surface)
        {
            var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();

            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physicalDevice.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }

                if (queueFamilyProperties [queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain    = CreateSwapchain(surface, surfaceFormat);
            images       = device.GetSwapchainImagesKHR(swapchain);
            renderPass   = CreateRenderPass(surfaceFormat);
            framebuffers = CreateFramebuffers(images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            fence = device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
Exemple #13
0
        public static bool TryCreateSwapChain(Instance instance, PhysicalDevice physicalDevice, Device device,
                                              SurfaceKhr surface, uint queue, ref System.Drawing.Size size,
                                              Format format, ColorSpaceKhr colorSpace, PresentModeKhr presentMode,
                                              ref SwapchainKhr swapchain)
        {
            SwapchainCreateInfoKhr swapChainCreateInfo = new SwapchainCreateInfoKhr
            {
                Surface            = surface,
                MinImageCount      = 2,
                ImageFormat        = format,
                ImageColorSpace    = colorSpace,
                ImageExtent        = ToExtent2D(size),
                ImageArrayLayers   = 1,
                ImageUsage         = ImageUsageFlags.ColorAttachment,
                ImageSharingMode   = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queue },
                PreTransform       = SurfaceTransformFlagsKhr.Inherit,
                CompositeAlpha     = CompositeAlphaFlagsKhr.Opaque, // TODO : set this to Ingerit if it can be fixed in Check
                PresentMode        = presentMode,
                Clipped            = false,
                OldSwapchain       = swapchain,
            };

            if (!CheckSwapchainCreateInfo(physicalDevice, swapChainCreateInfo, true))
            {
                return(false);
            }

            size.Width  = (int)swapChainCreateInfo.ImageExtent.Width;
            size.Height = (int)swapChainCreateInfo.ImageExtent.Height;

            SwapchainKhr newSwapchain = device.CreateSwapchainKHR(swapChainCreateInfo);

            if (newSwapchain != null)
            {
                swapchain = newSwapchain;
                return(true);
            }
            return(false);
        }
Exemple #14
0
        private void InitializeVulkan()
        {
            var devices = _instance.EnumeratePhysicalDevices();
            var surface = _instance.CreateWin32SurfaceKHR(
                new Win32SurfaceCreateInfoKhr
            {
                Hinstance = Instance,
                Hwnd      = Handle
            });
            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new [] { 1.0f }
            };
            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new [] { "VK_KHR_swapchain" },
                QueueCreateInfos      = new [] { queueInfo }
            };
            var physicalDevice = devices [0];

            _device = physicalDevice.CreateDevice(deviceInfo);
            _queue  = _device.GetQueue(0, 0);

            var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat       = SelectFormat(physicalDevice, surface);

            _swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat);
            var images       = _device.GetSwapchainImagesKHR(_swapchain);
            var renderPass   = CreateRenderPass(surfaceFormat);
            var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass);

            _commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities);
            var fenceInfo = new FenceCreateInfo();

            _fences = new [] { _device.CreateFence(fenceInfo) };
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore = _device.CreateSemaphore(semaphoreInfo);

            _initialized = true;
        }
Exemple #15
0
        public bool CreateSwapChain(DrunkSpock spock,
                                    int extentX, int extentY)
        {
            PhysicalDevice phys = mLogical.Parent;
            SurfaceKhr     surf = spock.GetSurface();

            SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf);

            SurfaceFormatKhr                [] surfFormats = phys.GetSurfaceFormatsKhr(surf);
            PresentModeKhr                  [] presModes   = phys.GetSurfacePresentModesKhr(surf);

            if (surfFormats.Length <= 0 || presModes.Length <= 0)
            {
                Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes...");
                return(false);
            }

            mSwapExtent = new Extent2D(extentX, extentY);

            int imageCount = surfCaps.MinImageCount + 1;

            if (surfCaps.MaxImageCount > 0 && imageCount > surfCaps.MaxImageCount)
            {
                imageCount = surfCaps.MaxImageCount;
            }

            SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr(
                surf, Format.B8G8R8A8UNorm, mSwapExtent,
                imageCount, ColorSpaceKhr.SRgbNonlinear, 1,
                ImageUsages.ColorAttachment);

            scci.ImageSharingMode = SharingMode.Exclusive;

            if (presModes.Contains(PresentModeKhr.Mailbox))
            {
                scci.PresentMode = PresentModeKhr.Mailbox;
            }

            mSwapChain = mLogical.CreateSwapchainKhr(scci);
            if (mSwapChain == null)
            {
                Misc.SafeInvoke(eErrorSpam, "Create swap chain failed...");
                return(false);
            }

            VulkanCore.Image        [] chainImages = mSwapChain.GetImages();

            mChainImageViews = new ImageView[chainImages.Length];

            for (int i = 0; i < chainImages.Length; i++)
            {
                ImageSubresourceRange isr = new ImageSubresourceRange(
                    ImageAspects.Color, 0, 1, 0, 1);

                ImageViewCreateInfo ivci = new ImageViewCreateInfo(
                    mSwapChain.Format, isr);

                mChainImageViews[i] = chainImages[i].CreateView(ivci);
            }

            //descriptor pool stuff
            DescriptorPoolSize dps = new DescriptorPoolSize(
                DescriptorType.UniformBuffer, chainImages.Length);

            DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo();

            dpci.PoolSizes = new DescriptorPoolSize[] { dps };
            dpci.MaxSets   = chainImages.Length;

            mDPool = mLogical.CreateDescriptorPool(dpci);

            return(true);
        }
Exemple #16
0
        public void CreateSwapChain(PresentModeKhr presentMode, uint imageCount)
        {
            SwapchainKhr oldSwapChain = SwapChain;

            if (SwapSurface == null)
            {
                // == Create Surface for Swap Chain
                IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module);

                Win32SurfaceCreateInfoKhr surfaceInfo = new Win32SurfaceCreateInfoKhr()
                {
                    Hwnd      = window.Handle,
                    Flags     = 0,
                    Hinstance = hInstance,
                };

                SurfaceKhr surface = Instance.CreateWin32SurfaceKHR(surfaceInfo, null);

                QueueInfo graphicsQueueInfo = GetQueue(QueueFlags.Graphics);
                Queue     graphicsQueue     = Device.GetQueue(graphicsQueueInfo.queueFamilyIndex, graphicsQueueInfo.queueIndex);

                SwapSurface = surface;
            }

            // == Create Swap Chain

            // TODO : this is bugged in Vulkan-Mono PresentModeKhr can not be called from Marshal.SizeOf

            /*bool presentModeSupported = false;
             * PresentModeKhr[] presentModes = Gpu.GetSurfacePresentModesKHR(SwapSurface);
             * foreach (PresentModeKhr checkMode in presentModes)
             * {
             *  if(checkMode == presentMode)
             *  {
             *      presentModeSupported = true;
             *      break;
             *  }
             * }
             * if(!presentModeSupported )
             * {
             *  throw new Exception("PresentMode :" + presentMode + " not supported by gpu.");
             * }*/

            SurfaceCapabilitiesKhr surfaceCapabilities = Gpu.GetSurfaceCapabilitiesKHR(SwapSurface);

            if (surfaceCapabilities.CurrentExtent.Width == uint.MaxValue)
            {
                BackBufferWidth  = (uint)window.Width;
                BackBufferHeight = (uint)window.Height;
            }
            else
            {
                BackBufferWidth  = surfaceCapabilities.CurrentExtent.Width;
                BackBufferHeight = surfaceCapabilities.CurrentExtent.Height;
            }

            uint reqImageCount = surfaceCapabilities.MinImageCount + imageCount;

            if (reqImageCount > 0 && reqImageCount > surfaceCapabilities.MaxImageCount)
            {
                reqImageCount = surfaceCapabilities.MaxImageCount;
            }


            SurfaceFormatKhr[] surfaceFormats = Gpu.GetSurfaceFormatsKHR(SwapSurface);
            Format             format         = surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined ?
                                                Format.B8g8r8a8Unorm : surfaceFormats[0].Format;
            SurfaceTransformFlagsKhr preTransform = (surfaceCapabilities.SupportedTransforms & SurfaceTransformFlagsKhr.Identity) == SurfaceTransformFlagsKhr.Identity ?
                                                    SurfaceTransformFlagsKhr.Identity : surfaceCapabilities.CurrentTransform;

            SwapchainCreateInfoKhr swapChainInfo = new SwapchainCreateInfoKhr
            {
                Surface         = SwapSurface,
                MinImageCount   = reqImageCount,
                ImageFormat     = format,
                ImageColorSpace = surfaceFormats[0].ColorSpace,
                ImageExtent     = new Extent2D
                {
                    Width  = BackBufferWidth,
                    Height = BackBufferHeight,
                },
                ImageUsage       = (uint)ImageUsageFlags.ColorAttachment,
                PreTransform     = preTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                ImageArrayLayers = 1,
                ImageSharingMode = SharingMode.Exclusive,
                PresentMode      = presentMode,
                // TODO : Vulkan : we cant assing a null swapChain
                //OldSwapchain = oldSwapChain != null ? oldSwapChain : null,
                Clipped = true,
            };

            if (oldSwapChain != null)
            {
                // this is a workaround as we cant assing a null one
                swapChainInfo.OldSwapchain = oldSwapChain;

                Device.DestroySwapchainKHR(oldSwapChain, null);
                oldSwapChain = null;
            }

            SwapchainKhr swapChain = Device.CreateSwapchainKHR(swapChainInfo, null);

            // ==  Create Images

            Image[] swapImages = Device.GetSwapchainImagesKHR(swapChain);

            SwapChainBuffer[] buffers = new SwapChainBuffer[swapImages.Length];
            for (uint i = 0; i < buffers.Length; i++)
            {
                ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo
                {
                    Format     = format,
                    Components = new ComponentMapping
                    {
                        R = ComponentSwizzle.R,
                        G = ComponentSwizzle.G,
                        B = ComponentSwizzle.B,
                        A = ComponentSwizzle.A,
                    },
                    SubresourceRange = new ImageSubresourceRange
                    {
                        AspectMask     = (uint)ImageAspectFlags.Color,
                        BaseMipLevel   = 1,
                        BaseArrayLayer = 0,
                        LayerCount     = 1,
                    },
                    ViewType = ImageViewType.View2D,
                    Flags    = 0,
                    Image    = swapImages[i],
                };

                ImageView view = Device.CreateImageView(imageViewInfo, null);

                buffers[i] = new SwapChainBuffer
                {
                    image = swapImages[i],
                    view  = view,
                };
            }
        }
 private static vkGetPastPresentationTimingGOOGLEDelegate vkGetPastPresentationTimingGOOGLE(SwapchainKhr swapchain) => GetProc <vkGetPastPresentationTimingGOOGLEDelegate>(swapchain, nameof(vkGetPastPresentationTimingGOOGLE));
 private static vkGetRefreshCycleDurationGOOGLEDelegate vkGetRefreshCycleDurationGOOGLE(SwapchainKhr swapchain) => GetProc <vkGetRefreshCycleDurationGOOGLEDelegate>(swapchain, nameof(vkGetRefreshCycleDurationGOOGLE));
 private static TDelegate GetProc <TDelegate>(SwapchainKhr swapchain, string name) where TDelegate : class => swapchain.Parent.GetProc <TDelegate>(name);
Exemple #20
0
        private static Frame[] GetFrames(Device device, SwapchainKhr swapchain, Extent2D imageSize, RenderPass renderpass)
        {
            var images = device.GetSwapchainImagesKHR(swapchain);

            return(images.Select(image => new Frame(image, device, imageSize, renderpass)).ToArray());
        }
Exemple #21
0
        private void CreateSwapchain(int swapchainCount)
        {
            SurfaceCapabilitiesKhr capabilities = hostDevice.GetCurrentCapabilities(surface);

            //Clamp the size to within the min and max extends reported by the surface capabilities
            swapchainSize = nativeWindow.ClientRect.Size.Clamp(
                new Int2(capabilities.MinImageExtent.Width, capabilities.MinImageExtent.Height),
                new Int2(capabilities.MaxImageExtent.Width, capabilities.MaxImageExtent.Height));

            //Gather info about the swapchain
            var createInfo = new SwapchainCreateInfoKhr
                             (
                surface: surface,
                minImageCount: swapchainCount,
                imageFormat: surfaceFormat,
                imageColorSpace: surfaceColorspace,
                imageExtent: new Extent2D(swapchainSize.X, swapchainSize.Y),
                imageArrayLayers: 1,
                imageUsage: ImageUsages.ColorAttachment,

                //If the graphics and present queues are different we need to allow sharing the
                //swapchain images
                imageSharingMode: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                SharingMode.Exclusive : SharingMode.Concurrent,
                queueFamilyIndices: graphicsQueue.FamilyIndex == presentQueue.FamilyIndex ?
                null : new [] { graphicsQueue.FamilyIndex, presentQueue.FamilyIndex },

                preTransform: capabilities.CurrentTransform,
                compositeAlpha: CompositeAlphasKhr.Opaque,
                presentMode: presentMode,
                clipped: true
                             );

            //Create the swapchain
            swapchain = logicalDevice.CreateSwapchainKhr(createInfo);
            var swapchainImages = swapchain.GetImages();

            //Verify that we got the amount of images we expected
            if (swapchainImages.Length != swapchainCount)
            {
                throw new Exception(
                          $"[{nameof(Window)}] Incorrect number of swapchain images acquired, expected: {swapchainCount}, got: {swapchainImages.Length}");
            }

            //Create the image targets
            swapchainTextures = new DeviceTexture[swapchainCount];
            for (int i = 0; i < swapchainTextures.Length; i++)
            {
                swapchainTextures[i] = DeviceTexture.CreateSwapchainTarget(
                    swapchainSize, surfaceFormat, swapchainImages[i]);
            }

            logger?.Log(nameof(Window),
                        $@"Swapchain created:
{{
    size: {swapchainSize},
    texCount: {swapchainTextures.Length},
    mode: {presentMode},
    format: {surfaceFormat},
    colorSpace: {surfaceColorspace}
}}");
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ImageSwapchainCreateInfoKhx"/> structure.
 /// </summary>
 /// <param name="swapchain">
 /// Is <c>null</c> or a handle of an <see cref="SwapchainKhr"/> that the image will be bound to.
 /// </param>
 /// <param name="next">
 /// Is <see cref="IntPtr.Zero"/> or a pointer to an extension-specific structure.
 /// </param>
 public ImageSwapchainCreateInfoKhx(SwapchainKhr swapchain, IntPtr next = default(IntPtr))
 {
     Type      = StructureType.ImageSwapchainCreateInfoKhx;
     Next      = next;
     Swapchain = swapchain;
 }
Exemple #23
0
 private static vkGetSwapchainCounterEXTDelegate vkGetSwapchainCounterEXT(SwapchainKhr swapchain) => swapchain.Parent.GetProc <vkGetSwapchainCounterEXTDelegate>(nameof(vkGetSwapchainCounterEXT));
Exemple #24
0
 internal static unsafe extern Result vkAcquireNextImageKHR(Device device, SwapchainKhr swapchain, UInt64 timeout, Semaphore semaphore, Fence fence, out UInt32 *ImageIndex);
Exemple #25
0
 internal static unsafe extern Result vkGetSwapchainImagesKHR(Device device, SwapchainKhr swapchain, out UInt32 *SwapchainImageCount, out IntPtr pSwapchainImages);
Exemple #26
0
 internal static unsafe extern void vkDestroySwapchainKHR(Device device, SwapchainKhr swapchain, AllocationCallbacks *Allocator);
Exemple #27
0
            void InitSwapChain()
            {
                surface = VulkanInitUtility.CreateSurface(instance, window);

                // TODO : try to use a linear format
                // TODO : dount just guest the queue
                surfaceFormat = Format.B8G8R8A8Unorm;
                surfaceSize   = window.Size;
                if (!VulkanInitUtility.TryCreateSwapChain(instance, physicalDevice, device, surface, (uint)0, ref surfaceSize,
                                                          surfaceFormat, ColorSpaceKhr.SrgbNonlinear, PresentModeKhr.Fifo, ref swapChain))
                {
                    throw new Exception("Failed to create swap chain");
                }

                swapChainSemphore = device.CreateSemaphore(new SemaphoreCreateInfo {
                });

                // create Images and Image Views

                swapchainImages     = device.GetSwapchainImagesKHR(swapChain);
                swapchainImageViews = new ImageView[swapchainImages.Length];

                int i = 0;

                foreach (Image image in swapchainImages)
                {
                    ImageView view = device.CreateImageView(new ImageViewCreateInfo
                    {
                        Image      = image,
                        Format     = surfaceFormat,
                        ViewType   = ImageViewType.View2D,
                        Components = new ComponentMapping
                        {
                            R = ComponentSwizzle.Identity,
                            G = ComponentSwizzle.Identity,
                            B = ComponentSwizzle.Identity,
                            A = ComponentSwizzle.Identity,
                        },
                        SubresourceRange = new ImageSubresourceRange
                        {
                            AspectMask     = ImageAspectFlags.Color,
                            LayerCount     = 1,
                            LevelCount     = 1,
                            BaseMipLevel   = 0,
                            BaseArrayLayer = 0,
                        },
                    });

                    swapchainImageViews[i] = view;
                    i++;
                }

                cleanupStack.Push(() => {
                    foreach (ImageView imageView in swapchainImageViews)
                    {
                        device.DestroyImageView(imageView);
                    }

                    device.DestroySemaphore(swapChainSemphore);
                    swapChainSemphore = null;

                    device.DestroySwapchainKHR(swapChain);
                    swapChain = null;

                    instance.DestroySurfaceKHR(surface);
                    surface = null;
                });
            }
 /// <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));
 }
Exemple #29
0
		public void Create(CommandBuffer commandBuffer) {
			var surfaceCapabilities = PhysicalDevice.GetSurfaceCapabilitiesKHR(Surface);
			Extent2D swapChainExtend = new Extent2D {
				Width = surfaceCapabilities.CurrentExtent.Width,
				Height = surfaceCapabilities.CurrentExtent.Height
			};

			var presentModes = PhysicalDevice.GetSurfacePresentModesKHR(Surface);
			PresentModeKhr presentMode = GetBestPresentMode(presentModes);

			var desiredImages = surfaceCapabilities.MinImageCount + 1;
			if (surfaceCapabilities.MaxImageCount > 0 && desiredImages > surfaceCapabilities.MaxImageCount) {
				desiredImages = surfaceCapabilities.MaxImageCount;
			}

			var preTransform = surfaceCapabilities.CurrentTransform;
			if (surfaceCapabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKhr.Identity)) {
				preTransform = SurfaceTransformFlagsKhr.Identity;
			}

			var oldSwapChain = Swapchain;
			var swapChainCreateInfo = new SwapchainCreateInfoKhr {
				Surface = Surface,
				MinImageCount = desiredImages,
				ImageFormat = ColorFormat,
				ImageColorSpace = ColorSpace,
				ImageExtent = swapChainExtend,
				ImageUsage = ImageUsageFlags.ColorAttachment,
				PreTransform = preTransform,
				ImageArrayLayers = 1,
				ImageSharingMode = SharingMode.Exclusive,
				QueueFamilyIndexCount = 0,
				QueueFamilyIndices = null,
				PresentMode = presentMode,
				Clipped = true,

				// Alpha on the window surface should be opaque:
				// If it was not we could create transparent regions of our window which
				// would require support from the Window compositor. You can totally do
				// that if you wanted though ;)
				CompositeAlpha = CompositeAlphaFlagsKhr.Opaque
			};
			Swapchain = Device.CreateSwapchainKHR(swapChainCreateInfo);

			if (oldSwapChain != null) {
				Device.DestroySwapchainKHR(oldSwapChain);
			}

			Images = Device.GetSwapchainImagesKHR(Swapchain).ToList();

			// Create the image views for the swap chain. They will all be single
			// layer, 2D images, with no mipmaps.
			// Check the VkImageViewCreateInfo structure to see other views you
			// can potentially create.
			for (var i = 0; i < Images.Count; i++) {
				var buffer = new SwapChainBuffer();

				var colorAttachmentView = new ImageViewCreateInfo {
					Format = ColorFormat,
					Components = new ComponentMapping {
						R = ComponentSwizzle.R,
						G = ComponentSwizzle.G,
						B = ComponentSwizzle.B,
						A = ComponentSwizzle.A
					},
					SubresourceRange = new ImageSubresourceRange {
						AspectMask = ImageAspectFlags.Color,
						BaseMipLevel = 0,
						LevelCount = 1,
						BaseArrayLayer = 0,
						LayerCount = 1
					},
					ViewType = ImageViewType.View2D
				};
				buffer.Image = Images[i];
				SetImageLayout(commandBuffer, buffer.Image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSrcKhr);
				buffer.View = Device.CreateImageView(colorAttachmentView);
				Buffers.Add(buffer);
			}
		}