vulkan: allow drivers to see image acquire/release
Change-Id: I8143aeebd1f65142486cc55662c685d081ba41eb
(cherry picked from commit 58b4df743ecad9f1a0fc7cb7c0f5340dd8365308)
diff --git a/vulkan/libvulkan/get_proc_addr.cpp b/vulkan/libvulkan/get_proc_addr.cpp
index c840e5b..6fca95f 100644
--- a/vulkan/libvulkan/get_proc_addr.cpp
+++ b/vulkan/libvulkan/get_proc_addr.cpp
@@ -1176,14 +1176,26 @@
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
diff --git a/vulkan/libvulkan/get_proc_addr.cpp.tmpl b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
index de348e7..429455f 100644
--- a/vulkan/libvulkan/get_proc_addr.cpp.tmpl
+++ b/vulkan/libvulkan/get_proc_addr.cpp.tmpl
@@ -263,14 +263,26 @@
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
diff --git a/vulkan/libvulkan/loader.h b/vulkan/libvulkan/loader.h
index 74694a8..6999e1e 100644
--- a/vulkan/libvulkan/loader.h
+++ b/vulkan/libvulkan/loader.h
@@ -203,6 +203,8 @@
// 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;
};
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 6d9f6c8..53c13a9 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -588,14 +588,24 @@
}
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 @@
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