On Sat, Sep 2, 2017 at 1:17 AM, Chad Versace <chadvers...@chromium.org> wrote:
> This implementation is correct (afaict), but takes two shortcuts > regarding the import/export of Android sync fds. > > Shortcut 1. When Android calls vkAcquireImageANDROID to import a sync > fd into a VkSemaphore or VkFence, the driver instead simply blocks on > the sync fd, then puts the VkSemaphore or VkFence into the signalled > state. Thanks to implicit sync, this produces correct behavior (with > extra latency overhead, perhaps) despite its ugliness. > > Shortcut 2. When Android calls vkQueueSignalReleaseImageANDROID to > export > a collection of wait semaphores as a sync fd, the driver instead > submits the semaphores to the queue, then returns sync fd -1, which > informs the caller that no additional synchronization is needed. > Again, thanks to implicit sync, this produces correct behavior (with > extra batch submission overhead) despite its ugliness. > > I chose to take the shortcuts instead of properly importing/exporting > the sync fds for two reasons: > > Reason 1. I've already tested this patch with dEQP and with demos > apps. It works. I wanted to get the tested patches into the tree now, > and polish the implementation afterwards. > > Reason 2. I want to run this on a 3.18 kernel (gasp!). In 3.18, i915 > supports neither Android's sync_fence, nor upstream's sync_file, nor > drm_syncobj. Again, I tested these patches on Android with a 3.18 > kernel and they work. > > I plan to quickly follow-up with patches that remove the shortcuts and > properly import/export the sync fds. > Let's see how review goes but my Saturday morning gut reaction is that I'd rather we merge the "correct" version upstream directly and you can carry the implicit sync version as a patch in the ChromeOS tree. I can probably be convinced otherwise but that's my reactioin today. > Non-Testing > =========== > I did not test at all using the Android.mk buildsystem. I probably > broke it. Please test and review that. > > Testing > ======= > I tested with 64-bit ARC++ on a Skylake Chromebook and a 3.18 kernel. > The following pass: > > a little spinning cube demo APK > dEQP-VK.info.* > dEQP-VK.api.smoke.* > dEQP-VK.api.info.instance.* > dEQP-VK.api.info.device.* > dEQP-VK.api.wsi.android.* > --- > src/intel/Makefile.sources | 3 + > src/intel/Makefile.vulkan.am | 4 + > src/intel/vulkan/anv_android.c | 246 > ++++++++++++++++++++++++++++++++ > src/intel/vulkan/anv_device.c | 38 ++++- > src/intel/vulkan/anv_entrypoints_gen.py | 10 +- > src/intel/vulkan/anv_extensions.py | 1 + > src/intel/vulkan/anv_image.c | 129 +++++++++++++++-- > src/intel/vulkan/anv_private.h | 1 + > 8 files changed, 421 insertions(+), 11 deletions(-) > create mode 100644 src/intel/vulkan/anv_android.c > > diff --git a/src/intel/Makefile.sources b/src/intel/Makefile.sources > index f6a69f65455..e4a371cbe3f 100644 > --- a/src/intel/Makefile.sources > +++ b/src/intel/Makefile.sources > @@ -228,6 +228,9 @@ VULKAN_FILES := \ > vulkan/anv_wsi.c \ > vulkan/vk_format_info.h > > +VULKAN_ANDROID_FILES := \ > + vulkan/anv_android.c > + > VULKAN_WSI_WAYLAND_FILES := \ > vulkan/anv_wsi_wayland.c > > diff --git a/src/intel/Makefile.vulkan.am b/src/intel/Makefile.vulkan.am > index d1b1132ed2e..bc4b12768ad 100644 > --- a/src/intel/Makefile.vulkan.am > +++ b/src/intel/Makefile.vulkan.am > @@ -147,8 +147,12 @@ VULKAN_LIB_DEPS = \ > -lm > > if HAVE_PLATFORM_ANDROID > +VULKAN_CPPFLAGS += \ > + -I$(top_srcdir)/include/android \ > + $(ANDROID_CPPFLAGS) > VULKAN_CFLAGS += $(ANDROID_CFLAGS) > VULKAN_LIB_DEPS += $(ANDROID_LIBS) > +VULKAN_SOURCES += $(VULKAN_ANDROID_FILES) > endif > > if HAVE_PLATFORM_X11 > diff --git a/src/intel/vulkan/anv_android.c b/src/intel/vulkan/anv_ > android.c > new file mode 100644 > index 00000000000..24274510cd6 > --- /dev/null > +++ b/src/intel/vulkan/anv_android.c > @@ -0,0 +1,246 @@ > +/* > + * Copyright 2017 Google > + * > + * 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 <hardware/gralloc.h> > +#include <hardware/hardware.h> > +#include <hardware/hwvulkan.h> > +#include <vulkan/vk_android_native_buffer.h> > +#include <vulkan/vk_icd.h> > +#include <sync/sync.h> > + > +#include "anv_private.h" > + > + > +#include "anv_private.h" > + > +static int anv_hal_open(const struct hw_module_t* mod, const char* id, > struct hw_device_t** dev); > +static int anv_hal_close(struct hw_device_t *dev); > + > +static void UNUSED > +static_asserts(void) > +{ > + STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC); > +} > + > +PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = { > + .common = { > + .tag = HARDWARE_MODULE_TAG, > + .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1, > + .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0), > + .id = HWVULKAN_HARDWARE_MODULE_ID, > + .name = "Intel Vulkan HAL", > + .author = "Intel", > + .methods = &(hw_module_methods_t) { > + .open = anv_hal_open, > + }, > + }, > +}; > + > +static int > +anv_hal_open(const struct hw_module_t* mod, const char* id, > + struct hw_device_t** dev) > +{ > + assert(mod == &HAL_MODULE_INFO_SYM.common); > + assert(strcmp(id, HWVULKAN_DEVICE_0) == 0); > + > + hwvulkan_device_t *vkdev = malloc(sizeof(*vkdev)); > + if (!vkdev) > + return -1; > + > + *vkdev = (hwvulkan_device_t) { > + .common = { > + .tag = HARDWARE_DEVICE_TAG, > + .version = HWVULKAN_DEVICE_API_VERSION_0_1, > + .module = &HAL_MODULE_INFO_SYM.common, > + .close = anv_hal_close, > + }, > + .EnumerateInstanceExtensionProperties = anv_ > EnumerateInstanceExtensionProperties, > + .CreateInstance = anv_CreateInstance, > + .GetInstanceProcAddr = anv_GetInstanceProcAddr, > + }; > + > + *dev = &vkdev->common; > + return 0; > +} > + > +static int > +anv_hal_close(struct hw_device_t *dev) > +{ > + /* hwvulkan.h claims that hw_device_t::close() is never called. */ > + return -1; > +} > + > +VkResult anv_GetSwapchainGrallocUsageANDROID( > + VkDevice device_h, > + VkFormat format, > + VkImageUsageFlags imageUsage, > + int* grallocUsage) > +{ > + ANV_FROM_HANDLE(anv_device, device, device_h); > + struct anv_physical_device *phys_dev = &device->instance-> > physicalDevice; > + VkPhysicalDevice phys_dev_h = anv_physical_device_to_handle(phys_dev); > + VkFormatProperties props; > + > + static const VkFormat fb_formats[] = { > + VK_FORMAT_B8G8R8A8_UNORM, > + VK_FORMAT_B5G6R5_UNORM_PACK16, > + }; > + > + *grallocUsage = 0; > + anv_GetPhysicalDeviceFormatProperties(phys_dev_h, format, &props); > + > + for (uint32_t i = 0; i < ARRAY_SIZE(fb_formats); ++i) { > + if (format == fb_formats[i]) { > + /* TODO(chadv): Query these properties from isl. */ > + *grallocUsage |= GRALLOC_USAGE_HW_FB | > + GRALLOC_USAGE_HW_COMPOSER | > + GRALLOC_USAGE_EXTERNAL_DISP; > + break; > + } > + } > + > + if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_ > IMAGE_BIT)) > + *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE; > + > + if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ > ATTACHMENT_BIT)) > + *grallocUsage |= GRALLOC_USAGE_HW_RENDER; > + > + if ((props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_ > IMAGE_BIT)) > + *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE; > + > + if (*grallocUsage == 0) > + return VK_ERROR_FORMAT_NOT_SUPPORTED; > + > + return VK_SUCCESS; > +} > + > +VkResult > +anv_AcquireImageANDROID( > + VkDevice device_h, > + VkImage image_h, > + int nativeFenceFd, > + VkSemaphore semaphore_h, > + VkFence fence_h) > +{ > + ANV_FROM_HANDLE(anv_semaphore, semaphore, semaphore_h); > + ANV_FROM_HANDLE(anv_fence, fence, fence_h); > + VkResult result = VK_SUCCESS; > + > + if (nativeFenceFd != -1) { > + /* As a simple, firstpass implementation of > VK_ANDROID_native_buffer, we > + * block on the nativeFenceFd. This may introduce latency and is > + * definitiely inefficient, yet it's correct. > + * > + * FINISHME(chadv): Import the nativeFenceFd into the VkSemaphore > and > + * VkFence. > + */ > + if (sync_wait(nativeFenceFd, /*timeout*/ -1) < 0) { > + result = vk_errorf(VK_ERROR_DEVICE_LOST, > + "%s: failed to wait on nativeFenceFd=%d", > + __func__, nativeFenceFd); > + goto done; > + } > + } > + > + if (semaphore) { > + /* It's illegal to import into an existing import. */ > + assert(semaphore->temporary.type == ANV_SEMAPHORE_TYPE_NONE); > + > + /* It's also illegal here to import into an in-flight semaphore. > + * Therefore, thanks to implicit sync, there's nothing to do here > + * because we have already blocked on the nativeFenceFd. > + */ > + } > + > + if (fence) { > + /* It's illegal to import into an existing import. */ > + assert(fence->temporary.type == ANV_FENCE_TYPE_NONE); > + > + > + /* We can transition the fence's state from reset to signalled > because > + * we blocked on the sync fd. Since the fence had no waiters, > there's no > + * need to broadcast the state transition. > + */ > + switch (fence->permanent.type) { > + case ANV_FENCE_TYPE_NONE: > + unreachable("anv_fence::permanent::type is NONE"); > + case ANV_FENCE_TYPE_BO: > + /* It's illegal to import into a fence in the non-resting state. > */ > + assert(fence->permanent.bo.state == ANV_BO_FENCE_STATE_RESET); > + fence->permanent.bo.state = ANV_BO_FENCE_STATE_SIGNALED; > + break; > + case ANV_FENCE_TYPE_SYNCOBJ: > + break; > + } > + } > + > + done: > + if (nativeFenceFd != -1) { > + /* From VK_ANDROID_native_buffer's pseudo spec > + * (https://source.android.com/devices/graphics/implement-vulkan): > + * > + * The driver takes ownership of the fence fd and is responsible > for > + * closing it [...] even if vkAcquireImageANDROID fails and > returns > + * an error. > + */ > + close(nativeFenceFd); > + } > + > + return result; > +} > + > +VkResult > +anv_QueueSignalReleaseImageANDROID( > + VkQueue queue, > + uint32_t waitSemaphoreCount, > + const VkSemaphore* pWaitSemaphores, > + VkImage image, > + int* pNativeFenceFd) > +{ > + VkResult result; > + > + if (waitSemaphoreCount == 0) > + goto done; > + > + result = anv_QueueSubmit(queue, > + 1, (VkSubmitInfo[]) { > + { > + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, > + .waitSemaphoreCount = 1, > + .pWaitSemaphores = pWaitSemaphores, > + }, > + }, > + (VkFence) VK_NULL_HANDLE); > + if (result != VK_SUCCESS) > + return result; > + > + done: > + if (pNativeFenceFd) { > + /* We can rely implicit on sync because above we submitted all > + * semaphores to the queue. > + */ > + *pNativeFenceFd = -1; > + } > + > + return VK_SUCCESS; > +} > diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c > index 8cc760c3721..d221ba46645 100644 > --- a/src/intel/vulkan/anv_device.c > +++ b/src/intel/vulkan/anv_device.c > @@ -1440,10 +1440,20 @@ VkResult anv_AllocateMemory( > struct anv_device_memory *mem; > VkResult result = VK_SUCCESS; > > + /* VK_ANDROID_native_buffer defines VkNativeBufferANDROID as an > extension > + * of VkImageCreateInfo. We abuse the struct by chaining it to > + * VkMemoryAllocateInfo in the implementation of vkCreateImage. > + */ > + const VkNativeBufferANDROID *gralloc_info = NULL; > +#ifdef ANDROID > + gralloc_info = vk_find_struct_const(pAllocateInfo->pNext, > NATIVE_BUFFER_ANDROID); > +#endif > + > assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ > ALLOCATE_INFO); > > /* The Vulkan 1.0.33 spec says "allocationSize must be greater than > 0". */ > - assert(pAllocateInfo->allocationSize > 0); > + assert(gralloc_info || pAllocateInfo->allocationSize > 0); > + assert(!gralloc_info || pAllocateInfo->allocationSize == 0); > > /* The kernel relocation API has a limitation of a 32-bit delta value > * applied to the address before it is written which, in spite of it > being > @@ -1495,7 +1505,31 @@ VkResult anv_AllocateMemory( > 0, &mem->bo); > if (result != VK_SUCCESS) > goto fail; > - } else { > + } > +#ifdef ANDROID > + else if (gralloc_info) { > + if (gralloc_info->handle->numFds != 1) { > + result = vk_errorf(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR, > + "VkNativeBufferANDROID::handle::numFds is > %d, " > + "expected 1", gralloc_info->handle->numFds); > + goto fail; > + } > + > + int dma_buf = gralloc_info->handle->data[0]; > + > + /* Do not close the gralloc handle's dma_buf fd. The lifetime of the > + * dma_buf fd must exceed that of the gralloc handle, and we do not > own > + * the gralloc handle. > + */ > + result = anv_bo_cache_import(device, &device->bo_cache, dma_buf, -1, > + ANV_BO_CACHE_IMPORT_NO_CLOSE_FD > + | ANV_BO_CACHE_IMPORT_IGNORE_ > SIZE_PARAM, > + &mem->bo); > + if (result != VK_SUCCESS) > + goto fail; > + } > +#endif > + else { > result = anv_bo_cache_alloc(device, &device->bo_cache, > pAllocateInfo->allocationSize, > &mem->bo); > diff --git a/src/intel/vulkan/anv_entrypoints_gen.py > b/src/intel/vulkan/anv_entrypoints_gen.py > index 983be09a39b..dcdde31cdd7 100644 > --- a/src/intel/vulkan/anv_entrypoints_gen.py > +++ b/src/intel/vulkan/anv_entrypoints_gen.py > @@ -271,7 +271,15 @@ def get_entrypoints(doc, entrypoints_to_defines, > start_index): > if extension.attrib['name'] not in supported: > continue > > - assert extension.attrib['supported'] == 'vulkan' > + # Workaround VK_ANDROID_native_buffer. In vk.xml, it's listed as > + # supported="disabled", but we patch it to supported="vulkan" in > our > + # custom vk_android_native_buffer.xml. > + assert (extension.attrib['supported'] == 'vulkan' or > + extension.attrib['name'] == 'VK_ANDROID_native_buffer') > + > + if extension.attrib['supported'] != 'vulkan': > + continue > + > for command in extension.findall('./require/command'): > enabled_commands.add(command.attrib['name']) > > diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_ > extensions.py > index 6cd0c3692b6..18062359d31 100644 > --- a/src/intel/vulkan/anv_extensions.py > +++ b/src/intel/vulkan/anv_extensions.py > @@ -50,6 +50,7 @@ class Extension: > # the those extension strings, then tests dEQP-VK.api.info.instance. > extensions > # and dEQP-VK.api.info.device fail due to the duplicated strings. > EXTENSIONS = [ > + Extension('VK_ANDROID_native_buffer', 5, 'ANDROID'), > Extension('VK_KHR_dedicated_allocation', 1, True), > Extension('VK_KHR_descriptor_update_template', 1, True), > Extension('VK_KHR_external_fence', 1, > diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c > index 1cc3adae5ee..1b8bb363a17 100644 > --- a/src/intel/vulkan/anv_image.c > +++ b/src/intel/vulkan/anv_image.c > @@ -32,6 +32,11 @@ > #include "util/debug.h" > > #include "vk_format_info.h" > +#include "vk_util.h" > + > +static void > +add_fast_clear_state_buffer(struct anv_image *image, > + const struct anv_device *device); > > static void > add_fast_clear_state_buffer(struct anv_image *image, > @@ -111,7 +116,9 @@ get_surface(struct anv_image *image, > VkImageAspectFlags aspect) > } > > static VkResult > -choose_isl_tiling_flags(const struct anv_image_create_info *anv_info, > +choose_isl_tiling_flags(struct anv_device *device, > + const struct anv_image_create_info *anv_info, > + const VkNativeBufferANDROID *gralloc_info, > isl_tiling_flags_t *restrict flags) > { > *flags = ISL_TILING_ANY_MASK; > @@ -122,6 +129,41 @@ choose_isl_tiling_flags(const struct > anv_image_create_info *anv_info, > if (anv_info->isl_tiling_flags) > *flags &= anv_info->isl_tiling_flags; > > +#if defined(ANDROID) > + if (gralloc_info) { > + int dma_buf = gralloc_info->handle->data[0]; > + > + uint32_t gem_handle = anv_gem_fd_to_handle(device, dma_buf); > + if (gem_handle == 0) { > + return vk_errorf(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR, > + "DRM_IOCTL_PRIME_FD_TO_HANDLE failed for " > + "VkNativeBufferANDROID"); > + } > + > + int i915_tiling = anv_gem_get_tiling(device, gem_handle); > + switch (i915_tiling) { > + case I915_TILING_NONE: > + *flags &= ISL_TILING_LINEAR_BIT; > + break; > + case I915_TILING_X: > + *flags &= ISL_TILING_X_BIT; > + break; > + case I915_TILING_Y: > + *flags &= ISL_TILING_Y0_BIT; > + break; > + case -1: > + return vk_errorf(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR, > + "DRM_IOCTL_I915_GEM_GET_TILING failed for " > + "VkNativeBufferANDROID"); > + default: > + return vk_errorf(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR, > + "DRM_IOCTL_I915_GEM_GET_TILING returned unknown > " > + "tiling %d for VkNativeBufferANDROID", > i915_tiling); > + > + } > + } > +#endif > + > return VK_SUCCESS; > } > > @@ -245,9 +287,13 @@ try_make_mcs_surface(const struct anv_device *dev, > static VkResult > try_make_aux_surface(const struct anv_device *dev, > const VkImageCreateInfo *base_info, > + const VkNativeBufferANDROID *gralloc_info, > VkImageAspectFlags aspect, > struct anv_image *image) > { > + if (gralloc_info) > + return VK_SUCCESS; > + > if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { > try_make_hiz_surface(dev, base_info, image); > } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && > @@ -344,8 +390,9 @@ add_fast_clear_state_buffer(struct anv_image *image, > * Exactly one bit must be set in \a aspect. > */ > static VkResult > -make_main_surface(const struct anv_device *dev, > +make_main_surface(struct anv_device *dev, > const struct anv_image_create_info *anv_info, > + const VkNativeBufferANDROID *gralloc_info, > VkImageAspectFlags aspect, > struct anv_image *image) > { > @@ -360,7 +407,8 @@ make_main_surface(const struct anv_device *dev, > }; > > isl_tiling_flags_t tiling_flags; > - result = choose_isl_tiling_flags(anv_info, &tiling_flags); > + result = choose_isl_tiling_flags(dev, anv_info, gralloc_info, > + &tiling_flags); > if (result != VK_SUCCESS) > return result; > > @@ -373,6 +421,19 @@ make_main_surface(const struct anv_device *dev, > aspect, base_info->tiling); > assert(format != ISL_FORMAT_UNSUPPORTED); > > + uint32_t row_pitch = anv_info->stride; > +#ifdef ANDROID > + if (gralloc_info) { > + row_pitch = gralloc_info->stride * > + (isl_format_get_layout(format)->bpb / 8); > + } > +#endif > + > + isl_surf_usage_flags_t usage = > + choose_isl_surf_usage(base_info->flags, image->usage, aspect); > + if (gralloc_info) > + usage |= ISL_SURF_USAGE_DISABLE_AUX_BIT; > + > ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl, > .dim = vk_to_isl_surf_dim[base_info->imageType], > .format = format, > @@ -383,8 +444,8 @@ make_main_surface(const struct anv_device *dev, > .array_len = base_info->arrayLayers, > .samples = base_info->samples, > .min_alignment = 0, > - .row_pitch = anv_info->stride, > - .usage = choose_isl_surf_usage(base_info->flags, image->usage, > aspect), > + .row_pitch = row_pitch, > + .usage = usage, > .tiling_flags = tiling_flags); > > /* isl_surf_init() will fail only if provided invalid input. Invalid > input > @@ -393,9 +454,50 @@ make_main_surface(const struct anv_device *dev, > assert(ok); > > add_surface(image, anv_surf); > + > + if (gralloc_info) > + assert(anv_surf->offset == 0); > + > return VK_SUCCESS; > } > > +#ifdef ANDROID > +static VkResult > +import_gralloc(struct anv_device *device, > + struct anv_image *image, > + const VkNativeBufferANDROID *gralloc_info, > + const VkAllocationCallbacks *alloc) > +{ > + VkDevice device_h = anv_device_to_handle(device); > + VkDeviceMemory mem_h = VK_NULL_HANDLE; > + VkResult result; > + > + /* VK_ANDROID_native_buffer defines VkNativeBufferANDROID as an > extension > + * of VkImageCreateInfo. We abuse the struct by chaining it to > + * VkMemoryAllocateInfo. > + */ > + result = anv_AllocateMemory(device_h, > + &(VkMemoryAllocateInfo) { > + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, > + .pNext = gralloc_info, > + .allocationSize = 0, > + .memoryTypeIndex = 0, /* XXX: Arbitrary memory type */ > + }, > + alloc, > + &mem_h); > + > + if (result != VK_SUCCESS) > + return result; > + > + ANV_FROM_HANDLE(anv_device_memory, mem, mem_h); > + image->mem = mem; > + image->mem_offset = 0; > + image->mem_is_owned = true; > + > + return VK_SUCCESS; > +} > +#endif > + > VkResult > anv_image_create(VkDevice _device, > const struct anv_image_create_info *anv_info, > @@ -404,6 +506,8 @@ anv_image_create(VkDevice _device, > { > ANV_FROM_HANDLE(anv_device, device, _device); > const VkImageCreateInfo *base_info = anv_info->vk_info; > + const VkNativeBufferANDROID *gralloc_info = > + vk_find_struct_const(base_info->pNext, NATIVE_BUFFER_ANDROID); > struct anv_image *image = NULL; > VkResult r; > > @@ -432,21 +536,30 @@ anv_image_create(VkDevice _device, > image->tiling = base_info->tiling; > image->aux_usage = ISL_AUX_USAGE_NONE; > > +#ifdef ANDROID > + if (gralloc_info) { > + r = import_gralloc(device, image, gralloc_info, alloc); > + if (r != VK_SUCCESS) > + goto fail; > + } > +#endif > + > uint32_t b; > for_each_bit(b, image->aspects) { > VkImageAspectFlagBits aspect = 1 << b; > > - r = make_main_surface(device, anv_info, aspect, image); > + r = make_main_surface(device, anv_info, gralloc_info, aspect, > image); > if (r != VK_SUCCESS) > goto fail; > > - r = try_make_aux_surface(device, base_info, aspect, image); > + r = try_make_aux_surface(device, base_info, gralloc_info, aspect, > image); > if (r != VK_SUCCESS) > goto fail; > } > > - *pImage = anv_image_to_handle(image); > + VkImage image_h = anv_image_to_handle(image); > > + *pImage = image_h; > return VK_SUCCESS; > > fail: > diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_ > private.h > index d11a2363d9b..dafc37247f5 100644 > --- a/src/intel/vulkan/anv_private.h > +++ b/src/intel/vulkan/anv_private.h > @@ -71,6 +71,7 @@ struct gen_l3_config; > #include <vulkan/vulkan.h> > #include <vulkan/vulkan_intel.h> > #include <vulkan/vk_icd.h> > +#include <vulkan/vk_android_native_buffer.h> > > #include "anv_entrypoints.h" > #include "isl/isl.h" > -- > 2.13.5 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev