Skip to content

Commit

Permalink
cube: Throttle rendering rather than presentation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
damienleone authored and TonyBarbour committed May 2, 2017
1 parent 97301d6 commit c336d82
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 24 deletions.
23 changes: 3 additions & 20 deletions demos/cube.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,6 @@ typedef struct {
VkDeviceMemory uniform_memory;
VkFramebuffer framebuffer;
VkDescriptorSet descriptor_set;
VkFence fence;
} SwapchainImageResources;

struct demo {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions demos/cube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit c336d82

Please sign in to comment.