Mesa (main): venus: add support for external fence on Android
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jun 11 23:54:30 UTC 2021
Module: Mesa
Branch: main
Commit: e2ac01aaac8bb5a9adbbe0ff84c75a0b395b2414
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e2ac01aaac8bb5a9adbbe0ff84c75a0b395b2414
Author: Chia-I Wu <olvaffe at gmail.com>
Date: Tue Jun 8 10:54:49 2021 -0700
venus: add support for external fence on Android
This is a hack.
Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Yiwei Zhang <zzyiwei at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11253>
---
src/virtio/vulkan/vn_device.c | 13 ++++++++
src/virtio/vulkan/vn_queue.c | 75 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 86 insertions(+), 2 deletions(-)
diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c
index 94465092646..2ea3efb4f85 100644
--- a/src/virtio/vulkan/vn_device.c
+++ b/src/virtio/vulkan/vn_device.c
@@ -1412,6 +1412,13 @@ vn_physical_device_init_external_fence_handles(
* and idle waiting.
*/
physical_dev->external_fence_handles = 0;
+
+#ifdef ANDROID
+ if (physical_dev->instance->experimental.globalFencing) {
+ physical_dev->external_fence_handles =
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
+ }
+#endif
}
static void
@@ -1468,6 +1475,12 @@ vn_physical_device_get_native_extensions(
#endif
}
+#ifdef ANDROID
+ if (instance->experimental.globalFencing) {
+ exts->KHR_external_fence_fd = true;
+ }
+#endif
+
#ifdef VN_USE_WSI_PLATFORM
exts->KHR_incremental_present = true;
exts->KHR_swapchain = true;
diff --git a/src/virtio/vulkan/vn_queue.c b/src/virtio/vulkan/vn_queue.c
index b1cfa79ea6a..c694d734b78 100644
--- a/src/virtio/vulkan/vn_queue.c
+++ b/src/virtio/vulkan/vn_queue.c
@@ -10,6 +10,7 @@
#include "vn_queue.h"
+#include "util/libsync.h"
#include "venus-protocol/vn_protocol_driver_event.h"
#include "venus-protocol/vn_protocol_driver_fence.h"
#include "venus-protocol/vn_protocol_driver_queue.h"
@@ -664,12 +665,60 @@ vn_WaitForFences(VkDevice device,
return vn_result(dev->instance, result);
}
+static VkResult
+vn_create_sync_file(struct vn_device *dev, int *out_fd)
+{
+ struct vn_renderer_sync *sync;
+ VkResult result = vn_renderer_sync_create(dev->renderer, 0,
+ VN_RENDERER_SYNC_BINARY, &sync);
+ if (result != VK_SUCCESS)
+ return vn_error(dev->instance, result);
+
+ const struct vn_renderer_submit submit = {
+ .batches =
+ &(const struct vn_renderer_submit_batch){
+ .syncs = &sync,
+ .sync_values = &(const uint64_t){ 1 },
+ .sync_count = 1,
+ },
+ .batch_count = 1,
+ };
+ result = vn_renderer_submit(dev->renderer, &submit);
+ if (result != VK_SUCCESS) {
+ vn_renderer_sync_destroy(dev->renderer, sync);
+ return vn_error(dev->instance, result);
+ }
+
+ *out_fd = vn_renderer_sync_export_syncobj(dev->renderer, sync, true);
+ vn_renderer_sync_destroy(dev->renderer, sync);
+
+ return *out_fd >= 0 ? VK_SUCCESS : VK_ERROR_TOO_MANY_OBJECTS;
+}
+
VkResult
vn_ImportFenceFdKHR(VkDevice device,
const VkImportFenceFdInfoKHR *pImportFenceFdInfo)
{
struct vn_device *dev = vn_device_from_handle(device);
- return vn_error(dev->instance, VK_ERROR_UNKNOWN);
+ struct vn_fence *fence = vn_fence_from_handle(pImportFenceFdInfo->fence);
+ ASSERTED const bool sync_file = pImportFenceFdInfo->handleType ==
+ VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
+ const int fd = pImportFenceFdInfo->fd;
+
+ assert(dev->instance->experimental.globalFencing);
+ assert(sync_file);
+ if (fd >= 0) {
+ const int ret = sync_wait(fd, -1);
+ if (ret)
+ return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
+
+ close(fd);
+ }
+
+ /* abuse VN_SYNC_TYPE_WSI_SIGNALED */
+ vn_fence_signal_wsi(dev, fence);
+
+ return VK_SUCCESS;
}
VkResult
@@ -678,7 +727,29 @@ vn_GetFenceFdKHR(VkDevice device,
int *pFd)
{
struct vn_device *dev = vn_device_from_handle(device);
- return vn_error(dev->instance, VK_ERROR_UNKNOWN);
+ struct vn_fence *fence = vn_fence_from_handle(pGetFdInfo->fence);
+ const bool sync_file =
+ pGetFdInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
+ struct vn_sync_payload *payload = fence->payload;
+
+ assert(dev->instance->experimental.globalFencing);
+ assert(sync_file);
+ int fd = -1;
+ if (payload->type == VN_SYNC_TYPE_DEVICE_ONLY) {
+ VkResult result = vn_create_sync_file(dev, &fd);
+ if (result != VK_SUCCESS)
+ return vn_error(dev->instance, result);
+ }
+
+ if (sync_file) {
+ vn_sync_payload_release(dev, &fence->temporary);
+ fence->payload = &fence->permanent;
+
+ /* XXX implies reset operation on the host fence */
+ }
+
+ *pFd = fd;
+ return VK_SUCCESS;
}
/* semaphore commands */
More information about the mesa-commit
mailing list