Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static void demo_draw(struct demo *demo) {
- VkResult U_ASSERT_ONLY err;
- // 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]);
- do {
- // 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], VK_NULL_HANDLE, &demo->current_buffer);
- if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // demo->swapchain is out of date (e.g. the window was resized) and
- // must be recreated:
- demo_resize(demo);
- } else if (err == VK_SUBOPTIMAL_KHR) {
- // demo->swapchain is not as optimal as it could be, but the platform's
- // presentation engine will still present the image correctly.
- break;
- } else {
- assert(!err);
- }
- } while (err != VK_SUCCESS);
- demo_update_data_buffer(demo);
- if (demo->VK_GOOGLE_display_timing_enabled) {
- // Look at what happened to previous presents, and make appropriate
- // adjustments in timing:
- DemoUpdateTargetIPD(demo);
- // Note: a real application would position its geometry to that it's in
- // the correct locatoin for when the next image is presented. It might
- // also wait, so that there's less latency between any input and when
- // the next image is rendered/presented. This demo program is so
- // simple that it doesn't do either of those.
- }
- // Wait for the image acquired semaphore to be signaled to ensure
- // that the image won't be rendered to until the presentation
- // engine has fully released ownership to the application, and it is
- // okay to render to the image.
- VkPipelineStageFlags pipe_stage_flags;
- VkSubmitInfo submit_info;
- submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submit_info.pNext = NULL;
- submit_info.pWaitDstStageMask = &pipe_stage_flags;
- pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- submit_info.waitSemaphoreCount = 1;
- submit_info.pWaitSemaphores = &demo->image_acquired_semaphores[demo->frame_index];
- submit_info.commandBufferCount = 1;
- 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];
- err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, demo->fences[demo->frame_index]);
- assert(!err);
- if (demo->separate_present_queue) {
- // If we are using separate queues, change image ownership to the
- // present queue before presenting, waiting for the draw complete
- // semaphore and signalling the ownership released semaphore when finished
- VkFence nullFence = VK_NULL_HANDLE;
- pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- submit_info.waitSemaphoreCount = 1;
- submit_info.pWaitSemaphores = &demo->draw_complete_semaphores[demo->frame_index];
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &demo->swapchain_image_resources[demo->current_buffer].graphics_to_present_cmd;
- submit_info.signalSemaphoreCount = 1;
- submit_info.pSignalSemaphores = &demo->image_ownership_semaphores[demo->frame_index];
- err = vkQueueSubmit(demo->present_queue, 1, &submit_info, nullFence);
- assert(!err);
- }
- // If we are using separate queues we have to wait for image ownership,
- // otherwise wait for draw complete
- VkPresentInfoKHR present = {
- .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
- .pNext = NULL,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = (demo->separate_present_queue) ? &demo->image_ownership_semaphores[demo->frame_index]
- : &demo->draw_complete_semaphores[demo->frame_index],
- .swapchainCount = 1,
- .pSwapchains = &demo->swapchain,
- .pImageIndices = &demo->current_buffer,
- };
- VkRectLayerKHR rect;
- VkPresentRegionKHR region;
- VkPresentRegionsKHR regions;
- if (demo->VK_KHR_incremental_present_enabled) {
- // If using VK_KHR_incremental_present, we provide a hint of the region
- // that contains changed content relative to the previously-presented
- // image. The implementation can use this hint in order to save
- // work/power (by only copying the region in the hint). The
- // implementation is free to ignore the hint though, and so we must
- // ensure that the entire image has the correctly-drawn content.
- uint32_t eighthOfWidth = demo->width / 8;
- uint32_t eighthOfHeight = demo->height / 8;
- rect.offset.x = eighthOfWidth;
- rect.offset.y = eighthOfHeight;
- rect.extent.width = eighthOfWidth * 6;
- rect.extent.height = eighthOfHeight * 6;
- rect.layer = 0;
- region.rectangleCount = 1;
- region.pRectangles = ▭
- regions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
- regions.pNext = present.pNext;
- regions.swapchainCount = present.swapchainCount;
- regions.pRegions = ®ion;
- present.pNext = ®ions;
- }
- if (demo->VK_GOOGLE_display_timing_enabled) {
- VkPresentTimeGOOGLE ptime;
- if (demo->prev_desired_present_time == 0) {
- // This must be the first present for this swapchain.
- //
- // We don't know where we are relative to the presentation engine's
- // display's refresh cycle. We also don't know how long rendering
- // takes. Let's make a grossly-simplified assumption that the
- // desiredPresentTime should be half way between now and
- // now+target_IPD. We will adjust over time.
- uint64_t curtime = getTimeInNanoseconds();
- if (curtime == 0) {
- // Since we didn't find out the current time, don't give a
- // desiredPresentTime:
- ptime.desiredPresentTime = 0;
- } else {
- ptime.desiredPresentTime = curtime + (demo->target_IPD >> 1);
- }
- } else {
- ptime.desiredPresentTime = (demo->prev_desired_present_time + demo->target_IPD);
- }
- ptime.presentID = demo->next_present_id++;
- demo->prev_desired_present_time = ptime.desiredPresentTime;
- VkPresentTimesInfoGOOGLE present_time = {
- .sType = VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE,
- .pNext = present.pNext,
- .swapchainCount = present.swapchainCount,
- .pTimes = &ptime,
- };
- if (demo->VK_GOOGLE_display_timing_enabled) {
- present.pNext = &present_time;
- }
- }
- err = demo->fpQueuePresentKHR(demo->present_queue, &present);
- demo->frame_index += 1;
- demo->frame_index %= FRAME_LAG;
- if (err == VK_ERROR_OUT_OF_DATE_KHR) {
- // demo->swapchain is out of date (e.g. the window was resized) and
- // must be recreated:
- demo_resize(demo);
- } else if (err == VK_SUBOPTIMAL_KHR) {
- // demo->swapchain is not as optimal as it could be, but the platform's
- // presentation engine will still present the image correctly.
- } else {
- assert(!err);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement