[Mesa-dev] [PATCH 1/1] android: VK_ANDROID_native_buffer implementation WIP

Tapani Pälli tapani.palli at intel.com
Thu Aug 31 10:25:23 UTC 2017


Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
---
 Android.common.mk                       |  3 ++
 include/vulkan/vulkan_intel.h           | 12 +++++
 src/intel/Android.vulkan.mk             |  4 +-
 src/intel/Makefile.sources              |  3 ++
 src/intel/vulkan/anv_entrypoints_gen.py | 24 ++++++++++
 src/intel/vulkan/anv_extensions.py      |  1 +
 src/intel/vulkan/anv_image.c            | 69 +++++++++++++++++++++++++++
 src/intel/vulkan/anv_wsi_android.c      | 82 +++++++++++++++++++++++++++++++++
 src/vulkan/registry/vk.xml              |  2 +-
 9 files changed, 198 insertions(+), 2 deletions(-)
 create mode 100644 src/intel/vulkan/anv_wsi_android.c

diff --git a/Android.common.mk b/Android.common.mk
index ecbbd87165..66f9ccdeec 100644
--- a/Android.common.mk
+++ b/Android.common.mk
@@ -103,6 +103,9 @@ endif
 LOCAL_CFLAGS_32 += -DDEFAULT_DRIVER_DIR=\"/system/lib/$(MESA_DRI_MODULE_REL_PATH)\"
 LOCAL_CFLAGS_64 += -DDEFAULT_DRIVER_DIR=\"/system/lib64/$(MESA_DRI_MODULE_REL_PATH)\"
 
+# Enable VK_ANDROID_native_buffer
+LOCAL_CFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR
+
 # uncomment to keep the debug symbols
 #LOCAL_STRIP_MODULE := false
 
diff --git a/include/vulkan/vulkan_intel.h b/include/vulkan/vulkan_intel.h
index 8ede61b53d..23078fcc34 100644
--- a/include/vulkan/vulkan_intel.h
+++ b/include/vulkan/vulkan_intel.h
@@ -55,6 +55,18 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateDmaBufImageINTEL(
 
 #endif
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#ifndef PFN_vkGetSwapchainGrallocUsageANDROID
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsageANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
+#endif
+#ifndef PFN_vkAcquireImageANDROID
+typedef VkResult (VKAPI_PTR *PFN_vkAcquireImageANDROID)(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
+#endif
+#ifndef PFN_vkQueueSignalReleaseImageANDROID
+typedef VkResult (VKAPI_PTR *PFN_vkQueueSignalReleaseImageANDROID)(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
+#endif
+#endif
+
 #ifdef __cplusplus
 } // extern "C"
 #endif // __cplusplus
diff --git a/src/intel/Android.vulkan.mk b/src/intel/Android.vulkan.mk
index 44edafd24f..bd5ec01468 100644
--- a/src/intel/Android.vulkan.mk
+++ b/src/intel/Android.vulkan.mk
@@ -194,12 +194,14 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 
 intermediates := $(call local-generated-sources-dir)
 
-LOCAL_SRC_FILES := $(VULKAN_FILES)
+LOCAL_SRC_FILES := $(VULKAN_FILES) $(VULKAN_WSI_ANDROID_FILES)
 
 LOCAL_C_INCLUDES := \
 	$(ANV_INCLUDES) \
 	$(MESA_TOP)/src/compiler
 
+LOCAL_CFLAGS += -isystem frameworks/native/vulkan/include
+
 LOCAL_WHOLE_STATIC_LIBRARIES := \
 	libmesa_anv_entrypoints \
 	libmesa_genxml \
diff --git a/src/intel/Makefile.sources b/src/intel/Makefile.sources
index 4074ba9ee5..752e137b6b 100644
--- a/src/intel/Makefile.sources
+++ b/src/intel/Makefile.sources
@@ -232,6 +232,9 @@ VULKAN_WSI_WAYLAND_FILES := \
 VULKAN_WSI_X11_FILES := \
 	vulkan/anv_wsi_x11.c
 
+VULKAN_WSI_ANDROID_FILES := \
+	vulkan/anv_wsi_android.c
+
 VULKAN_GEM_FILES := \
 	vulkan/anv_gem.c
 
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index f5c527ed92..7ddfcad839 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -360,6 +360,30 @@ def main():
                         'VkImage* pImage', len(entrypoints),
                         cal_hash('vkCreateDmaBufImageINTEL'), None))
 
+    # Insert Android specific entrypoints
+    entrypoints.append(('VkResult', 'GetSwapchainGrallocUsageANDROID',
+                        'VkDevice device, ' +
+                        'VkFormat fmt, ' +
+                        'VkImageUsageFlags usage, ' +
+                        'int *grallocUsage', len(entrypoints),
+                        cal_hash('vkGetSwapchainGrallocUsageANDROID'), None))
+
+    entrypoints.append(('VkResult', 'AcquireImageANDROID',
+                        'VkDevice device, ' +
+                        'VkImage image, ' +
+                        'int nativeFenceFd, ' +
+                        'VkSemaphore semaphore, ' +
+                        'VkFence fence', len(entrypoints),
+                        cal_hash('vkAcquireImageANDROID'), None))
+
+    entrypoints.append(('VkResult', 'QueueSignalReleaseImageANDROID',
+                        'VkQueue queue, ' +
+                        'uint32_t waitSemaphoreCount, ' +
+                        'const VkSemaphore* pWaitSemaphores, ' +
+                        'VkImage image, ' +
+                        'int *pNativeFenceFd', len(entrypoints),
+                        cal_hash('vkQueueSignalReleaseImageANDROID'), None))
+
     # For outputting entrypoints.h we generate a anv_EntryPoint() prototype
     # per entry point.
     with open(os.path.join(args.outdir, 'anv_entrypoints.h'), 'wb') as f:
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index 6b3d72e4b4..598be4d49a 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -71,6 +71,7 @@ EXTENSIONS = [
     Extension('VK_KHR_surface',                          25, True),
     Extension('VK_KHR_swapchain',                        68, True),
     Extension('VK_KHR_variable_pointers',                 1, True),
+    Extension('VK_ANDROID_native_buffer',                 4, 'VK_USE_PLATFORM_ANDROID_KHR'),
     Extension('VK_KHR_wayland_surface',                   6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
     Extension('VK_KHR_xcb_surface',                       6, 'VK_USE_PLATFORM_XCB_KHR'),
     Extension('VK_KHR_xlib_surface',                      6, 'VK_USE_PLATFORM_XLIB_KHR'),
diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c
index 4f0a818b08..36f2b073aa 100644
--- a/src/intel/vulkan/anv_image.c
+++ b/src/intel/vulkan/anv_image.c
@@ -30,9 +30,14 @@
 
 #include "anv_private.h"
 #include "util/debug.h"
+#include "vulkan/util/vk_util.h"
 
 #include "vk_format_info.h"
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+#include <vulkan/vk_android_native_buffer.h>
+#endif
+
 /**
  * Exactly one bit must be set in \a aspect.
  */
@@ -338,6 +343,61 @@ make_surface(const struct anv_device *dev,
    return VK_SUCCESS;
 }
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+static int
+anv_ioctl(int fd, unsigned long request, void *arg)
+{
+   int ret;
+
+   do {
+      ret = ioctl(fd, request, arg);
+   } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+   return ret;
+}
+
+static VkResult
+android_anv_image_create(VkDevice _device,
+                         const VkAllocationCallbacks* alloc,
+                         const VkImageCreateInfo *pCreateInfo,
+                         const VkNativeBufferANDROID* buffer,
+                         VkImage *pImage)
+{
+   struct anv_device *device = anv_device_from_handle(_device);
+   const native_handle_t* handle = (const native_handle_t*) (buffer->handle);
+
+   struct drm_i915_gem_get_tiling get_tiling = {
+      .handle = anv_gem_fd_to_handle(device, handle->data[0]),
+   };
+
+   if (anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_GET_TILING,
+       &get_tiling))
+      return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
+
+   uint32_t stride = buffer->stride;
+
+   if (get_tiling.tiling_mode == I915_TILING_X)
+      stride *= 4;
+
+   VkDeviceMemory pMem;
+   VkDmaBufImageCreateInfo dmabufInfo = {
+      .sType = VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL,
+      .pNext = NULL,
+      .fd = handle->data[0],
+      .format = pCreateInfo->format,
+      .extent = {
+         .width = pCreateInfo->extent.width,
+         .height = pCreateInfo->extent.height,
+         .depth = pCreateInfo->extent.depth,
+      },
+      .strideInBytes = stride,
+   };
+
+   return anv_CreateDmaBufImageINTEL(_device, &dmabufInfo, alloc, &pMem,
+                                     pImage);
+}
+#endif
+
 VkResult
 anv_image_create(VkDevice _device,
                  const struct anv_image_create_info *create_info,
@@ -358,6 +418,15 @@ anv_image_create(VkDevice _device,
    anv_assert(pCreateInfo->extent.height > 0);
    anv_assert(pCreateInfo->extent.depth > 0);
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+   vk_foreach_struct(image_ext, pCreateInfo->pNext) {
+      if (image_ext->sType == VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID)
+         return android_anv_image_create(_device, alloc, pCreateInfo,
+                                         (const VkNativeBufferANDROID *)
+                                         image_ext, pImage);
+   }
+#endif
+
    image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
    if (!image)
diff --git a/src/intel/vulkan/anv_wsi_android.c b/src/intel/vulkan/anv_wsi_android.c
new file mode 100644
index 0000000000..4e38e5f305
--- /dev/null
+++ b/src/intel/vulkan/anv_wsi_android.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <libsync.h>
+#include <util/hash_table.h>
+#include "vk_format_info.h"
+#include "anv_private.h"
+
+/* libhardware/include/hardware/gralloc.h */
+enum {
+   GRALLOC_USAGE_HW_TEXTURE = 0x00000100,
+   GRALLOC_USAGE_HW_RENDER = 0x00000200,
+   GRALLOC_USAGE_HW_FB = 0x00001000,
+};
+
+VkResult
+anv_GetSwapchainGrallocUsageANDROID(VkDevice device,
+                                    VkFormat format,
+                                    VkImageUsageFlags imageUsage,
+                                    int* grallocUsage)
+{
+   VkImageUsageFlags usageSrc =
+      VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
+      VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+
+   VkImageUsageFlags usageDst =
+      VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+   /* used for texturing */
+   if (imageUsage & usageSrc)
+      *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
+
+   /* used for rendering */
+   if (imageUsage & usageDst)
+      *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_AcquireImageANDROID(VkDevice device,
+                        VkImage image,
+                        int nativeFenceFd,
+                        VkSemaphore semaphore,
+                        VkFence fence)
+{
+   sync_wait(nativeFenceFd, -1);
+   close(nativeFenceFd);
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_QueueSignalReleaseImageANDROID(VkQueue queue,
+                                   uint32_t waitSemaphoreCount,
+                                   const VkSemaphore* pWaitSemaphores,
+                                   VkImage image,
+                                   int* pNativeFenceFd)
+{
+   if (pNativeFenceFd)
+      *pNativeFenceFd = -1;
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/registry/vk.xml b/src/vulkan/registry/vk.xml
index f0a1cd625b..cef80b997c 100644
--- a/src/vulkan/registry/vk.xml
+++ b/src/vulkan/registry/vk.xml
@@ -5500,7 +5500,7 @@ private version is maintained in the 1.0 branch of the member gitlab server.
                 <command name="vkGetPhysicalDeviceWin32PresentationSupportKHR"/>
             </require>
         </extension>
-        <extension name="VK_ANDROID_native_buffer" number="11" supported="disabled">
+        <extension name="VK_ANDROID_native_buffer" number="11" type="device" supported="vulkan">
             <require>
                 <enum value="4"                                         name="VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION"/>
                 <enum value="11"                                        name="VK_ANDROID_NATIVE_BUFFER_NUMBER"/>
-- 
2.13.5



More information about the mesa-dev mailing list