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; }
public override unsafe void Present() { var swapChainCopy = swapChain; var currentBufferIndexCopy = currentBufferIndex; var presentInfo = new VkPresentInfoKHR { sType = VkStructureType.PresentInfoKHR, swapchainCount = 1, pSwapchains = &swapChainCopy, pImageIndices = ¤tBufferIndexCopy, }; // Present if (vkQueuePresentKHR(GraphicsDevice.NativeCommandQueue, &presentInfo) == VkResult.ErrorOutOfDateKHR) { // TODO VULKAN return; } // Get next image if (vkAcquireNextImageKHR(GraphicsDevice.NativeDevice, swapChain, ulong.MaxValue, GraphicsDevice.GetNextPresentSemaphore(), VkFence.Null, out currentBufferIndex) == VkResult.ErrorOutOfDateKHR) { // TODO VULKAN return; } // Flip render targets backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView); }
private unsafe void PresenterThread() { VkSwapchainKHR swapChainCopy = swapChain; uint currentBufferIndexCopy = 0; VkPresentInfoKHR presentInfo = new VkPresentInfoKHR { sType = VkStructureType.PresentInfoKHR, swapchainCount = 1, pSwapchains = &swapChainCopy, pImageIndices = ¤tBufferIndexCopy, }; 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); } } }
public VkResult Present(VkPresentInfoKHR pPresentInfo) { if (pPresentInfo.waitSemaphoreCount > 0) { SoftwareSemaphore.WaitAll(pPresentInfo.waitSemaphoreCount, pPresentInfo.pWaitSemaphores); } if (pPresentInfo.pResults == null) { pPresentInfo.pResults = new VkResult[] { } } ; while (pPresentInfo.pResults.Length < pPresentInfo.swapchainCount) { pPresentInfo.pResults = new VkResult[] { VkResult.VK_SUCCESS } } ; VkResult result = VkResult.VK_SUCCESS; for (int i = 0; i < pPresentInfo.swapchainCount; i++) { int imageIndex = pPresentInfo.pImageIndices[i]; var swapChain = (SoftwareSwapchain)pPresentInfo.pSwapchains[i]; VkResult subResult = swapChain.PresentImage(imageIndex); pPresentInfo.pResults[i] = subResult; if (subResult != VkResult.VK_SUCCESS) { result = subResult; } } return(result); }
public void PresentKHR(SwapchainKHR swapchain, uint imageIndex, VkSemaphore[] waitSemaphores) { AssertValid(); unsafe { swapchain.AssertValid(); var swapHandle = swapchain.Handle; fixed(VkSemaphore *waitPtr = waitSemaphores) { var result = VkResult.ErrorDeviceLost; var info = new VkPresentInfoKHR() { SType = VkStructureType.PresentInfoKhr, PNext = IntPtr.Zero, SwapchainCount = 1, PSwapchains = &swapHandle, PImageIndices = &imageIndex, WaitSemaphoreCount = (uint)(waitSemaphores?.Length ?? 0), PWaitSemaphores = waitPtr, PResults = &result }; Handle.QueuePresentKHR(&info); VkException.Check(result); } } }
/// <summary>Presents the last frame rendered.</summary> public void PresentFrame() { var frameIndex = _frameIndex; var waitSemaphore = QueueSubmitSemaphore; var swapChain = SwapChain; var signalSemaphore = QueueSubmitSemaphore; var presentInfo = new VkPresentInfoKHR { sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, pNext = null, waitSemaphoreCount = 1, pWaitSemaphores = &waitSemaphore, swapchainCount = 1, pSwapchains = &swapChain, pImageIndices = &frameIndex, pResults = null, }; var result = vkQueuePresentKHR(DeviceQueue, &presentInfo); if (result != VK_SUCCESS) { ThrowExternalException(nameof(vkQueuePresentKHR), (int)result); } result = vkQueueSubmit(DeviceQueue, submitCount: 0, pSubmits: null, Fences[frameIndex]); if (result != VK_SUCCESS) { ThrowExternalException(nameof(vkQueueSubmit), (int)result); } }
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(); }
/** * Queue an image for presentation * * @param queue Presentation queue for presenting the image * @param imageIndex Index of the swapchain image to queue for presentation * @param waitSemaphore (Optional) Semaphore that is waited on before the image is presented (only used if != VK_NULL_HANDLE) * * @return VkResult of the queue presentation */ public VkResult QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = new VkSemaphore()) { var presentInfo = VkPresentInfoKHR.Alloc(); presentInfo->swapchainsImages.Set(Swapchain); presentInfo->swapchainsImages.Set(imageIndex); // Check if a wait semaphore has been specified to wait for before presenting the image if (waitSemaphore != 0ul) { presentInfo->waitSemaphores = waitSemaphore; } return(vkQueuePresentKHR(queue, presentInfo)); }
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); }
public VkResult Present(PresentInfo info) { unsafe { var waitSemaphoresNative = stackalloc VkSemaphore[info.waitSemaphores.Count]; Interop.Marshal <VkSemaphore, Semaphore>(info.waitSemaphores, waitSemaphoresNative); var swapchainsNative = stackalloc VkSwapchainKHR[info.swapchains.Count]; Interop.Marshal <VkSwapchainKHR, Swapchain>(info.swapchains, swapchainsNative); int indicesCount = 0; if (info.imageIndices != null) { indicesCount = info.imageIndices.Count; } uint *imageIndices = stackalloc uint[info.imageIndices.Count]; for (int i = 0; i < info.imageIndices.Count; i++) { imageIndices[i] = info.imageIndices[i]; } int resultsLength = 0; if (info.results != null) { resultsLength = info.results.Count; } var results = stackalloc int[resultsLength]; var infoNative = new VkPresentInfoKHR(); infoNative.sType = VkStructureType.PresentInfoKhr; infoNative.waitSemaphoreCount = (uint)info.waitSemaphores.Count; infoNative.pWaitSemaphores = (IntPtr)waitSemaphoresNative; infoNative.swapchainCount = (uint)info.swapchains.Count; infoNative.pSwapchains = (IntPtr)swapchainsNative; infoNative.pImageIndices = (IntPtr)imageIndices; var result = Device.Commands.queuePresent(queue, ref infoNative); for (int i = 0; i < resultsLength; i++) //already determined if null { info.results[i] = (VkResult)results[i]; } return(result); } }
private void DrawFrame() { // Acquiring and image from the swap chain uint imageIndex; Helpers.CheckErrors(VulkanNative.vkAcquireNextImageKHR(this.device, this.swapChain, ulong.MaxValue, this.imageAvailableSemaphore, 0, &imageIndex)); // Submitting the command buffer VkSemaphore * waitSemaphores = stackalloc VkSemaphore[] { this.imageAvailableSemaphore }; VkPipelineStageFlags *waitStages = stackalloc VkPipelineStageFlags[] { VkPipelineStageFlags.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSemaphore * signalSemaphores = stackalloc VkSemaphore[] { this.renderFinishedSemaphore }; VkCommandBuffer * commandBuffersPtr = stackalloc VkCommandBuffer[] { commandBuffers[imageIndex] }; VkSubmitInfo submitInfo = new VkSubmitInfo() { sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO, waitSemaphoreCount = 1, pWaitSemaphores = waitSemaphores, pWaitDstStageMask = waitStages, commandBufferCount = 1, pCommandBuffers = commandBuffersPtr, signalSemaphoreCount = 1, pSignalSemaphores = signalSemaphores, }; Helpers.CheckErrors(VulkanNative.vkQueueSubmit(this.graphicsQueue, 1, &submitInfo, 0)); // Presentation VkSwapchainKHR * swapChains = stackalloc VkSwapchainKHR[] { this.swapChain }; VkPresentInfoKHR presentInfo = new VkPresentInfoKHR() { sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, waitSemaphoreCount = 1, pWaitSemaphores = signalSemaphores, swapchainCount = 1, pSwapchains = swapChains, pImageIndices = &imageIndex, pResults = null, // Optional }; Helpers.CheckErrors(VulkanNative.vkQueuePresentKHR(this.presentQueue, &presentInfo)); Helpers.CheckErrors(VulkanNative.vkQueueWaitIdle(this.presentQueue)); } } }
/** * Queue an image for presentation * * @param queue Presentation queue for presenting the image * @param imageIndex Index of the swapchain image to queue for presentation * @param waitSemaphore (Optional) Semaphore that is waited on before the image is presented (only used if != VK_NULL_HANDLE) * * @return VkResult of the queue presentation */ public VkResult QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = new VkSemaphore()) { VkPresentInfoKHR presentInfo = VkPresentInfoKHR.New(); presentInfo.pNext = null; presentInfo.swapchainCount = 1; var sc = Swapchain; presentInfo.pSwapchains = ≻ presentInfo.pImageIndices = &imageIndex; // Check if a wait semaphore has been specified to wait for before presenting the image if (waitSemaphore.Handle != 0) { presentInfo.pWaitSemaphores = &waitSemaphore; presentInfo.waitSemaphoreCount = 1; } return(vkQueuePresentKHR(queue, &presentInfo)); }
public void DrawFrame() { var result = VulkanNative.vkQueueWaitIdle(vkPresentQueue); Helpers.CheckErrors(result); uint imageIndex; result = VulkanNative.vkAcquireNextImageKHR(vkDevice, vkSwapChain, ulong.MaxValue, vkImageAvailableSemaphore, 0, &imageIndex); Helpers.CheckErrors(result); VkSemaphore * waitSemaphores = stackalloc VkSemaphore[] { vkImageAvailableSemaphore }; VkPipelineStageFlagBits *waitStages = stackalloc VkPipelineStageFlagBits[] { VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkSemaphore * signalSemaphores = stackalloc VkSemaphore[] { vkRenderFinishedSemaphore }; VkCommandBuffer * commandBuffers = stackalloc VkCommandBuffer[] { vkCommandBuffers[imageIndex] }; var submitInfo = new VkSubmitInfo() { sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO, pWaitSemaphores = waitSemaphores, waitSemaphoreCount = 1, pWaitDstStageMask = waitStages, commandBufferCount = 1, pCommandBuffers = commandBuffers, signalSemaphoreCount = 1, pSignalSemaphores = signalSemaphores, }; result = VulkanNative.vkQueueSubmit(vkGraphicsQueue, 1, &submitInfo, 0); Helpers.CheckErrors(result); VkSwapchainKHR *swapChains = stackalloc VkSwapchainKHR[] { vkSwapChain }; var presentInfo = new VkPresentInfoKHR() { sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, waitSemaphoreCount = 1, pWaitSemaphores = signalSemaphores, swapchainCount = 1, pSwapchains = swapChains, pImageIndices = &imageIndex, }; result = VulkanNative.vkQueuePresentKHR(vkPresentQueue, &presentInfo); Helpers.CheckErrors(result); }
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); }
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(); }
public VkResult Present(PresentInfo info) { unsafe { var waitSemaphoresNative = stackalloc VkSemaphore[info.waitSemaphores.Count]; Interop.Marshal <VkSemaphore, Semaphore>(info.waitSemaphores, waitSemaphoresNative); //swapchains, indices, and results must have the same length int swapchainCount = info.swapchains.Count; var swapchainsNative = stackalloc VkSwapchainKHR[swapchainCount]; Interop.Marshal <VkSwapchainKHR, Swapchain>(info.swapchains, swapchainsNative); uint *imageIndices = stackalloc uint[swapchainCount]; Interop.Copy(info.imageIndices, (IntPtr)imageIndices); int resultsLength = 0; if (info.results != null) //user may not request results { resultsLength = swapchainCount; } var results = stackalloc int[resultsLength]; var infoNative = new VkPresentInfoKHR(); infoNative.sType = VkStructureType.PresentInfoKhr; infoNative.waitSemaphoreCount = (uint)info.waitSemaphores.Count; infoNative.pWaitSemaphores = (IntPtr)waitSemaphoresNative; infoNative.swapchainCount = (uint)swapchainCount; infoNative.pSwapchains = (IntPtr)swapchainsNative; infoNative.pImageIndices = (IntPtr)imageIndices; var result = Device.Commands.queuePresent(queue, ref infoNative); for (int i = 0; i < resultsLength; i++) //default resultsLength is 0, safe to iterate { info.results[i] = (VkResult)results[i]; } return(result); } }
public unsafe void Present( Swapchain swapchain, uint imageIndex = 0, List <API.Semaphore> waitSemaphores = null ) { var semaphores = new NativeList <VkSemaphore>(); if (waitSemaphores != null) { foreach (var s in waitSemaphores) { semaphores.Add(s.Handle); } } var swapchains = new NativeList <VkSwapchainKHR>(); swapchains.Add(swapchain.Handle); var presentInfo = new VkPresentInfoKHR { sType = VkStructureType.PresentInfoKHR, swapchainCount = 1, pSwapchains = (VkSwapchainKHR *)swapchains.Data.ToPointer(), pImageIndices = &imageIndex, waitSemaphoreCount = semaphores.Count, pWaitSemaphores = (VkSemaphore *)semaphores.Data.ToPointer(), }; //get a free device queue var queue = GetQueue(swapchain.PresentQueueFamily); if (VulkanNative.vkQueuePresentKHR( queue, &presentInfo ) != VkResult.Success) { throw new Exception("failed to present swapchain image"); } }
public unsafe void QueuePresent(VkQueue queue, uint imageIndex, VkSemaphore waitSemaphore = default) { var sc = swapchain; var presentInfo = new VkPresentInfoKHR { sType = VkStructureType.PresentInfoKHR, pNext = null, swapchainCount = 1, pSwapchains = &sc, pImageIndices = &imageIndex }; // Check if a wait semaphore has been specified to wait for before presenting the image if (waitSemaphore != VkSampler.Null) { presentInfo.pWaitSemaphores = (VkSemaphore *)Unsafe.AsPointer(ref waitSemaphore); presentInfo.waitSemaphoreCount = 1; } VulkanUtil.CheckResult(vkQueuePresentKHR(queue, &presentInfo)); }
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); } }
public void DrawFrame() { var imageIndex = swapChain.AcquireNextImageKHR(ulong.MaxValue, imageAvailableSemaphore, null).Object; var submitInfo = new VkSubmitInfo { WaitSemaphores = new[] { imageAvailableSemaphore }, WaitDstStageMask = new[] { VkPipelineStageFlags.ColorAttachmentOutput }, CommandBuffers = new[] { commandBuffers[imageIndex] }, SignalSemaphores = new[] { renderFinishedSemaphore } }; graphicsQueue.Submit(new [] { submitInfo }, null).CheckSuccess(); var presentInfo = new VkPresentInfoKHR { WaitSemaphores = new[] { renderFinishedSemaphore }, Swapchains = new[] { swapChain }, ImageIndices = new[] { imageIndex }, Results = null }; presentQueue.PresentKHR(presentInfo).CheckSuccess(); }
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); }
public static VkResult vkQueuePresentKHR(VkQueue queue, VkSemaphore waitSemaphore, VkSwapchainKHR swapchain, uint imageIndex) { var presentInfo = new VkPresentInfoKHR { sType = VkStructureType.PresentInfoKHR, pNext = null }; if (waitSemaphore != VkSemaphore.Null) { presentInfo.waitSemaphoreCount = 1u; presentInfo.pWaitSemaphores = &waitSemaphore; } if (swapchain != VkSwapchainKHR.Null) { presentInfo.swapchainCount = 1u; presentInfo.pSwapchains = &swapchain; presentInfo.pImageIndices = &imageIndex; } return(vkQueuePresentKHR(queue, &presentInfo)); }
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 = ¤tBufferIndexCopy, }; 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); }
static void Main(string[] args) { Console.WriteLine(AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES").ToString()); Console.WriteLine($"Hello Vulkan!"); Init(); if (!GLFW.Vulkan.IsSupported) { Console.Error.WriteLine("GLFW says that vulkan is not supported."); return; } WindowHint(Hint.ClientApi, ClientApi.None); NativeWindow window = new GLFW.NativeWindow(width, height, "Fabricor"); Glfw.SetKeyCallback(window, (a, b, c, d, e) => { GLFWInput.KeyCallback(a, b, c, d, e); }); FInstance finst = new FInstance(); VkSurfaceKHR surface = CreateSurface(finst.instance, window); VkDevice device = CreateDevice(finst.instance, out var physicalDevice, surface, out var queueFamilyIndex); VkSwapchainKHR swapchain = CreateSwapchain(VkSwapchainKHR.Null, finst.instance, device, physicalDevice, surface, queueFamilyIndex); VkRenderPass renderPass = CreateRenderPass(device); uint swapchainImageCount = 0; Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, null));////////////IMAGES VkImage[] swapchainImages = new VkImage[swapchainImageCount]; fixed(VkImage *ptr = &swapchainImages[0]) Assert(vkGetSwapchainImagesKHR(device, swapchain, &swapchainImageCount, ptr)); CommandPoolManager.Init(device, queueFamilyIndex); int poolId = CommandPoolManager.CreateCommandPool(VkCommandPoolCreateFlags.ResetCommandBuffer); VkSemaphoreCreateInfo pCreateInfo = VkSemaphoreCreateInfo.New(); VkSemaphore acquireSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &acquireSemaphore); VkSemaphore releaseSemaphore = new VkSemaphore(); vkCreateSemaphore(device, &pCreateInfo, null, &releaseSemaphore); VkQueue graphicsQueue = VkQueue.Null; vkGetDeviceQueue(device, queueFamilyIndex, 0, &graphicsQueue); string[] textures = new string[] { "res/Linus.png", "res/Alex.png", "res/Victor.png", "res/Alex2.png", //"res/Cyan.png", "res/Alex3.png", //"res/Red.png", }; FTexture texture = new FTexture(device, physicalDevice, poolId, graphicsQueue, textures, VkFormat.R8g8b8a8Unorm, 512, 512, (uint)(Math.Log(512) / Math.Log(2)) + 1); VkPipelineCache pipelineCache = VkPipelineCache.Null;//This is critcal for performance. FGraphicsPipeline voxelPipeline = new FGraphicsPipeline(device, physicalDevice, pipelineCache, renderPass, "shaders/voxel", swapchainImageCount, texture); voxelPipeline.CreateDepthBuffer(physicalDevice, (uint)width, (uint)height); VkImageView[] swapchainImageViews = new VkImageView[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { swapchainImageViews[i] = FTexture.CreateColourImageView(device, swapchainImages[i], surfaceFormat.format); } VkFramebuffer[] frambuffers = new VkFramebuffer[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { frambuffers[i] = CreateFramebuffer(device, renderPass, swapchainImageViews[i], voxelPipeline.depthImageView); } MeshWrapper <VoxelVertex> mesh = VoxelMeshFactory.GenerateMesh(device, physicalDevice); Action updateMesh = delegate { VoxelMeshFactory.UpdateMesh(device, physicalDevice, mesh); }; GLFWInput.Subscribe(Keys.U, updateMesh, InputState.Press); Action changeTexture = delegate { Span <VoxelVertex> span = mesh.Mesh.vertices.Map(); for (int j = 0; j < span.Length; j++) { span[j].textureId++; } span = mesh.Mesh.vertices.UnMap(); }; GLFWInput.Subscribe(Keys.F, changeTexture, InputState.Press); FCommandBuffer[] cmdBuffers = new FCommandBuffer[swapchainImageCount]; VkFence[] fences = new VkFence[swapchainImageCount]; for (int i = 0; i < swapchainImageCount; i++) { cmdBuffers[i] = new FCommandBuffer(device, poolId); VkFenceCreateInfo createInfo = VkFenceCreateInfo.New(); createInfo.flags = VkFenceCreateFlags.Signaled; VkFence fence = VkFence.Null; Assert(vkCreateFence(device, &createInfo, null, &fence)); fences[i] = fence; } FCamera camera = new FCamera(); camera.AspectWidth = width; camera.AspectHeight = height; camera.position.Z = -1f; //camera.rotation=Quaternion.CreateFromYawPitchRoll(MathF.PI,0,0); double lastTime = Glfw.Time; int nbFrames = 0; while (!WindowShouldClose(window)) { PollEvents(); GLFWInput.Update(); // Measure speed double currentTime = Glfw.Time; nbFrames++; if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1 sec ago // printf and reset timer Console.WriteLine($"ms/frame: {1000.0 / nbFrames}"); nbFrames = 0; lastTime += 1.0; } if (GLFWInput.TimeKeyPressed(Keys.D) > 0) { camera.position += Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.A) > 0) { camera.position -= Vector3.Transform(Vector3.UnitX * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.W) > 0) { camera.position += Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.S) > 0) { camera.position -= Vector3.Transform(Vector3.UnitZ * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Space) > 0) { camera.position += Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.LeftShift) > 0) { camera.position -= Vector3.Transform(Vector3.UnitY * 0.00015f, camera.rotation); } if (GLFWInput.TimeKeyPressed(Keys.Right) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, 0.00015f); } if (GLFWInput.TimeKeyPressed(Keys.Left) > 0) { camera.rotation *= Quaternion.CreateFromAxisAngle(Vector3.UnitY, -0.00015f); } uint imageIndex = 0; Assert(vkAcquireNextImageKHR(device, swapchain, ulong.MaxValue, acquireSemaphore, VkFence.Null, &imageIndex)); VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New(); beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit; voxelPipeline.swapchainFramebuffer = frambuffers[imageIndex]; voxelPipeline.swapchainImage = swapchainImages[imageIndex]; voxelPipeline.swapchainImageIndex = imageIndex; voxelPipeline.mesh = mesh; voxelPipeline.camera = camera; fixed(VkFence *ptr = &(fences[imageIndex])) { vkWaitForFences(device, 1, ptr, VkBool32.False, ulong.MaxValue); vkResetFences(device, 1, ptr); } cmdBuffers[imageIndex].RecordCommandBuffer(new Action <VkCommandBuffer>[] { voxelPipeline.Execute, }); VkPipelineStageFlags submitStageMask = VkPipelineStageFlags.ColorAttachmentOutput; VkSubmitInfo submitInfo = VkSubmitInfo.New(); submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = &acquireSemaphore; submitInfo.pWaitDstStageMask = &submitStageMask; submitInfo.commandBufferCount = 1; fixed(VkCommandBuffer *ptr = &(cmdBuffers[imageIndex].buffer)) submitInfo.pCommandBuffers = ptr; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &releaseSemaphore; Assert(vkQueueSubmit(graphicsQueue, 1, &submitInfo, fences[imageIndex])); VkPresentInfoKHR presentInfoKHR = VkPresentInfoKHR.New(); presentInfoKHR.swapchainCount = 1; presentInfoKHR.pSwapchains = &swapchain; presentInfoKHR.pImageIndices = &imageIndex; presentInfoKHR.waitSemaphoreCount = 1; presentInfoKHR.pWaitSemaphores = &releaseSemaphore; Assert(vkQueuePresentKHR(graphicsQueue, &presentInfoKHR)); vkDeviceWaitIdle(device); } finst.Destroy(); DestroyWindow(window); Terminate(); }
public void Present(VkPresentInfoKHR present) { Utils.CheckResult(vkQueuePresentKHR(handle, ref present)); }
public static extern VkResult QueuePresentKHR( VkQueue queue, ref VkPresentInfoKHR pPresentInfo );
public VkResult Present(VkPresentInfoKHR pPresentInfo) { return(VkResult.VK_SUCCESS); }
void MainLoop() { var submitInfo = new VkSubmitInfo(); submitInfo.sType = CSGL.Vulkan.VkStructureType.SubmitInfo; var waitSemaphores = new Native <VkSemaphore>(imageAvailableSemaphore); var waitStages = new Native <CSGL.Vulkan.VkPipelineStageFlags>(CSGL.Vulkan.VkPipelineStageFlags.ColorAttachmentOutputBit); var signalSemaphores = new Native <VkSemaphore>(renderFinishedSemaphore); var swapchains = new Native <VkSwapchainKHR>(swapchain); var commandBuffer = new Native <VkCommandBuffer>(); var indexNative = new Native <uint>(); submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores.Address; submitInfo.pWaitDstStageMask = waitStages.Address; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = commandBuffer.Address; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores.Address; var submitInfoNative = new Native <VkSubmitInfo>(submitInfo); var presentInfo = new VkPresentInfoKHR(); presentInfo.sType = CSGL.Vulkan.VkStructureType.PresentInfoKhr; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores.Address; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapchains.Address; presentInfo.pImageIndices = indexNative.Address; while (true) { GLFW.PollEvents(); if (GLFW.WindowShouldClose(window)) { break; } if (reCreateSwapchainFlag) { reCreateSwapchainFlag = false; RecreateSwapchain(); } uint imageIndex; var result = acquireNextImage(device, swapchain, ulong.MaxValue, imageAvailableSemaphore, VkFence.Null, out imageIndex); if (result == CSGL.Vulkan.VkResult.ErrorOutOfDateKhr || result == CSGL.Vulkan.VkResult.SuboptimalKhr) { RecreateSwapchain(); continue; } commandBuffer.Value = commandBuffers[(int)imageIndex]; swapchains.Value = swapchain; indexNative.Value = imageIndex; VK.QueueSubmit(graphicsQueue, 1, submitInfoNative.Address, VkFence.Null); result = queuePresent(presentQueue, ref presentInfo); if (result == CSGL.Vulkan.VkResult.ErrorOutOfDateKhr || result == CSGL.Vulkan.VkResult.SuboptimalKhr) { RecreateSwapchain(); } } VK.DeviceWaitIdle(device); waitSemaphores.Dispose(); waitStages.Dispose(); signalSemaphores.Dispose(); swapchains.Dispose(); commandBuffer.Dispose(); submitInfoNative.Dispose(); }