OSDN Git Service

vulkan: allow drivers to see image acquire/release
authorJesse Hall <jessehall@google.com>
Wed, 4 Nov 2015 18:56:20 +0000 (10:56 -0800)
committerJesse Hall <jessehall@google.com>
Mon, 25 Jan 2016 21:49:31 +0000 (13:49 -0800)
Change-Id: I8143aeebd1f65142486cc55662c685d081ba41eb
(cherry picked from commit 58b4df743ecad9f1a0fc7cb7c0f5340dd8365308)

vulkan/doc/implementors_guide.adoc
vulkan/doc/implementors_guide.html
vulkan/include/vulkan/vk_ext_android_native_buffer.h
vulkan/libvulkan/get_proc_addr.cpp
vulkan/libvulkan/get_proc_addr.cpp.tmpl
vulkan/libvulkan/loader.h
vulkan/libvulkan/swapchain.cpp
vulkan/nulldrv/null_driver.cpp
vulkan/nulldrv/null_driver.h

index 313a5e1..60a6f61 100644 (file)
@@ -2,7 +2,7 @@
 = Vulkan on Android Implementor's Guide =
 :toc: right
 :numbered:
-:revnumber: 2
+:revnumber: 3
 
 This document is intended for GPU IHVs writing Vulkan drivers for Android, and OEMs integrating them for specific devices. It describes how a Vulkan driver interacts with the system, how GPU-specific tools should be installed, and Android-specific requirements.
 
@@ -99,30 +99,33 @@ When creating a gralloc-backed image, the +VkImageCreateInfo+ will have:
   .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices
 ----
 
-+vkImportNativeFenceANDROID+ imports an externally-signalled native fence into an existing +VkSemaphore+ object:
++vkAcquireImageANDROID+ acquires ownership of a swapchain image and imports an externally-signalled native fence into an existing +VkSemaphore+ object:
 
 [source,c]
 ----
-VkResult VKAPI vkImportNativeFenceANDROID(
-    VkDevice        device,
-    VkSemaphore     semaphore,
-    int             nativeFenceFd
+VkResult VKAPI vkAcquireImageANDROID(
+    VkDevice            device,
+    VkImage             image,
+    int                 nativeFenceFd,
+    VkSemaphore         semaphore
+);
 );
 ----
 
-This function is called during +vkAcquireNextImageWSI+ to import a native fence into the +VkSemaphore+ object provided by the application. This call puts the +VkSemaphore+ into the same "pending" state as +vkQueueSignalSemaphore+, so queues can wait on the semaphore. The +VkSemaphore+ signals when the underlying native fence signals; if the fence has already signalled, then the semaphore
-will be in the signalled state when this function returns. The driver takes ownership of the fence fd and is responsible for closing it when the +VkSemaphore+ is destroyed, when a different native fence is imported, or any other condition that replaces the +VkSemaphore+'s underlying synchronization object. If +fenceFd+ is -1, the +VkSemaphore+ will be considered signalled immediately, but it can still be passed to +vkQueueWaitSemaphore+.
+This function is called during +vkAcquireNextImageWSI+ to import a native fence into the +VkSemaphore+ object provided by the application. The driver may also use this opportunity to recognize and handle any external changes to the gralloc buffer state; many drivers won't need to do anything here. This call puts the +VkSemaphore+ into the same "pending" state as +vkQueueSignalSemaphore+, so queues can wait on the semaphore. The +VkSemaphore+ signals when the underlying native fence signals; if the fence has already signalled, then the semaphore will be in the signalled state when this function returns. The driver takes ownership of the fence fd and is responsible for closing it when the +VkSemaphore+ is destroyed, when a different native fence is imported, or any other condition that replaces the +VkSemaphore+'s underlying synchronization object. If +fenceFd+ is -1, the +VkSemaphore+ will be considered signalled immediately, but it can still be passed to +vkQueueWaitSemaphore+.
 
-+vkQueueSignalNativeFenceANDROID+ creates a native fence and schedules it to be signalled when prior work on the queue has completed.
++vkQueueSignalReleaseImageANDROID+ prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.
 
 [source,c]
 ----
-VkResult VKAPI vkQueueSignalNativeFenceANDROID(
-    VkQueue         queue,
-    int*            pNativeFenceFd);
+VkResult VKAPI vkQueueSignalReleaseImageANDROID(
+    VkQueue             queue,
+    VkImage             image,
+    int*                pNativeFenceFd
+);
 ----
 
-This will be called during +vkQueuePresentWSI+ on the provided queue. Effects are similar to +vkQueueSignalSemaphore+, except with a native fence instead of a semaphore. Unlike +vkQueueSignalSemaphore+, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set +*pNativeFenceFd+ to -1. The file descriptor returned in +*pNativeFenceFd+ is owned and will be closed by the caller.
+This will be called during +vkQueuePresentWSI+ on the provided queue. Effects are similar to +vkQueueSignalSemaphore+, except with a native fence instead of a semaphore. Unlike +vkQueueSignalSemaphore+, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set +*pNativeFenceFd+ to -1. The file descriptor returned in +*pNativeFenceFd+ is owned and will be closed by the caller. Many drivers will be able to ignore the +image+ parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to +VK_IMAGE_LAYOUT_PRESENT_SRC_KHR+.
 
 == History ==
 
@@ -132,3 +135,8 @@ This will be called during +vkQueuePresentWSI+ on the provided queue. Effects ar
    * Wording and formatting changes
    * Updated based on resolution of Khronos bug 14265
    * Deferred support for multiple drivers
+. *2015-11-04*
+   * Added vkGetSwapchainGrallocUsageANDROID
+   * Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
+     with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
+     drivers to known the ownership state of swapchain images.
index 8186ae3..8d6297a 100644 (file)
@@ -733,7 +733,7 @@ asciidoc.install(2);
 <body class="book">
 <div id="header">
 <h1>Vulkan on Android Implementor&#8217;s Guide</h1>
-<span id="revnumber">version 1</span>
+<span id="revnumber">version 3</span>
 <div id="toc">
   <div id="toctitle">Table of Contents</div>
   <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
@@ -843,29 +843,32 @@ http://www.gnu.org/software/src-highlite -->
   .queueFamilyCount    = VkSwapChainCreateInfoWSI::queueFamilyCount
   .pQueueFamilyIndices = VkSwapChainCreateInfoWSI::pQueueFamilyIndices</pre>
 </div></div>
-<div class="paragraph"><p><span class="monospaced">vkImportNativeFenceANDROID</span> imports an externally-signalled native fence into an existing <span class="monospaced">VkSemaphore</span> object:</p></div>
+<div class="paragraph"><p><span class="monospaced">vkAcquireImageANDROID</span> acquires ownership of a swapchain image and imports an externally-signalled native fence into an existing <span class="monospaced">VkSemaphore</span> object:</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
 http://www.lorenzobettini.it
 http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkImportNativeFenceANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkDevice</span>        device<span style="color: #990000">,</span>
-    <span style="color: #008080">VkSemaphore</span>     semaphore<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span>             nativeFenceFd
+<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkAcquireImageANDROID</span></span><span style="color: #990000">(</span>
+    <span style="color: #008080">VkDevice</span>            device<span style="color: #990000">,</span>
+    <span style="color: #008080">VkImage</span>             image<span style="color: #990000">,</span>
+    <span style="color: #009900">int</span>                 nativeFenceFd<span style="color: #990000">,</span>
+    VkSemaphore         semaphore
+<span style="color: #990000">);</span>
 <span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This function is called during <span class="monospaced">vkAcquireNextImageWSI</span> to import a native fence into the <span class="monospaced">VkSemaphore</span> object provided by the application. This call puts the <span class="monospaced">VkSemaphore</span> into the same "pending" state as <span class="monospaced">vkQueueSignalSemaphore</span>, so queues can wait on the semaphore. The <span class="monospaced">VkSemaphore</span> signals when the underlying native fence signals; if the fence has already signalled, then the semaphore
-will be in the signalled state when this function returns. The driver takes ownership of the fence fd and is responsible for closing it when the <span class="monospaced">VkSemaphore</span> is destroyed, when a different native fence is imported, or any other condition that replaces the <span class="monospaced">VkSemaphore</span>'s underlying synchronization object. If <span class="monospaced">fenceFd</span> is -1, the <span class="monospaced">VkSemaphore</span> will be considered signalled immediately, but it can still be passed to <span class="monospaced">vkQueueWaitSemaphore</span>.</p></div>
-<div class="paragraph"><p><span class="monospaced">vkQueueSignalNativeFenceANDROID</span> creates a native fence and schedules it to be signalled when prior work on the queue has completed.</p></div>
+<div class="paragraph"><p>This function is called during <span class="monospaced">vkAcquireNextImageWSI</span> to import a native fence into the <span class="monospaced">VkSemaphore</span> object provided by the application. The driver may also use this opportunity to recognize and handle any external changes to the gralloc buffer state; many drivers won&#8217;t need to do anything here. This call puts the <span class="monospaced">VkSemaphore</span> into the same "pending" state as <span class="monospaced">vkQueueSignalSemaphore</span>, so queues can wait on the semaphore. The <span class="monospaced">VkSemaphore</span> signals when the underlying native fence signals; if the fence has already signalled, then the semaphore will be in the signalled state when this function returns. The driver takes ownership of the fence fd and is responsible for closing it when the <span class="monospaced">VkSemaphore</span> is destroyed, when a different native fence is imported, or any other condition that replaces the <span class="monospaced">VkSemaphore</span>'s underlying synchronization object. If <span class="monospaced">fenceFd</span> is -1, the <span class="monospaced">VkSemaphore</span> will be considered signalled immediately, but it can still be passed to <span class="monospaced">vkQueueWaitSemaphore</span>.</p></div>
+<div class="paragraph"><p><span class="monospaced">vkQueueSignalReleaseImageANDROID</span> prepares a swapchain image for external use, and creates a native fence and schedules it to be signalled when prior work on the queue has completed.</p></div>
 <div class="listingblock">
 <div class="content"><!-- Generator: GNU source-highlight 3.1.6
 by Lorenzo Bettini
 http://www.lorenzobettini.it
 http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkQueueSignalNativeFenceANDROID</span></span><span style="color: #990000">(</span>
-    <span style="color: #008080">VkQueue</span>         queue<span style="color: #990000">,</span>
-    <span style="color: #009900">int</span><span style="color: #990000">*</span>            pNativeFenceFd<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>This will be called during <span class="monospaced">vkQueuePresentWSI</span> on the provided queue. Effects are similar to <span class="monospaced">vkQueueSignalSemaphore</span>, except with a native fence instead of a semaphore. Unlike <span class="monospaced">vkQueueSignalSemaphore</span>, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set <span class="monospaced">*pNativeFenceFd</span> to -1. The file descriptor returned in <span class="monospaced">*pNativeFenceFd</span> is owned and will be closed by the caller.</p></div>
+<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkQueueSignalReleaseImageANDROID</span></span><span style="color: #990000">(</span>
+    <span style="color: #008080">VkQueue</span>             queue<span style="color: #990000">,</span>
+    <span style="color: #008080">VkImage</span>             image<span style="color: #990000">,</span>
+    <span style="color: #009900">int</span><span style="color: #990000">*</span>                pNativeFenceFd
+<span style="color: #990000">);</span></tt></pre></div></div>
+<div class="paragraph"><p>This will be called during <span class="monospaced">vkQueuePresentWSI</span> on the provided queue. Effects are similar to <span class="monospaced">vkQueueSignalSemaphore</span>, except with a native fence instead of a semaphore. Unlike <span class="monospaced">vkQueueSignalSemaphore</span>, however, this call creates and returns the synchronization object that will be signalled rather than having it provided as input. If the queue is already idle when this function is called, it is allowed but not required to set <span class="monospaced">*pNativeFenceFd</span> to -1. The file descriptor returned in <span class="monospaced">*pNativeFenceFd</span> is owned and will be closed by the caller. Many drivers will be able to ignore the <span class="monospaced">image</span> parameter, but some may need to prepare CPU-side data structures associated with a gralloc buffer for use by external image consumers. Preparing buffer contents for use by external consumers should have been done asynchronously as part of transitioning the image to <span class="monospaced">VK_IMAGE_LAYOUT_PRESENT_SRC_KHR</span>.</p></div>
 </div>
 </div>
 <div class="sect1">
@@ -904,6 +907,25 @@ Deferred support for multiple drivers
 </li>
 </ul></div>
 </li>
+<li>
+<p>
+<strong>2015-11-04</strong>
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Added vkGetSwapchainGrallocUsageANDROID
+</p>
+</li>
+<li>
+<p>
+Replaced vkImportNativeFenceANDROID and vkQueueSignalNativeFenceANDROID
+     with vkAcquireImageANDROID and vkQueueSignalReleaseImageANDROID, to allow
+     drivers to known the ownership state of swapchain images.
+</p>
+</li>
+</ul></div>
+</li>
 </ol></div>
 </div>
 </div>
@@ -911,8 +933,8 @@ Deferred support for multiple drivers
 <div id="footnotes"><hr></div>
 <div id="footer">
 <div id="footer-text">
-Version 1<br>
-Last updated 2015-11-04 09:13:11 PST
+Version 3<br>
+Last updated 2015-11-04 10:58:22 PST
 </div>
 </div>
 </body>
index f923377..f665164 100644 (file)
@@ -48,8 +48,12 @@ typedef struct {
 } VkNativeBufferANDROID;
 
 typedef VkResult (VKAPI *PFN_vkGetSwapchainGrallocUsageANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
+typedef VkResult (VKAPI *PFN_vkAcquireImageANDROID)(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore);
+typedef VkResult (VKAPI *PFN_vkQueueSignalReleaseImageANDROID)(VkQueue queue, VkImage image, int* pNativeFenceFd);
+// -- DEPRECATED --
 typedef VkResult (VKAPI *PFN_vkImportNativeFenceANDROID)(VkDevice device, VkSemaphore semaphore, int nativeFenceFd);
 typedef VkResult (VKAPI *PFN_vkQueueSignalNativeFenceANDROID)(VkQueue queue, int* pNativeFenceFd);
+// ----------------
 
 #ifdef VK_PROTOTYPES
 VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
@@ -58,6 +62,18 @@ VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
     VkImageUsageFlags   imageUsage,
     int*                grallocUsage
 );
+VkResult VKAPI vkAcquireImageANDROID(
+    VkDevice            device,
+    VkImage             image,
+    int                 nativeFenceFd,
+    VkSemaphore         semaphore
+);
+VkResult VKAPI vkQueueSignalReleaseImageANDROID(
+    VkQueue             queue,
+    VkImage             image,
+    int*                pNativeFenceFd
+);
+// -- DEPRECATED --
 VkResult VKAPI vkImportNativeFenceANDROID(
     VkDevice            device,
     VkSemaphore         semaphore,
@@ -67,6 +83,7 @@ VkResult VKAPI vkQueueSignalNativeFenceANDROID(
     VkQueue             queue,
     int*                pNativeFenceFd
 );
+// ----------------
 #endif
 
 #ifdef __cplusplus
index c840e5b..6fca95f 100644 (file)
@@ -1176,14 +1176,26 @@ bool LoadDeviceVtbl(VkDevice device,
         ALOGW("missing device proc: %s", "vkGetSwapchainGrallocUsageANDROID");
         // success = false;
     }
-    vtbl.ImportNativeFenceANDROID = reinterpret_cast<PFN_vkImportNativeFenceANDROID>(get_proc_addr(device, "vkImportNativeFenceANDROID"));
-    if (UNLIKELY(!vtbl.ImportNativeFenceANDROID)) {
-        ALOGE("missing device proc: %s", "vkImportNativeFenceANDROID");
-        success = false;
+    vtbl.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(device, "vkAcquireImageANDROID"));
+    if (UNLIKELY(!vtbl.AcquireImageANDROID)) {
+        // TODO(jessehall): temporarily make this optional, until drivers have been updated
+        // ALOGE("missing device proc: %s", "vkImportNativeFenceANDROID");
+        ALOGW("missing device proc: %s", "vkAcquireImageANDROID");
+        // success = false;
     }
+    vtbl.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(device, "vkQueueSignalReleaseImageANDROID"));
+    if (UNLIKELY(!vtbl.QueueSignalReleaseImageANDROID)) {
+        // TODO(jessehall): temporarily make this optional, until drivers have been updated
+        // ALOGE("missing device proc: %s", "vkQueueSignalReleaseImageANDROID");
+        ALOGW("missing device proc: %s", "vkQueueSignalReleaseImageANDROID");
+        // success = false;
+    }
+    // TODO(jessehall): these are deprecated; remove when drivers have been updated
+    vtbl.ImportNativeFenceANDROID = reinterpret_cast<PFN_vkImportNativeFenceANDROID>(get_proc_addr(device, "vkImportNativeFenceANDROID"));
     vtbl.QueueSignalNativeFenceANDROID = reinterpret_cast<PFN_vkQueueSignalNativeFenceANDROID>(get_proc_addr(device, "vkQueueSignalNativeFenceANDROID"));
-    if (UNLIKELY(!vtbl.QueueSignalNativeFenceANDROID)) {
-        ALOGE("missing device proc: %s", "vkQueueSignalNativeFenceANDROID");
+    if (!((!vtbl.AcquireImageANDROID && !vtbl.QueueSignalReleaseImageANDROID && vtbl.ImportNativeFenceANDROID && vtbl.QueueSignalNativeFenceANDROID) ||
+    (vtbl.AcquireImageANDROID && vtbl.QueueSignalReleaseImageANDROID && !vtbl.ImportNativeFenceANDROID && !vtbl.QueueSignalNativeFenceANDROID))) {
+        ALOGE("driver doesn't support exactly one of old- or new-style VK_EXT_ANDROID_native_buffer commands");
         success = false;
     }
     // clang-format on
index de348e7..429455f 100644 (file)
@@ -263,14 +263,26 @@ bool LoadDeviceVtbl(VkDevice device,
         ALOGW("missing device proc: %s", "vkGetSwapchainGrallocUsageANDROID");
         // success = false;
     }
-    vtbl.ImportNativeFenceANDROID = reinterpret_cast<PFN_vkImportNativeFenceANDROID>(get_proc_addr(device, "vkImportNativeFenceANDROID"));
-    if (UNLIKELY(!vtbl.ImportNativeFenceANDROID)) {
-        ALOGE("missing device proc: %s", "vkImportNativeFenceANDROID");
-        success = false;
+    vtbl.AcquireImageANDROID = reinterpret_cast<PFN_vkAcquireImageANDROID>(get_proc_addr(device, "vkAcquireImageANDROID"));
+    if (UNLIKELY(!vtbl.AcquireImageANDROID)) {
+        // TODO(jessehall): temporarily make this optional, until drivers have been updated
+        // ALOGE("missing device proc: %s", "vkImportNativeFenceANDROID");
+        ALOGW("missing device proc: %s", "vkAcquireImageANDROID");
+        // success = false;
     }
+    vtbl.QueueSignalReleaseImageANDROID = reinterpret_cast<PFN_vkQueueSignalReleaseImageANDROID>(get_proc_addr(device, "vkQueueSignalReleaseImageANDROID"));
+    if (UNLIKELY(!vtbl.QueueSignalReleaseImageANDROID)) {
+        // TODO(jessehall): temporarily make this optional, until drivers have been updated
+        // ALOGE("missing device proc: %s", "vkQueueSignalReleaseImageANDROID");
+        ALOGW("missing device proc: %s", "vkQueueSignalReleaseImageANDROID");
+        // success = false;
+    }
+    // TODO(jessehall): these are deprecated; remove when drivers have been updated
+    vtbl.ImportNativeFenceANDROID = reinterpret_cast<PFN_vkImportNativeFenceANDROID>(get_proc_addr(device, "vkImportNativeFenceANDROID"));
     vtbl.QueueSignalNativeFenceANDROID = reinterpret_cast<PFN_vkQueueSignalNativeFenceANDROID>(get_proc_addr(device, "vkQueueSignalNativeFenceANDROID"));
-    if (UNLIKELY(!vtbl.QueueSignalNativeFenceANDROID)) {
-        ALOGE("missing device proc: %s", "vkQueueSignalNativeFenceANDROID");
+    if (!((!vtbl.AcquireImageANDROID && !vtbl.QueueSignalReleaseImageANDROID && vtbl.ImportNativeFenceANDROID && vtbl.QueueSignalNativeFenceANDROID) ||
+          (vtbl.AcquireImageANDROID && vtbl.QueueSignalReleaseImageANDROID && !vtbl.ImportNativeFenceANDROID && !vtbl.QueueSignalNativeFenceANDROID))) {
+        ALOGE("driver doesn't support exactly one of old- or new-style VK_EXT_ANDROID_native_buffer commands");
         success = false;
     }
     // clang-format on
index 74694a8..6999e1e 100644 (file)
@@ -203,6 +203,8 @@ struct DeviceVtbl {
 
     // Implemented only by drivers, not by layers or the loader
     PFN_vkGetSwapchainGrallocUsageANDROID GetSwapchainGrallocUsageANDROID;
+    PFN_vkAcquireImageANDROID AcquireImageANDROID;
+    PFN_vkQueueSignalReleaseImageANDROID QueueSignalReleaseImageANDROID;
     PFN_vkImportNativeFenceANDROID ImportNativeFenceANDROID;
     PFN_vkQueueSignalNativeFenceANDROID QueueSignalNativeFenceANDROID;
 };
index 6d9f6c8..53c13a9 100644 (file)
@@ -588,14 +588,24 @@ VkResult AcquireNextImageKHR(VkDevice device,
     }
 
     const DeviceVtbl& driver_vtbl = GetDriverVtbl(device);
-    result =
-        driver_vtbl.ImportNativeFenceANDROID(device, semaphore, fence_clone);
+    if (driver_vtbl.AcquireImageANDROID) {
+        result = driver_vtbl.AcquireImageANDROID(
+            device, swapchain.images[idx].image, fence_clone, semaphore);
+    } else {
+        ALOG_ASSERT(driver_vtbl.ImportNativeFenceANDROID,
+                    "Have neither vkAcquireImageANDROID nor "
+                    "vkImportNativeFenceANDROID");
+        result = driver_vtbl.ImportNativeFenceANDROID(device, semaphore,
+                                                      fence_clone);
+    }
     if (result != VK_SUCCESS) {
-        // NOTE: we're relying on ImportNativeFenceANDROID to close
-        // fence_clone, even if the call fails. We could close it ourselves on
-        // failure, but that would create a race condition if the driver closes
-        // it on a failure path. We must assume one of: the driver *always*
-        // closes it even on failure, or *never* closes it on failure.
+        // NOTE: we're relying on AcquireImageANDROID to close fence_clone,
+        // even if the call fails. We could close it ourselves on failure, but
+        // that would create a race condition if the driver closes it on a
+        // failure path: some other thread might create an fd with the same
+        // number between the time the driver closes it and the time we close
+        // it. We must assume one of: the driver *always* closes it even on
+        // failure, or *never* closes it on failure.
         swapchain.window->cancelBuffer(swapchain.window.get(), buffer, fence);
         swapchain.images[idx].dequeued = false;
         swapchain.images[idx].dequeue_fence = -1;
@@ -627,9 +637,17 @@ VkResult QueuePresentKHR(VkQueue queue, VkPresentInfoKHR* present_info) {
         int err;
 
         int fence = -1;
-        result = driver_vtbl.QueueSignalNativeFenceANDROID(queue, &fence);
+        if (driver_vtbl.QueueSignalReleaseImageANDROID) {
+            result = driver_vtbl.QueueSignalReleaseImageANDROID(
+                queue, img.image, &fence);
+        } else {
+            ALOG_ASSERT(driver_vtbl.QueueSignalNativeFenceANDROID,
+                        "Have neither vkQueueSignalReleaseImageANDROID nor "
+                        "vkQueueSignalNativeFenceANDROID");
+            result = driver_vtbl.QueueSignalNativeFenceANDROID(queue, &fence);
+        }
         if (result != VK_SUCCESS) {
-            ALOGE("vkQueueSignalNativeFenceANDROID failed: %d", result);
+            ALOGE("QueueSignalReleaseImageANDROID failed: %d", result);
             if (final_result == VK_SUCCESS)
                 final_result = result;
             // TODO(jessehall): What happens to the buffer here? Does the app
index e1678ea..053e403 100644 (file)
@@ -238,11 +238,11 @@ PFN_vkVoidFunction GetDeviceProcAddr(VkDevice, const char* name) {
     if (strcmp(name, "vkGetSwapchainGrallocUsageANDROID") == 0)
         return reinterpret_cast<PFN_vkVoidFunction>(
             GetSwapchainGrallocUsageANDROID);
-    if (strcmp(name, "vkImportNativeFenceANDROID") == 0)
-        return reinterpret_cast<PFN_vkVoidFunction>(ImportNativeFenceANDROID);
-    if (strcmp(name, "vkQueueSignalNativeFenceANDROID") == 0)
+    if (strcmp(name, "vkAcquireImageANDROID") == 0)
+        return reinterpret_cast<PFN_vkVoidFunction>(AcquireImageANDROID);
+    if (strcmp(name, "vkQueueSignalReleaseImageANDROID") == 0)
         return reinterpret_cast<PFN_vkVoidFunction>(
-            QueueSignalNativeFenceANDROID);
+            QueueSignalReleaseImageANDROID);
     return nullptr;
 }
 
@@ -673,12 +673,12 @@ VkResult GetSwapchainGrallocUsageANDROID(VkDevice,
     return VK_SUCCESS;
 }
 
-VkResult ImportNativeFenceANDROID(VkDevice, VkSemaphore, int fence) {
+VkResult AcquireImageANDROID(VkDevice, VkImage, int fence, VkSemaphore) {
     close(fence);
     return VK_SUCCESS;
 }
 
-VkResult QueueSignalNativeFenceANDROID(VkQueue, int* fence) {
+VkResult QueueSignalReleaseImageANDROID(VkQueue, VkImage, int* fence) {
     *fence = -1;
     return VK_SUCCESS;
 }
index 6cf0afd..808673a 100644 (file)
@@ -173,8 +173,8 @@ void CmdEndRenderPass(VkCmdBuffer cmdBuffer);
 void CmdExecuteCommands(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers);
 
 VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-VkResult ImportNativeFenceANDROID(VkDevice device, VkSemaphore semaphore, int nativeFenceFd);
-VkResult QueueSignalNativeFenceANDROID(VkQueue queue, int* pNativeFenceFd);
+VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore);
+VkResult QueueSignalReleaseImageANDROID(VkQueue queue, VkImage image, int* pNativeFenceFd);
 // clang-format on
 
 }  // namespace null_driver