From 356fc66b78afcd5d8a44df0cdde6b56f141fd9b2 Mon Sep 17 00:00:00 2001 From: Jordan Halase Date: Wed, 6 Nov 2019 14:06:52 -0600 Subject: Use events to read queue while in-flight --- main.c | 157 ++++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 81 insertions(+), 76 deletions(-) diff --git a/main.c b/main.c index 4cb873c..317f30c 100755 --- a/main.c +++ b/main.c @@ -169,6 +169,7 @@ struct VulkanDev { PFN_vkEndCommandBuffer vkEndCommandBuffer; PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; PFN_vkCmdClearColorImage vkCmdClearColorImage; + PFN_vkCmdSetEvent vkCmdSetEvent; PFN_vkCmdWaitEvents vkCmdWaitEvents; PFN_vkCreateSemaphore vkCreateSemaphore; PFN_vkDestroySemaphore vkDestroySemaphore; @@ -183,6 +184,7 @@ struct VulkanDev { PFN_vkQueueSubmit vkQueueSubmit; PFN_vkQueuePresentKHR vkQueuePresentKHR; PFN_vkSetEvent vkSetEvent; + PFN_vkGetEventStatus vkGetEventStatus; }; /** Application-specific swapchain behavior */ @@ -207,6 +209,7 @@ struct FenceVulkan { struct EventVulkan { VkEvent dummy; + VkEvent normal; }; struct SyncVulkan { @@ -1082,6 +1085,13 @@ static int rvkLoadDeviceFunctions(struct RenderVulkan *vk, VkDevice device) return -1; } + static const char *const _vkCmdSetEvent = "vkCmdSetEvent"; + vk->dev->vkCmdSetEvent = (PFN_vkCmdSetEvent)vk->api->vkGetDeviceProcAddr(device, _vkCmdSetEvent); + if (!vk->dev->vkCmdSetEvent) { + rvkSetErrMsg(vk, strErrLd, _vkCmdSetEvent); + return -1; + } + static const char *const _vkCmdWaitEvents = "vkCmdWaitEvents"; vk->dev->vkCmdWaitEvents = (PFN_vkCmdWaitEvents)vk->api->vkGetDeviceProcAddr(device, _vkCmdWaitEvents); if (!vk->dev->vkCmdWaitEvents) { @@ -1180,6 +1190,13 @@ static int rvkLoadDeviceFunctions(struct RenderVulkan *vk, VkDevice device) return -1; } + static const char *const _vkGetEventStatus = "vkGetEventStatus"; + vk->dev->vkGetEventStatus = (PFN_vkGetEventStatus)vk->api->vkGetDeviceProcAddr(device, _vkGetEventStatus); + if (!vk->dev->vkGetEventStatus) { + rvkSetErrMsg(vk, strErrLd, _vkGetEventStatus); + return -1; + } + return 0; } @@ -1344,6 +1361,7 @@ static int rvkCreateRawSwapchain(struct RenderVulkan *vk, int width, int height) } else { presentMode = VK_PRESENT_MODE_FIFO_KHR; } + presentMode = VK_PRESENT_MODE_FIFO_KHR; free(presentModes); printf("Using present mode:\t\t`%s`\t(%d)\n", strPresentMode(presentMode), presentMode); @@ -1351,7 +1369,7 @@ static int rvkCreateRawSwapchain(struct RenderVulkan *vk, int width, int height) vk->swapchain.extent.width = width; vk->swapchain.extent.height = height; - vk->swapchain.nImages = surfaceCapabilities.minImageCount + 7; + vk->swapchain.nImages = surfaceCapabilities.minImageCount + 6; //vk->swapchain.nImages = surfaceCapabilities.maxImageCount; printf("Using %d swapchain images\n", vk->swapchain.nImages); @@ -1490,6 +1508,11 @@ static int recordCommandBuffers(struct RenderVulkan *vk) beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; for (uint32_t i = 0; i < vk->swapchain.nImages; ++i) { + vk->dev->vkBeginCommandBuffer(vk->commandBuffers[i], &beginInfo); + vk->dev->vkCmdSetEvent(vk->commandBuffers[i], + vk->sync.event.normal, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); + VkImageMemoryBarrier toClearBarrier = { 0 }; toClearBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; toClearBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; @@ -1512,7 +1535,6 @@ static int recordCommandBuffers(struct RenderVulkan *vk) toPresentBarrier.image = vk->swapchain.images[i]; toPresentBarrier.subresourceRange = range; - vk->dev->vkBeginCommandBuffer(vk->commandBuffers[i], &beginInfo); vk->dev->vkCmdPipelineBarrier(vk->commandBuffers[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, @@ -1537,73 +1559,19 @@ static int recordCommandBuffers(struct RenderVulkan *vk) static int recordDummyBuffer(struct RenderVulkan *vk) { - VkClearColorValue clearValue = { 0 }; - clearValue.float32[0] = (float)0xa4/0x100; // R - clearValue.float32[1] = (float)0x1e/0x100; // G - clearValue.float32[2] = (float)0x22/0x100; // B - clearValue.float32[3] = (float)0xff/0x100; // A - - VkImageSubresourceRange range = { 0 }; - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - range.baseMipLevel = 0; - range.levelCount = 1; - range.baseArrayLayer = 0; - range.layerCount = 1; - VkCommandBufferBeginInfo beginInfo = { 0 }; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - VkImageMemoryBarrier toClearBarrier = { 0 }; - toClearBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - toClearBarrier.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; - toClearBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - toClearBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - toClearBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - toClearBarrier.srcQueueFamilyIndex = vk->graphicsIndex; - toClearBarrier.dstQueueFamilyIndex = vk->graphicsIndex; - toClearBarrier.image = vk->swapchain.images[0]; - toClearBarrier.subresourceRange = range; - - VkImageMemoryBarrier toPresentBarrier = { 0 }; - toPresentBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - toPresentBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - toPresentBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; - toPresentBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - toPresentBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - toPresentBarrier.srcQueueFamilyIndex = vk->graphicsIndex; - toPresentBarrier.dstQueueFamilyIndex = vk->graphicsIndex; - toPresentBarrier.image = vk->swapchain.images[0]; - toPresentBarrier.subresourceRange = range; - vk->dev->vkBeginCommandBuffer(vk->dummyBuffer, &beginInfo); - for (uint32_t i = 0; i < 1; ++i) { - //vk->dev->vkCmdPipelineBarrier(vk->dummyBuffer, - // VK_PIPELINE_STAGE_TRANSFER_BIT, - // VK_PIPELINE_STAGE_TRANSFER_BIT, - // 0, - // 0, NULL, - // 0, NULL, - // 1, &toClearBarrier); - vk->dev->vkCmdWaitEvents(vk->dummyBuffer, - 1, &vk->sync.event.dummy, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, NULL, - 0, NULL, - 1, &toClearBarrier - //0, NULL - ); - vk->dev->vkCmdClearColorImage(vk->dummyBuffer, vk->swapchain.images[0], - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1, &range); - vk->dev->vkCmdPipelineBarrier(vk->dummyBuffer, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - 0, - 0, NULL, - 0, NULL, - 1, &toPresentBarrier); - } + vk->dev->vkCmdWaitEvents(vk->dummyBuffer, + 1, &vk->sync.event.dummy, + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, NULL, + 0, NULL, + 0, NULL + ); vk->dev->vkEndCommandBuffer(vk->dummyBuffer); return 0; @@ -1623,9 +1591,6 @@ int rvkCreateSwapchain(struct RenderVulkan *vk, const int width, const int heigh rvkSetErrMsg(vk, "Could not allocate command buffers: %d", result); return -1; } - if (recordCommandBuffers(vk)) { - return -1; - } return 0; } @@ -1661,9 +1626,16 @@ int rvkCreateSyncObjects(struct RenderVulkan *vk) rvkSetErrMsg(vk, "Could not create dummy event\n"); return -1; } + if ((result = vk->dev->vkCreateEvent(vk->device, &eventInfo, ALLOC_VK, &vk->sync.event.normal))) { + rvkSetErrMsg(vk, "Could not create normal event\n"); + return -1; + } if (recordDummyBuffer(vk)) { return -1; } + if (recordCommandBuffers(vk)) { + return -1; + } return 0; } @@ -1695,6 +1667,9 @@ void rvkDestroySyncObjects(struct RenderVulkan *vk) if (vk->sync.event.dummy) { vk->dev->vkDestroyEvent(vk->device, vk->sync.event.dummy, ALLOC_VK); } + if (vk->sync.event.normal) { + vk->dev->vkDestroyEvent(vk->device, vk->sync.event.normal, ALLOC_VK); + } } static void rvkCloseDevice(struct RenderVulkan *vk) @@ -1819,19 +1794,34 @@ PuglStatus onDisplay(PuglView *view) dummyInfo.pSignalSemaphores = &vk->sync.semaphore.dummyFinished; static uint32_t dummy = 0; - +#if 0 + if (dummy == 1) { + for (uint32_t i = 0; i < 10000000; ++i) { + uint32_t j = i/2; + } + } +#endif if (!dummy) { - printf("Submitting dummy buffer...\n"); + printf("%d: Submitting dummy buffer...\n", dummy); if ((result = vk->dev->vkQueueSubmit(vk->graphicsQueue, 1, &dummyInfo, VK_NULL_HANDLE ))) { rvkSetErrMsg(vk, "Could not submit dummy to queue: %d", result); + running = 0; return PUGL_FAILURE; } - printf("Dummy buffer submitted\n"); - } else if (dummy == 3) { - printf("Setting event at frame %d\n", dummy); + printf("%d: Dummy buffer submitted\n", dummy); + } else if (dummy == vk->swapchain.nImages-1) { + result = vk->dev->vkGetEventStatus(vk->device, vk->sync.event.normal); + if (result == VK_EVENT_SET) { + printf("%d: ERROR: Queue already executed\n", dummy); + } else if (result == VK_EVENT_RESET) { + printf("%d: Success: queue not yet executed\n", dummy); + } else { + printf("%d: ERROR: %d\n", dummy, result); + } + printf("%d: Setting event\n", dummy); vk->dev->vkSetEvent(vk->device, vk->sync.event.dummy); } @@ -1843,6 +1833,9 @@ PuglStatus onDisplay(PuglView *view) // TODO: Swapchain recreation when rezing, minimizing, etc. // TODO: Possibly use unique semaphores per in-flight image? + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Acquiring swapchain image...\n", dummy); + } if ((result = vk->dev->vkAcquireNextImageKHR( vk->device, vk->swapchain.rawSwapchain, @@ -1851,8 +1844,12 @@ PuglStatus onDisplay(PuglView *view) VK_NULL_HANDLE, &imageIndex))) { rvkSetErrMsg(vk, "Could not acquire swapchain image: %d", result); + running = 0; return PUGL_FAILURE; } + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Swapchain image acquired\n", dummy); + } /* If running continuously and with an asynchronous presentation engine, * Vulkan can blast the queue with rendering work faster than the GPU @@ -1876,13 +1873,20 @@ PuglStatus onDisplay(PuglView *view) submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &vk->sync.semaphore.renderFinished; + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Submitting queue...\n", dummy); + } if ((result = vk->dev->vkQueueSubmit(vk->graphicsQueue, 1, &submitInfo, vk->sync.fence.swapchain[imageIndex] ))) { rvkSetErrMsg(vk, "Could not submit to queue: %d", result); + running = 0; return PUGL_FAILURE; } + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Queue submitted\n", dummy); + } VkPresentInfoKHR presentInfo = { 0 }; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; @@ -1893,12 +1897,13 @@ PuglStatus onDisplay(PuglView *view) presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = NULL; - if (dummy < 3) { - printf("Submitting present %d...\n", dummy); + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Submitting present...\n", dummy); } vk->dev->vkQueuePresentKHR(vk->graphicsQueue, &presentInfo); - if (dummy < 3) { - printf("Present %d submitted\n", dummy); + if (dummy < vk->swapchain.nImages-1) { + printf("%d: Present submitted\n", dummy); + fflush(stdout); } if (args.continuous) ++framesDrawn; -- cgit v1.2.1