summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Halase <jordan@halase.me>2019-11-06 11:03:32 -0600
committerJordan Halase <jordan@halase.me>2019-11-06 11:03:32 -0600
commit0fbe56c2d9ece2e5f958a8f4289e6d985052821d (patch)
tree95146e26f2d574b2f13b1c45ab86085b29daec4e
parentd8cee89cf98400e8a2d9f90e13ebedeef9e09980 (diff)
Use events to block queue while in-flight
-rwxr-xr-xmain.c104
1 files 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;
}