| 1738 | } |
| 1739 | |
| 1740 | static void VulkanBeginFrame(HContext _context) |
| 1741 | { |
| 1742 | VulkanContext* context = (VulkanContext*) _context; |
| 1743 | NativeBeginFrame(_context); |
| 1744 | |
| 1745 | VkDevice vk_device = context->m_LogicalDevice.m_Device; |
| 1746 | uint32_t frameInFlight = context->m_CurrentFrameInFlight; |
| 1747 | FrameResource& currentFrame = context->m_FrameResources[frameInFlight]; |
| 1748 | |
| 1749 | // Wait for GPU to finish work for this frame-in-flight |
| 1750 | vkWaitForFences(vk_device, 1, ¤tFrame.m_SubmitFence, VK_TRUE, UINT64_MAX); |
| 1751 | |
| 1752 | // Acquire next swap chain image |
| 1753 | VkResult res = context->m_SwapChain->Advance(vk_device, currentFrame.m_ImageAvailable); |
| 1754 | if (res != VK_SUCCESS) |
| 1755 | { |
| 1756 | if (res == VK_ERROR_OUT_OF_DATE_KHR) |
| 1757 | { |
| 1758 | context->m_WindowWidth = dmPlatform::GetWindowWidth(context->m_BaseContext.m_Window); |
| 1759 | context->m_WindowHeight = dmPlatform::GetWindowHeight(context->m_BaseContext.m_Window); |
| 1760 | SwapChainChanged(context, &context->m_WindowWidth, &context->m_WindowHeight, 0, 0); |
| 1761 | res = context->m_SwapChain->Advance(vk_device, currentFrame.m_ImageAvailable); |
| 1762 | CHECK_VK_ERROR(res); |
| 1763 | } |
| 1764 | else if (res == VK_SUBOPTIMAL_KHR) |
| 1765 | { |
| 1766 | // Presenting the swap chain will still work but not optimally, but we should still notify. |
| 1767 | dmLogOnceWarning("Vulkan swapchain is out of date, reason: VK_SUBOPTIMAL_KHR."); |
| 1768 | } |
| 1769 | else |
| 1770 | { |
| 1771 | dmLogOnceError("Vulkan swapchain is out of date, reason: %s.", VkResultToStr(res)); |
| 1772 | return; |
| 1773 | } |
| 1774 | } |
| 1775 | |
| 1776 | // Only reset after a successful acquire. If we bail before submitting, the fence must stay signaled. |
| 1777 | vkResetFences(vk_device, 1, ¤tFrame.m_SubmitFence); |
| 1778 | |
| 1779 | // Flush per-swapchain-image resources to destroy |
| 1780 | if (context->m_MainResourcesToDestroy[frameInFlight]->Size() > 0) |
| 1781 | { |
| 1782 | FlushResourcesToDestroy(context, context->m_MainResourcesToDestroy[frameInFlight]); |
| 1783 | } |
| 1784 | |
| 1785 | if (context->m_FenceResourcesToDestroy.Capacity() > 0) |
| 1786 | { |
| 1787 | FlushFenceResourcesToDestroy(context); |
| 1788 | } |
| 1789 | |
| 1790 | // Reset per-frame scratch buffer and descriptor pools |
| 1791 | ScratchBuffer* scratch = &context->m_MainScratchBuffers[frameInFlight]; |
| 1792 | context->m_DescriptorAllocatorGeneration[frameInFlight]++; |
| 1793 | ResetScratchBuffer(vk_device, scratch); |
| 1794 | |
| 1795 | res = scratch->m_DeviceBuffer.MapMemory(vk_device); |
| 1796 | CHECK_VK_ERROR(res); |
| 1797 |
nothing calls this directly
no test coverage detected