cube: demonstrate how to select other VkPresentModeKHR's
authorIan Elliott <ianelliott@google.com>
Mon, 3 Oct 2016 18:11:12 +0000 (12:11 -0600)
committerIan Elliott <ianelliott@google.com>
Tue, 4 Oct 2016 18:57:00 +0000 (12:57 -0600)
This comes from the Khronos-internal discussion of
https://github.com/LunarG/VulkanSamples/issues/98.  Cube will, by default,
choose VK_PRESENT_FIFO_KHR mode.  However, when that change was made, the old
(example) code was lost that showed how to search for the other present modes.
It was also discussed that there isn't good guidance on why an application
might want to use a mode other than FIFO.  This change adds both of those, but
only selects FIFO by default.  #ifdef's can be used to select other modes.
With that code is a reason why an application might wish to use that present
mode.

demos/cube.c

index 81db5b0..543a81e 100644 (file)
@@ -925,10 +925,58 @@ static void demo_prepare_buffers(struct demo *demo) {
     }
 
     // The FIFO present mode is guaranteed by the spec to be supported
-    // and to have no tearing.  MAILBOX is another option, but for fast
-    // rendering apps we could use a lot of gpu power rendering frames
-    // that are discarded and never displayed
+    // and to have no tearing.  It's a great default present mode to use.
     VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
+    //  There are times when you may wish to use another present mode.  The
+    //  following code shows how to select them, and the comments provide some
+    //  reasons you may wish to use them.
+    //
+    // It should be noted that Vulkan 1.0 doesn't provide a method for
+    // synchronizing rendering with the presentation engine's display.  There
+    // is a method provided for throttling rendering with the display, but
+    // there are some presentation engines for which this method will not work.
+    // If an application doesn't throttle its rendering, and if it renders much
+    // faster than the refresh rate of the display, this can waste power on
+    // mobile devices.  That is because power is being spent rendering images
+    // that may never be seen.
+//#define DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR
+//#define DESIRE_VK_PRESENT_MODE_MAILBOX_KHR
+//#define DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR
+#if defined(DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR)
+    // VK_PRESENT_MODE_IMMEDIATE_KHR is for applications that don't care about
+    // tearing, or have some way of synchronizing their rendering with the
+    // display.
+    for (size_t i = 0; i < presentModeCount; ++i) {
+        if (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
+            swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+            break;
+        }
+    }
+#elif defined(DESIRE_VK_PRESENT_MODE_MAILBOX_KHR)
+    // VK_PRESENT_MODE_MAILBOX_KHR may be useful for applications that
+    // generally render a new presentable image every refresh cycle, but are
+    // occasionally early.  In this case, the application wants the new image
+    // to be displayed instead of the previously-queued-for-presentation image
+    // that has not yet been displayed.
+    for (size_t i = 0; i < presentModeCount; ++i) {
+        if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
+            swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
+            break;
+        }
+    }
+#elif defined(DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR)
+    // VK_PRESENT_MODE_FIFO_RELAXED_KHR is for applications that generally
+    // render a new presentable image every refresh cycle, but are occasionally
+    // late.  In this case (perhaps because of stuttering/latency concerns),
+    // the application wants the late image to be immediately displayed, even
+    // though that may mean some tearing.
+    for (size_t i = 0; i < presentModeCount; ++i) {
+        if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
+            swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
+            break;
+        }
+    }
+#endif
 
     // Determine the number of VkImage's to use in the swap chain.
     // Application desires to only acquire 1 image at a time (which is