コード例 #1
0
ファイル: Program.cs プロジェクト: SamHSmith/VulkanRen
        static VkSwapchainKHR CreateSwapchain(VkSwapchainKHR oldSwapchain, VkInstance instance, VkDevice device, VkPhysicalDevice physicalDevice,
                                              VkSurfaceKHR surface, uint queueFamilyIndex)
        {
            vkDestroySwapchainKHR(device, oldSwapchain, null);//Does nothing if oldswapchain is null

            VkSurfaceCapabilitiesKHR capabilities = new VkSurfaceCapabilitiesKHR();

            Assert(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities));

            GetSwapchainFormat(physicalDevice, surface);
            VkSwapchainKHR           swapchain   = VkSwapchainKHR.Null;
            VkSwapchainCreateInfoKHR pCreateInfo = VkSwapchainCreateInfoKHR.New();

            pCreateInfo.surface               = surface;
            pCreateInfo.minImageCount         = capabilities.minImageCount;
            pCreateInfo.imageFormat           = surfaceFormat.format;//SHORTCUT: Some devices might not support
            pCreateInfo.imageColorSpace       = surfaceFormat.colorSpace;
            pCreateInfo.imageExtent           = capabilities.currentExtent;
            pCreateInfo.imageArrayLayers      = 1;
            pCreateInfo.imageUsage            = VkImageUsageFlags.ColorAttachment;
            pCreateInfo.queueFamilyIndexCount = 1;
            pCreateInfo.pQueueFamilyIndices   = &queueFamilyIndex;
            pCreateInfo.preTransform          = VkSurfaceTransformFlagsKHR.IdentityKHR;
            pCreateInfo.compositeAlpha        = VkCompositeAlphaFlagsKHR.OpaqueKHR;
            pCreateInfo.presentMode           = VkPresentModeKHR.MailboxKHR;

            Assert(vkCreateSwapchainKHR(device, &pCreateInfo, null, &swapchain));

            return(swapchain);
        }
コード例 #2
0
        protected override void PlatformSwapBuffers()
        {
            // First, ensure all pending draws are submitted to the proper render passes, and are completed.
            FlushFrameDrawCommands();

            // Then, present the swapchain.
            VkPresentInfoKHR presentInfo = VkPresentInfoKHR.New();

            presentInfo.waitSemaphoreCount = 1;
            // Wait on the last render pass to complete before presenting.
            VkSemaphore signalSemaphore = _renderPassSemaphores[_renderPassStates.Count - 1];

            presentInfo.pWaitSemaphores = &signalSemaphore;

            VkSwapchainKHR swapchain = _scInfo.Swapchain;

            presentInfo.swapchainCount = 1;
            presentInfo.pSwapchains    = &swapchain;
            uint imageIndex = _scInfo.ImageIndex;

            presentInfo.pImageIndices = &imageIndex;

            vkQueuePresentKHR(_presentQueue, ref presentInfo);

            ClearFrameObjects();
            _framebufferChanged = true;
        }
コード例 #3
0
ファイル: Vulkan.cs プロジェクト: bazoocaze/VulkanCpu
        public static VkResult vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapChain, ref int imageCount, VkImage[] swapChainImages)
        {
            VkPreconditions.CheckNull(device, nameof(device));
            VkPreconditions.CheckNull(swapChain, nameof(swapChain));

            return(GetDevice(device).GetSwapchainImages(swapChain, ref imageCount, swapChainImages));
        }
コード例 #4
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);
        }
コード例 #5
0
        private unsafe void DestroySwapchain()
        {
            if (swapChain == VkSwapchainKHR.Null)
            {
                return;
            }

            // stop our presenter thread
            if (presenterThread != null)
            {
                runPresenter = false;
                presentWaiter.Set();
                presenterThread.Join();
            }

            vkQueueWaitIdle(GraphicsDevice.NativeCommandQueue);

            backbuffer.OnDestroyed();

            foreach (var swapchainImage in swapchainImages)
            {
                vkDestroyImageView(GraphicsDevice.NativeDevice, swapchainImage.NativeColorAttachmentView, null);
            }
            swapchainImages = null;

            vkDestroySwapchainKHR(GraphicsDevice.NativeDevice, swapChain, null);
            swapChain = VkSwapchainKHR.Null;
        }
コード例 #6
0
        private unsafe void PresenterThread()
        {
            VkSwapchainKHR   swapChainCopy          = swapChain;
            uint             currentBufferIndexCopy = 0;
            VkPresentInfoKHR presentInfo            = new VkPresentInfoKHR {
                sType          = VkStructureType.PresentInfoKHR,
                swapchainCount = 1,
                pSwapchains    = &swapChainCopy,
                pImageIndices  = &currentBufferIndexCopy,
            };

            while (runPresenter)
            {
                // wait until we have a frame to present
                presentWaiter.Wait();

                // set the frame
                currentBufferIndexCopy = presentFrame;

                // prepare for next frame
                presentWaiter.Reset();

                // are we still OK to present?
                if (runPresenter == false)
                {
                    return;
                }

                using (GraphicsDevice.QueueLock.WriteLock())
                {
                    vkQueuePresentKHR(GraphicsDevice.NativeCommandQueue, &presentInfo);
                }
            }
        }
コード例 #7
0
        public void Render()
        {
            if (!isInitialized)
            {
                return;
            }

            if (this.submitInfos == null)
            {
                InitRenderParams();
            }

            VkDevice    device = this.device; VkSwapchainKHR swapchain = this.swapchain;
            VkSemaphore semaphore = this.vkSemaphore; VkFence fence = this.vkFence;
            VkQueue     queue = this.vkQueue;
            //uint nextIndex = device.AcquireNextImageKHR(swapchain, ulong.MaxValue, semaphore);
            UInt32 nextIndex;

            vkAPI.vkAcquireNextImageKHR(device, swapchain, ulong.MaxValue,
                                        semaphore, new VkFence(), &nextIndex).Check();
            //device.ResetFence(fence);
            vkAPI.vkResetFences(device, 1, &fence).Check();

            //queue.Submit(ref this.submitInfos[nextIndex], fence);
            //VkSubmitInfo submitInfo = this.submitInfos[nextIndex];
            //vkAPI.vkQueueSubmit(queue, 1, &submitInfo, fence).Check();
            vkAPI.vkQueueSubmit(queue, 1, &this.submitInfos[nextIndex], fence).Check();
            //device.WaitForFence(fence, true, 100000000);
            vkAPI.vkWaitForFences(device, 1, &fence, true, 100000000).Check();
            //queue.PresentKHR(ref this.presentInfos[nextIndex]);
            //VkPresentInfoKHR presentInfo = this.presentInfos[nextIndex];
            //vkAPI.vkQueuePresentKHR(queue, &presentInfo).Check();
            vkAPI.vkQueuePresentKHR(queue, &this.presentInfos[nextIndex]).Check();
        }
コード例 #8
0
 public static extern VkResult AcquireNextImageKHR(
     VkDevice device,
     VkSwapchainKHR swapchain,
     ulong timeout,
     VkSemaphore semaphore,
     VkFence fence,
     out uint pImageIndex
     );
コード例 #9
0
ファイル: Vulkan.cs プロジェクト: bazoocaze/VulkanCpu
        public static VkResult vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, long timeout, VkSemaphore semaphore, VkFence fence, out int pImageIndex)
        {
            VkPreconditions.CheckNull(device, nameof(device));
            VkPreconditions.CheckNull(swapchain, nameof(swapchain));
            VkPreconditions.CheckRange(timeout, 1, long.MaxValue, nameof(timeout));

            return(GetDevice(device).AcquireNextImage(swapchain, timeout, semaphore, fence, out pImageIndex));
        }
コード例 #10
0
 public VkResult AcquireNextImage(VkSwapchainKHR swapchain, long timeout, VkSemaphore semaphore, VkFence fence, out int pImageIndex)
 {
     pImageIndex      = m_NextImageIndex;
     m_NextImageIndex = (m_NextImageIndex + 1) % m_Images.Count;
     // semaphore?.Signal();
     // fence?.Signal();
     return(VkResult.VK_SUCCESS);
 }
コード例 #11
0
        public void Create()
        {
            if (state != ActivableState.Activated)
            {
                Activate();
            }

            Dev.WaitIdle();

            VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities(presentQueue.Surface);

            createInfos.minImageCount = capabilities.minImageCount;
            createInfos.preTransform  = capabilities.currentTransform;
            createInfos.oldSwapchain  = handle;

            if (capabilities.currentExtent.width == 0xFFFFFFFF)
            {
                if (createInfos.imageExtent.width < capabilities.minImageExtent.width)
                {
                    createInfos.imageExtent.width = capabilities.minImageExtent.width;
                }
                else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width)
                {
                    createInfos.imageExtent.width = capabilities.maxImageExtent.width;
                }

                if (createInfos.imageExtent.height < capabilities.minImageExtent.height)
                {
                    createInfos.imageExtent.height = capabilities.minImageExtent.height;
                }
                else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height)
                {
                    createInfos.imageExtent.height = capabilities.maxImageExtent.height;
                }
            }
            else
            {
                createInfos.imageExtent = capabilities.currentExtent;
            }

            VkSwapchainKHR newSwapChain = Dev.CreateSwapChain(createInfos);

            if (handle.Handle != 0)
            {
                _destroy();
            }
            handle = newSwapChain;

            VkImage[] tmp = Dev.GetSwapChainImages(handle);
            images = new Image[tmp.Length];
            for (int i = 0; i < tmp.Length; i++)
            {
                images[i] = new Image(Dev, tmp[i], ColorFormat, ImageUsage, Width, Height);
                images[i].CreateView();
                images[i].SetName("SwapChain Img" + i);
                images[i].Descriptor.imageView.SetDebugMarkerName(Dev, "SwapChain Img" + i + " view");
            }
        }
コード例 #12
0
ファイル: Vulkan.cs プロジェクト: bazoocaze/VulkanCpu
        public static void vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapChain, VkAllocationCallbacks pAllocator)
        {
            VkPreconditions.CheckNull(device, nameof(device));

            if (swapChain != null)
            {
                GetDevice(device).DestroySwapchainKHR(swapChain);
            }
        }
コード例 #13
0
        protected virtual void Draw(Timer timer)
        {
            // Acquire an index of drawing image for this frame.
            uint     nextImageIndex;
            VkResult result = vkAcquireNextImageKHR(Context.Device, Swapchain, ulong.MaxValue, ImageAvailableSemaphore, VkFence.Null, out nextImageIndex);

            result.CheckResult();

            // Use a fence to wait until the command buffer has finished execution before using it again
            VkFence fence = SubmitFences[nextImageIndex];

            result = vkWaitForFences(Context.Device, 1, &fence, false, ulong.MaxValue);
            result.CheckResult();

            result = vkResetFences(Context.Device, 1, &fence);
            result.CheckResult();

            VkSemaphore          signalSemaphore = RenderingFinishedSemaphore;
            VkSemaphore          waitSemaphore   = ImageAvailableSemaphore;
            VkPipelineStageFlags waitStages      = VkPipelineStageFlags.ColorAttachmentOutput;
            VkCommandBuffer      commandBuffer   = CommandBuffers[nextImageIndex];

            VkSubmitInfo submitInfo = new VkSubmitInfo()
            {
                sType = VkStructureType.SubmitInfo,
                waitSemaphoreCount   = 1,
                pWaitSemaphores      = &waitSemaphore,
                pWaitDstStageMask    = &waitStages,
                commandBufferCount   = 1,
                pCommandBuffers      = &commandBuffer,
                signalSemaphoreCount = 1,
                pSignalSemaphores    = &signalSemaphore,
            };

            result = vkQueueSubmit(Context.GraphicsQueue, 1, &submitInfo, SubmitFences[nextImageIndex]);
            result.CheckResult();

            // Present the color output to screen.
            VkSemaphore    waitSemaphoreHandle = RenderingFinishedSemaphore;
            VkSwapchainKHR swapchainHandle     = Swapchain;
            var            nativePresentInfo   = new VkPresentInfoKHR
            {
                sType = VkStructureType.PresentInfoKHR,
                pNext = null,
                waitSemaphoreCount = 1,
                pWaitSemaphores    = &waitSemaphoreHandle,
                swapchainCount     = 1,
                pSwapchains        = &swapchainHandle,
                pImageIndices      = &nextImageIndex
            };

            result = vkQueuePresentKHR(Context.PresentQueue, &nativePresentInfo);
            result.CheckResult();
        }
コード例 #14
0
        void drawFrame()
        {
            int imageIndex;

            Vulkan.vkAcquireNextImageKHR(device, swapChain, long.MaxValue, imageAvailableSemaphore, null, out imageIndex);

            VkSubmitInfo submitInfo = new VkSubmitInfo();

            submitInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO;

            VkSemaphore[]             waitSemaphores = new VkSemaphore[] { imageAvailableSemaphore };
            VkPipelineStageFlagBits[] waitStages     = new VkPipelineStageFlagBits[] { VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
            submitInfo.waitSemaphoreCount = 1;
            submitInfo.pWaitSemaphores    = waitSemaphores;
            submitInfo.pWaitDstStageMask  = waitStages;

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = new VkCommandBuffer[] { commandBuffers[imageIndex] };

            VkSemaphore[] signalSemaphores = new VkSemaphore[] { renderFinishedSemaphore };
            submitInfo.signalSemaphoreCount = 1;
            submitInfo.pSignalSemaphores    = signalSemaphores;

            fpsSubmitQueue.Begin();
            VkResult result = Vulkan.vkQueueSubmit(graphicsQueue, 1, new VkSubmitInfo[] { submitInfo }, null);

            fpsSubmitQueue.End(); fpsSubmitQueue.DebugPeriodicReport();

            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to submit draw command buffer!");
            }

            VkPresentInfoKHR presentInfo = new VkPresentInfoKHR();

            presentInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;

            presentInfo.waitSemaphoreCount = 1;
            presentInfo.pWaitSemaphores    = signalSemaphores;

            VkSwapchainKHR[] swapChains = new VkSwapchainKHR[] { swapChain };
            presentInfo.swapchainCount = 1;
            presentInfo.pSwapchains    = swapChains;
            presentInfo.pImageIndices  = new int[] { imageIndex };

            fpsPresentQueue.Begin();
            Vulkan.vkQueuePresentKHR(presentQueue, presentInfo);
            fpsPresentQueue.End(); fpsPresentQueue.DebugPeriodicReport();

            Vulkan.vkQueueWaitIdle(presentQueue);
        }
コード例 #15
0
    public static ReadOnlySpan <VkImage> vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain)
    {
        int swapchainImageCount = 0;

        vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, null).CheckResult();

        ReadOnlySpan <VkImage> swapchainImages = new VkImage[swapchainImageCount];

        fixed(VkImage *swapchainImagesPtr = swapchainImages)
        {
            vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, swapchainImagesPtr).CheckResult();
        }

        return(swapchainImages);
    }
コード例 #16
0
ファイル: VkDevice.cs プロジェクト: Equinox-/CSharpVulkan
        public VkImage[] GetSwapchainImagesKHR(VkSwapchainKHR swapchain)
        {
            unsafe
            {
                VkImage[] props;
                uint      count = 0;
                do
                {
                    props = new VkImage[count];

                    fixed(VkImage *pptr = props)
                    VkException.Check(vkGetSwapchainImagesKHR(this, swapchain, &count, pptr));
                } while (props.Length != count);
                return(props);
            }
        }
コード例 #17
0
ファイル: Device.cs プロジェクト: Svengali/vk.net
        unsafe public VkImage[] GetSwapChainImages(VkSwapchainKHR swapchain)
        {
            uint imageCount = 0;

            Utils.CheckResult(vkGetSwapchainImagesKHR(dev, swapchain, out imageCount, IntPtr.Zero));
            if (imageCount == 0)
            {
                throw new Exception("Swapchain image count is 0.");
            }
            VkImage[] imgs = new VkImage[imageCount];

            Utils.CheckResult(vkGetSwapchainImagesKHR(dev, swapchain, out imageCount, imgs.Pin()));
            imgs.Unpin();

            return(imgs);
        }
コード例 #18
0
        public void Present(SwapChain swapChain, VkSemaphore wait)
        {
            VkPresentInfoKHR present = VkPresentInfoKHR.New();

            uint           idx = swapChain.currentImageIndex;
            VkSwapchainKHR sc  = swapChain.handle;

            present.swapchainCount     = 1;
            present.pSwapchains        = sc.Pin();
            present.waitSemaphoreCount = 1;
            present.pWaitSemaphores    = wait.Pin();
            present.pImageIndices      = idx.Pin();

            Utils.CheckResult(vkQueuePresentKHR(handle, ref present));

            sc.Unpin();
            wait.Unpin();
            idx.Unpin();
        }
コード例 #19
0
        public void Present()
        {
            VkSemaphore    Semaphore   = NativeDevice.RenderFinishedSemaphore;
            VkSwapchainKHR swapchain   = SwapChain;
            CommandList    commandList = NativeDevice.NativeCommandList;

            VkPresentInfoKHR presentInfo = new VkPresentInfoKHR()
            {
                sType = VkStructureType.PresentInfoKHR,
                waitSemaphoreCount = 1,
                pWaitSemaphores    = &Semaphore,
                swapchainCount     = 1,
                pSwapchains        = &swapchain,
                pImageIndices      = Interop.AllocToPointer(ref commandList.imageIndex),
            };


            vkQueuePresentKHR(NativeDevice.NativeCommandQueue, &presentInfo);
        }
コード例 #20
0
        private unsafe void DestroySwapchain()
        {
            if (swapChain == VkSwapchainKHR.Null)
            {
                return;
            }

            vkDeviceWaitIdle(GraphicsDevice.NativeDevice);

            backbuffer.OnDestroyed();

            foreach (var swapchainImage in swapchainImages)
            {
                vkDestroyImageView(GraphicsDevice.NativeDevice, swapchainImage.NativeColorAttachmentView, null);
            }
            swapchainImages = null;

            vkDestroySwapchainKHR(GraphicsDevice.NativeDevice, swapChain, null);
            swapChain = VkSwapchainKHR.Null;
        }
コード例 #21
0
        private VkImage[] GetSwapchainImages(VkSwapchainKHR swapchain)
        {
            uint     swapchainImageCount;
            VkResult result = vkGetSwapchainImagesKHR(Context.Device, swapchain, &swapchainImageCount, null);

            result.CheckResult();

            var swapchainImages = stackalloc VkImage[(int)swapchainImageCount];

            result = vkGetSwapchainImagesKHR(Context.Device, swapchain, &swapchainImageCount, swapchainImages);
            result.CheckResult();

            var images = new VkImage[swapchainImageCount];

            for (int i = 0; i < swapchainImageCount; i++)
            {
                images[i] = swapchainImages[i];
            }
            return(images);
        }
コード例 #22
0
        private void InitRenderParams()
        {
            VkSwapchainKHR swapchain = this.swapchain;
            VkSemaphore    semaphore = this.vkSemaphore;

            VkCommandBuffer[] commandBuffers = this.commandBuffers;

            submitInfos  = VkSubmitInfo.Alloc(2);
            presentInfos = VkPresentInfoKHR.Alloc(2);
            for (uint index = 0; index < 2; index++)
            {
                //submitInfos[index].waitSemaphoresDstStageMasks.Set(semaphore);
                submitInfos[index].waitSemaphores = semaphore;
                submitInfos[index].waitSemaphoresDstStageMasks.Set(VkPipelineStageFlagBits.AllGraphics);
                submitInfos[index].commandBuffers = commandBuffers[index];

                presentInfos[index].swapchains = swapchain;
                //presentInfo->swapchainsImages.Set(swapchain);
                presentInfos[index].swapchainsImages.Set(index);
            }
        }
コード例 #23
0
        public override void SwapBuffers()
        {
            vkQueueWaitIdle(_graphicsQueue); // Meh
            FlushQueuedDisposables();

            // Then, present the swapchain.
            VkPresentInfoKHR presentInfo = VkPresentInfoKHR.New();

            VkSwapchainKHR swapchain = _scFB.Swapchain;

            presentInfo.swapchainCount = 1;
            presentInfo.pSwapchains    = &swapchain;
            uint imageIndex = _scFB.ImageIndex;

            presentInfo.pImageIndices = &imageIndex;

            vkQueuePresentKHR(_presentQueue, ref presentInfo);

            _scFB.AcquireNextImage(_device, VkSemaphore.Null, _imageAvailableFence);
            vkWaitForFences(_device, 1, ref _imageAvailableFence, true, ulong.MaxValue);
            vkResetFences(_device, 1, ref _imageAvailableFence);
        }
コード例 #24
0
        public override unsafe void Present()
        {
            // remember which frame we need to present (for presenting thread)
            VkSwapchainKHR   swapChainCopy          = swapChain;
            uint             currentBufferIndexCopy = currentBufferIndex;
            VkPresentInfoKHR presentInfo            = new VkPresentInfoKHR {
                sType          = VkStructureType.PresentInfoKHR,
                swapchainCount = 1,
                pSwapchains    = &swapChainCopy,
                pImageIndices  = &currentBufferIndexCopy,
            };

            VkResult result = VkResult.Success;

            try {
                result = vkAcquireNextImageKHR(GraphicsDevice.NativeDevice, swapChain, (ulong)0, VkSemaphore.Null, VkFence.Null, out currentBufferIndex);
                vkQueuePresentKHR(GraphicsDevice.NativeCommandQueue, &presentInfo);
            } catch (AccessViolationException ave) {
                Xenko.Graphics.SDL.Window.GeneratePresentError();
            }

            if ((int)result < 0)
            {
                Xenko.Graphics.SDL.Window.GenerateSwapchainError("vkAcquireNextImageKHR result: " + (int)result);
            }

            // did we get another image?
            while ((int)result > 0)
            {
                result = vkAcquireNextImageKHR(GraphicsDevice.NativeDevice, swapChain, (ulong)0, VkSemaphore.Null, VkFence.Null, out currentBufferIndex);
                Thread.Sleep(1);
            }

            // Flip render targets
            backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView);
        }
コード例 #25
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;
        }
コード例 #26
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;
        }
コード例 #27
0
 public static extern VkResult GetSwapchainImagesKHR(
     VkDevice device,
     VkSwapchainKHR swapchain,
     ref uint pSwapchainImageCount,
     IntPtr pSwapchainImages
     );
コード例 #28
0
ファイル: Vulkan.cs プロジェクト: bazoocaze/VulkanCpu
        public static VkResult vkCreateSwapchainKHR(VkDevice device, VkSwapchainCreateInfoKHR pCreateInfo, VkAllocationCallbacks pAllocator, out VkSwapchainKHR pSwapchain)
        {
            VkPreconditions.CheckNull(device, nameof(device));

            return(GetDevice(device).CreateSwapchain(pCreateInfo, out pSwapchain));
        }
コード例 #29
0
        /// <summary>
        /// Create/recreate swapchain and populate images array
        /// </summary>
        public void Create()
        {
            Dev.WaitIdle();

            VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities(presentQueue.Surface);

            createInfos.minImageCount = capabilities.minImageCount;
            createInfos.preTransform  = capabilities.currentTransform;
            createInfos.oldSwapchain  = Handle;

            if (capabilities.currentExtent.width == 0xFFFFFFFF)
            {
                if (createInfos.imageExtent.width < capabilities.minImageExtent.width)
                {
                    createInfos.imageExtent.width = capabilities.minImageExtent.width;
                }
                else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width)
                {
                    createInfos.imageExtent.width = capabilities.maxImageExtent.width;
                }

                if (createInfos.imageExtent.height < capabilities.minImageExtent.height)
                {
                    createInfos.imageExtent.height = capabilities.minImageExtent.height;
                }
                else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height)
                {
                    createInfos.imageExtent.height = capabilities.maxImageExtent.height;
                }
            }
            else
            {
                createInfos.imageExtent = capabilities.currentExtent;
            }

            Utils.CheckResult(vkCreateSwapchainKHR(Dev.VkDev, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain));

            if (Handle.Handle != 0)
            {
                _destroy();
            }

            presentComplete = Dev.CreateSemaphore();
            presentComplete.SetDebugMarkerName(Dev, "Semaphore PresentComplete");
            Handle = newSwapChain;

            Utils.CheckResult(vkGetSwapchainImagesKHR(Dev.VkDev, Handle, out uint imageCount, IntPtr.Zero));
            if (imageCount == 0)
            {
                throw new Exception("Swapchain image count is 0.");
            }
            VkImage[] imgs = new VkImage[imageCount];
            Utils.CheckResult(vkGetSwapchainImagesKHR(Dev.VkDev, Handle, out imageCount, imgs.Pin()));
            imgs.Unpin();

            images = new Image[imgs.Length];
            for (int i = 0; i < imgs.Length; i++)
            {
                images[i] = new Image(Dev, imgs[i], ColorFormat, ImageUsage, Width, Height);
                images[i].CreateView();
                images[i].SetName("SwapChain Img" + i);
                images[i].Descriptor.imageView.SetDebugMarkerName(Dev, "SwapChain Img" + i + " view");
            }
        }
コード例 #30
0
        /**
         * Create the swapchain and get it's Images with given width and height
         *
         * @param width Pointer to the width of the swapchain (may be adjusted to fit the requirements of the swapchain)
         * @param height Pointer to the height of the swapchain (may be adjusted to fit the requirements of the swapchain)
         * @param vsync (Optional) Can be used to force vsync'd rendering (by using VK_PRESENT_MODE_FIFO_KHR as presentation mode)
         */
        public void Create(uint *width, uint *height, bool vsync = false)
        {
            VkResult       err;
            VkSwapchainKHR oldSwapchain = Swapchain;

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

            err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(PhysicalDevice, Surface, &surfCaps);
            Debug.Assert(err == VkResult.Success);

            // Get available present modes
            uint presentModeCount;

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

            using (NativeList <VkPresentModeKHR> presentModes = new NativeList <VkPresentModeKHR>(presentModeCount))
            {
                err = vkGetPhysicalDeviceSurfacePresentModesKHR(PhysicalDevice, Surface, &presentModeCount, (VkPresentModeKHR *)presentModes.Data);
                Debug.Assert(err == VkResult.Success);
                presentModes.Count = presentModeCount;

                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  = *width;
                    swapchainExtent.height = *height;
                }
                else
                {
                    // If the Surface size is defined, the swap chain size must match
                    swapchainExtent = surfCaps.currentExtent;
                    *width  = surfCaps.currentExtent.width;
                    *height = 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 = VkSwapchainCreateInfoKHR.New();
                swapchainCI.pNext           = null;
                swapchainCI.surface         = Surface;
                swapchainCI.minImageCount   = desiredNumberOfSwapchainImages;
                swapchainCI.imageFormat     = ColorFormat;
                swapchainCI.imageColorSpace = ColorSpace;
                swapchainCI.imageExtent     = new VkExtent2D()
                {
                    width = swapchainExtent.width, height = swapchainExtent.height
                };
                swapchainCI.imageUsage            = VkImageUsageFlags.ColorAttachment;
                swapchainCI.preTransform          = preTransform;
                swapchainCI.imageArrayLayers      = 1;
                swapchainCI.imageSharingMode      = VkSharingMode.Exclusive;
                swapchainCI.queueFamilyIndexCount = 0;
                swapchainCI.pQueueFamilyIndices   = null;
                swapchainCI.presentMode           = swapchainPresentMode;
                swapchainCI.oldSwapchain          = oldSwapchain;
                // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area
                swapchainCI.clipped        = True;
                swapchainCI.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR;

                // Set additional usage flag for blitting from the swapchain Images if supported
                VkFormatProperties formatProps;
                vkGetPhysicalDeviceFormatProperties(PhysicalDevice, ColorFormat, out formatProps);
                if ((formatProps.optimalTilingFeatures & VkFormatFeatureFlags.BlitDst) != 0)
                {
                    swapchainCI.imageUsage |= VkImageUsageFlags.TransferSrc;
                }

                VkSwapchainKHR swapChain;
                err = vkCreateSwapchainKHR(Device, &swapchainCI, null, out swapChain);
                Debug.Assert(err == VkResult.Success);
                Swapchain = swapChain;

                // If an existing swap chain is re-created, destroy the old swap chain
                // This also cleans up all the presentable Images
                if (oldSwapchain.Handle != 0)
                {
                    for (uint i = 0; i < ImageCount; i++)
                    {
                        vkDestroyImageView(Device, Buffers[i].View, null);
                    }
                    vkDestroySwapchainKHR(Device, oldSwapchain, null);
                }

                uint imageCount;
                err = vkGetSwapchainImagesKHR(Device, swapChain, &imageCount, null);
                Debug.Assert(err == VkResult.Success);
                ImageCount = imageCount;

                // Get the swap chain Images
                Images.Resize(imageCount);
                err          = vkGetSwapchainImagesKHR(Device, swapChain, &imageCount, (VkImage *)Images.Data.ToPointer());
                Images.Count = imageCount;
                Debug.Assert(err == VkResult.Success);

                // Get the swap chain Buffers containing the image and imageview
                Buffers.Resize(imageCount);
                Buffers.Count = imageCount;
                for (uint i = 0; i < imageCount; i++)
                {
                    VkImageViewCreateInfo colorAttachmentView = new VkImageViewCreateInfo();
                    colorAttachmentView.sType      = VkStructureType.ImageViewCreateInfo;
                    colorAttachmentView.pNext      = null;
                    colorAttachmentView.format     = ColorFormat;
                    colorAttachmentView.components = new VkComponentMapping()
                    {
                        r = VkComponentSwizzle.R,
                        g = VkComponentSwizzle.G,
                        b = VkComponentSwizzle.B,
                        a = VkComponentSwizzle.A
                    };

                    colorAttachmentView.subresourceRange.aspectMask     = VkImageAspectFlags.Color;
                    colorAttachmentView.subresourceRange.baseMipLevel   = 0;
                    colorAttachmentView.subresourceRange.levelCount     = 1;
                    colorAttachmentView.subresourceRange.baseArrayLayer = 0;
                    colorAttachmentView.subresourceRange.layerCount     = 1;
                    colorAttachmentView.viewType = VkImageViewType.Image2D;
                    colorAttachmentView.flags    = 0;

                    Buffers[i].Image = Images[i];

                    colorAttachmentView.image = Buffers[i].Image;

                    VkImageView view;
                    err             = vkCreateImageView(Device, &colorAttachmentView, null, &view);
                    Buffers[i].View = view;
                    Debug.Assert(err == VkResult.Success);
                }
            }
        }