From 0fbe56c2d9ece2e5f958a8f4289e6d985052821d Mon Sep 17 00:00:00 2001 From: Jordan Halase Date: Wed, 6 Nov 2019 11:03:32 -0600 Subject: Use events to block queue while in-flight --- main.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/main.c b/main.c index d8e26fd..4cb873c 100755 --- a/main.c +++ b/main.c @@ -169,16 +169,20 @@ struct VulkanDev { PFN_vkEndCommandBuffer vkEndCommandBuffer; PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier; PFN_vkCmdClearColorImage vkCmdClearColorImage; + PFN_vkCmdWaitEvents vkCmdWaitEvents; PFN_vkCreateSemaphore vkCreateSemaphore; PFN_vkDestroySemaphore vkDestroySemaphore; PFN_vkCreateFence vkCreateFence; PFN_vkDestroyFence vkDestroyFence; + PFN_vkCreateEvent vkCreateEvent; + PFN_vkDestroyEvent vkDestroyEvent; PFN_vkGetFenceStatus vkGetFenceStatus; PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR; PFN_vkWaitForFences vkWaitForFences; PFN_vkResetFences vkResetFences; PFN_vkQueueSubmit vkQueueSubmit; PFN_vkQueuePresentKHR vkQueuePresentKHR; + PFN_vkSetEvent vkSetEvent; }; /** Application-specific swapchain behavior */ @@ -201,9 +205,14 @@ struct FenceVulkan { VkFence *swapchain; // Fences for each swapchain image }; +struct EventVulkan { + VkEvent dummy; +}; + struct SyncVulkan { struct SemaphoreVulkan semaphore; struct FenceVulkan fence; + struct EventVulkan event; }; /** Vulkan application that uses Pugl for windows and events @@ -1073,6 +1082,13 @@ static int rvkLoadDeviceFunctions(struct RenderVulkan *vk, VkDevice device) return -1; } + static const char *const _vkCmdWaitEvents = "vkCmdWaitEvents"; + vk->dev->vkCmdWaitEvents = (PFN_vkCmdWaitEvents)vk->api->vkGetDeviceProcAddr(device, _vkCmdWaitEvents); + if (!vk->dev->vkCmdWaitEvents) { + rvkSetErrMsg(vk, strErrLd, _vkCmdWaitEvents); + return -1; + } + static const char *const _vkCreateSemaphore = "vkCreateSemaphore"; vk->dev->vkCreateSemaphore = (PFN_vkCreateSemaphore)vk->api->vkGetDeviceProcAddr(device, _vkCreateSemaphore); if (!vk->dev->vkCreateSemaphore) { @@ -1094,6 +1110,20 @@ static int rvkLoadDeviceFunctions(struct RenderVulkan *vk, VkDevice device) return -1; } + static const char *const _vkCreateEvent = "vkCreateEvent"; + vk->dev->vkCreateEvent = (PFN_vkCreateEvent)vk->api->vkGetDeviceProcAddr(device, _vkCreateEvent); + if (!vk->dev->vkCreateEvent) { + rvkSetErrMsg(vk, strErrLd, _vkCreateEvent); + return -1; + } + + static const char *const _vkDestroyEvent = "vkDestroyEvent"; + vk->dev->vkDestroyEvent = (PFN_vkDestroyEvent)vk->api->vkGetDeviceProcAddr(device, _vkDestroyEvent); + if (!vk->dev->vkDestroyEvent) { + rvkSetErrMsg(vk, strErrLd, _vkDestroyEvent); + return -1; + } + static const char *const _vkGetFenceStatus = "vkGetFenceStatus"; vk->dev->vkGetFenceStatus = (PFN_vkGetFenceStatus)vk->api->vkGetDeviceProcAddr(device, _vkGetFenceStatus); if (!vk->dev->vkGetFenceStatus) { @@ -1143,6 +1173,13 @@ static int rvkLoadDeviceFunctions(struct RenderVulkan *vk, VkDevice device) return -1; } + static const char *const _vkSetEvent = "vkSetEvent"; + vk->dev->vkSetEvent = (PFN_vkSetEvent)vk->api->vkGetDeviceProcAddr(device, _vkSetEvent); + if (!vk->dev->vkSetEvent) { + rvkSetErrMsg(vk, strErrLd, _vkSetEvent); + return -1; + } + return 0; } @@ -1314,7 +1351,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; + vk->swapchain.nImages = surfaceCapabilities.minImageCount + 7; //vk->swapchain.nImages = surfaceCapabilities.maxImageCount; printf("Using %d swapchain images\n", vk->swapchain.nImages); @@ -1540,14 +1577,23 @@ static int recordDummyBuffer(struct RenderVulkan *vk) toPresentBarrier.subresourceRange = range; vk->dev->vkBeginCommandBuffer(vk->dummyBuffer, &beginInfo); - for (uint32_t i = 0; i < 20000; ++i) { - vk->dev->vkCmdPipelineBarrier(vk->dummyBuffer, + 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, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, NULL, 0, NULL, - 1, &toClearBarrier); + 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, @@ -1580,9 +1626,6 @@ int rvkCreateSwapchain(struct RenderVulkan *vk, const int width, const int heigh if (recordCommandBuffers(vk)) { return -1; } - if (recordDummyBuffer(vk)) { - return -1; - } return 0; } @@ -1612,6 +1655,15 @@ int rvkCreateSyncObjects(struct RenderVulkan *vk) return -1; } } + VkEventCreateInfo eventInfo = { 0 }; + eventInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; + if ((result = vk->dev->vkCreateEvent(vk->device, &eventInfo, ALLOC_VK, &vk->sync.event.dummy))) { + rvkSetErrMsg(vk, "Could not create dummy event\n"); + return -1; + } + if (recordDummyBuffer(vk)) { + return -1; + } return 0; } @@ -1640,6 +1692,9 @@ void rvkDestroySyncObjects(struct RenderVulkan *vk) vk->dev->vkDestroySemaphore(vk->device, vk->sync.semaphore.dummyFinished, ALLOC_VK); vk->sync.semaphore.dummyFinished = VK_NULL_HANDLE; } + if (vk->sync.event.dummy) { + vk->dev->vkDestroyEvent(vk->device, vk->sync.event.dummy, ALLOC_VK); + } } static void rvkCloseDevice(struct RenderVulkan *vk) @@ -1751,21 +1806,22 @@ PuglStatus onDisplay(PuglView *view) VK_PIPELINE_STAGE_TRANSFER_BIT }; + const VkPipelineStageFlags dummyStage = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_HOST_BIT; + VkSubmitInfo dummyInfo = { 0 }; dummyInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; //dummyInfo.waitSemaphoreCount = 1; //dummyInfo.pWaitSemaphores = &vk->sync.semaphore.presentComplete; - dummyInfo.pWaitDstStageMask = &waitStages[0]; + dummyInfo.pWaitDstStageMask = &dummyStage; dummyInfo.commandBufferCount = 1; dummyInfo.pCommandBuffers = &vk->dummyBuffer; dummyInfo.signalSemaphoreCount = 1; dummyInfo.pSignalSemaphores = &vk->sync.semaphore.dummyFinished; - static bool dummy = true; - static uint32_t dummyIndex = 0; + static uint32_t dummy = 0; - if (dummy) { - //printf("Submitting dummy buffer...\n"); + if (!dummy) { + printf("Submitting dummy buffer...\n"); if ((result = vk->dev->vkQueueSubmit(vk->graphicsQueue, 1, &dummyInfo, VK_NULL_HANDLE @@ -1774,6 +1830,9 @@ PuglStatus onDisplay(PuglView *view) return PUGL_FAILURE; } printf("Dummy buffer submitted\n"); + } else if (dummy == 3) { + printf("Setting event at frame %d\n", dummy); + vk->dev->vkSetEvent(vk->device, vk->sync.event.dummy); } const VkSemaphore waits[] = { @@ -1809,7 +1868,7 @@ PuglStatus onDisplay(PuglView *view) VkSubmitInfo submitInfo = { 0 }; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = dummy ? 2 : 1; + submitInfo.waitSemaphoreCount = !dummy ? 2 : 1; submitInfo.pWaitSemaphores = waits; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; @@ -1834,17 +1893,16 @@ PuglStatus onDisplay(PuglView *view) presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = NULL; - //if (dummyIndex < 2) { - // printf("Presenting %d...\n", dummyIndex); - //} + if (dummy < 3) { + printf("Submitting present %d...\n", dummy); + } vk->dev->vkQueuePresentKHR(vk->graphicsQueue, &presentInfo); - //if (dummyIndex < 2) { - // printf("Present %d submitted\n", dummyIndex); - //} + if (dummy < 3) { + printf("Present %d submitted\n", dummy); + } - dummy = false; if (args.continuous) ++framesDrawn; - ++dummyIndex; + ++dummy; return PUGL_SUCCESS; } -- cgit v1.2.1