summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Leone <dleone@nvidia.com>2017-04-14 16:10:14 -0700
committerTony-LunarG <tony@lunarg.com>2017-05-02 08:56:10 -0600
commitf06ab9cba631acdd64e8009b2290e3656073a499 (patch)
tree88aa1a10a4255e4c140757e9ca7bb3c786d4d1f6
parentca472cf81919f5b020ccba721d2b7b56c39301aa (diff)
cube: Throttle rendering rather than presentation
It is currently impossible to reliably throttle presentation per the Vulkan spec. The previous code was relying on fences returned by vkAcquireNextImageKHR() to throttle. The only information this fence holds is whether it is possible to render to that image since the *last time* it was presented, which could have happened several frames ago. Instead, we can throttle the rendering by passing a fence to vkQueueSubmit(). The previous code (only the cube.c version) was using a fence there to synchronize a vkMapMemory() in demo_update_data_buffer(), which doesn't seem necessary. Before this commit, we were effectively throttling to the number of frames in the swapchain rather than on FRAME_LAG. In the FIFO present mode, this could schedule too much work in the presentation channel (since we have to account for VBLANK events) and thus causing undesired side effects, such as stutters when trying to move the cube window on a desktop, which is I assume why the throttle code was added in the first place.
-rw-r--r--demos/cube.c23
-rw-r--r--demos/cube.cpp8
2 files changed, 7 insertions, 24 deletions
diff --git a/demos/cube.c b/demos/cube.c
index 10ec60d4..e2e40c3d 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -309,7 +309,6 @@ typedef struct {
VkDeviceMemory uniform_memory;
VkFramebuffer framebuffer;
VkDescriptorSet descriptor_set;
- VkFence fence;
} SwapchainImageResources;
struct demo {
@@ -809,9 +808,6 @@ void demo_update_data_buffer(struct demo *demo) {
(float)degreesToRadians(demo->spin_angle));
mat4x4_mul(MVP, VP, demo->model_matrix);
- vkWaitForFences(demo->device, 1, &demo->swapchain_image_resources[demo->current_buffer].fence,
- VK_TRUE, UINT64_MAX);
-
err = vkMapMemory(demo->device,
demo->swapchain_image_resources[demo->current_buffer].uniform_memory, 0,
VK_WHOLE_SIZE, 0, (void **)&pData);
@@ -957,15 +953,14 @@ void DemoUpdateTargetIPD(struct demo *demo) {
static void demo_draw(struct demo *demo) {
VkResult U_ASSERT_ONLY err;
- // Ensure no more than FRAME_LAG presentations are outstanding
+ // Ensure no more than FRAME_LAG renderings are outstanding
vkWaitForFences(demo->device, 1, &demo->fences[demo->frame_index], VK_TRUE, UINT64_MAX);
vkResetFences(demo->device, 1, &demo->fences[demo->frame_index]);
// Get the index of the next available swapchain image:
err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,
demo->image_acquired_semaphores[demo->frame_index],
- demo->fences[demo->frame_index],
- &demo->current_buffer);
+ VK_NULL_HANDLE, &demo->current_buffer);
demo_update_data_buffer(demo);
@@ -1012,9 +1007,8 @@ static void demo_draw(struct demo *demo) {
submit_info.pCommandBuffers = &demo->swapchain_image_resources[demo->current_buffer].cmd;
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &demo->draw_complete_semaphores[demo->frame_index];
- vkResetFences(demo->device, 1, &demo->swapchain_image_resources[demo->current_buffer].fence);
err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info,
- demo->swapchain_image_resources[demo->current_buffer].fence);
+ demo->fences[demo->frame_index]);
assert(!err);
if (demo->separate_present_queue) {
@@ -1313,12 +1307,6 @@ static void demo_prepare_buffers(struct demo *demo) {
demo->swapchainImageCount);
assert(demo->swapchain_image_resources);
- VkFenceCreateInfo fence_ci = {
- .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- .pNext = NULL,
- .flags = VK_FENCE_CREATE_SIGNALED_BIT
- };
-
for (i = 0; i < demo->swapchainImageCount; i++) {
VkImageViewCreateInfo color_image_view = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
@@ -1347,9 +1335,6 @@ static void demo_prepare_buffers(struct demo *demo) {
err = vkCreateImageView(demo->device, &color_image_view, NULL,
&demo->swapchain_image_resources[i].view);
assert(!err);
-
- err = vkCreateFence(demo->device, &fence_ci, NULL, &demo->swapchain_image_resources[i].fence);
- assert(!err);
}
if (demo->VK_GOOGLE_display_timing_enabled) {
@@ -2399,7 +2384,6 @@ static void demo_cleanup(struct demo *demo) {
&demo->swapchain_image_resources[i].cmd);
vkDestroyBuffer(demo->device, demo->swapchain_image_resources[i].uniform_buffer, NULL);
vkFreeMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, NULL);
- vkDestroyFence(demo->device, demo->swapchain_image_resources[i].fence, NULL);
}
free(demo->swapchain_image_resources);
free(demo->queue_props);
@@ -2476,7 +2460,6 @@ static void demo_resize(struct demo *demo) {
&demo->swapchain_image_resources[i].cmd);
vkDestroyBuffer(demo->device, demo->swapchain_image_resources[i].uniform_buffer, NULL);
vkFreeMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, NULL);
- vkDestroyFence(demo->device, demo->swapchain_image_resources[i].fence, NULL);
}
vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
if (demo->separate_present_queue) {
diff --git a/demos/cube.cpp b/demos/cube.cpp
index 588d1cd9..4470e8f3 100644
--- a/demos/cube.cpp
+++ b/demos/cube.cpp
@@ -434,13 +434,13 @@ struct Demo {
}
void draw() {
- // Ensure no more than FRAME_LAG presentations are outstanding
+ // Ensure no more than FRAME_LAG renderings are outstanding
device.waitForFences(1, &fences[frame_index], VK_TRUE, UINT64_MAX);
device.resetFences(1, &fences[frame_index]);
// Get the index of the next available swapchain image:
- auto result = device.acquireNextImageKHR(swapchain, UINT64_MAX, image_acquired_semaphores[frame_index], fences[frame_index],
- &current_buffer);
+ auto result = device.acquireNextImageKHR(swapchain, UINT64_MAX, image_acquired_semaphores[frame_index],
+ vk::Fence(), &current_buffer);
if (result == vk::Result::eErrorOutOfDateKHR) {
// swapchain is out of date (e.g. the window was resized) and
// must be recreated:
@@ -471,7 +471,7 @@ struct Demo {
.setSignalSemaphoreCount(1)
.setPSignalSemaphores(&draw_complete_semaphores[frame_index]);
- result = graphics_queue.submit(1, &submit_info, vk::Fence());
+ result = graphics_queue.submit(1, &submit_info, fences[frame_index]);
VERIFY(result == vk::Result::eSuccess);
if (separate_present_queue) {