= 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.
.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 ==
* 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.
<body class="book">
<div id="header">
<h1>Vulkan on Android Implementor’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>
.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’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">
</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>
<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>
} 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(
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,
VkQueue queue,
int* pNativeFenceFd
);
+// ----------------
#endif
#ifdef __cplusplus
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
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
// 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;
};
}
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;
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
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;
}
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;
}
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