summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Halase <jordan@halase.me>2019-11-06 14:06:52 -0600
committerJordan Halase <jordan@halase.me>2019-11-06 14:06:52 -0600
commit356fc66b78afcd5d8a44df0cdde6b56f141fd9b2 (patch)
tree23c3709a66d466c37fd0764432c7551f0ef759d5
parent0fbe56c2d9ece2e5f958a8f4289e6d985052821d (diff)
Use events to read queue while in-flight
-rwxr-xr-xmain.c157
1 files 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;