101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2017, Google Inc. 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include <hardware/gralloc.h> 257ec681f3Smrg 267ec681f3Smrg#if ANDROID_API_LEVEL >= 26 277ec681f3Smrg#include <hardware/gralloc1.h> 287ec681f3Smrg#endif 297ec681f3Smrg 3001e04c3fSmrg#include <hardware/hardware.h> 3101e04c3fSmrg#include <hardware/hwvulkan.h> 3201e04c3fSmrg#include <vulkan/vk_android_native_buffer.h> 3301e04c3fSmrg#include <vulkan/vk_icd.h> 3401e04c3fSmrg#include <sync/sync.h> 3501e04c3fSmrg 3601e04c3fSmrg#include "anv_private.h" 377ec681f3Smrg#include "vk_common_entrypoints.h" 389f464c52Smaya#include "vk_util.h" 3901e04c3fSmrg 4001e04c3fSmrgstatic int anv_hal_open(const struct hw_module_t* mod, const char* id, struct hw_device_t** dev); 4101e04c3fSmrgstatic int anv_hal_close(struct hw_device_t *dev); 4201e04c3fSmrg 4301e04c3fSmrgstatic void UNUSED 4401e04c3fSmrgstatic_asserts(void) 4501e04c3fSmrg{ 4601e04c3fSmrg STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC); 4701e04c3fSmrg} 4801e04c3fSmrg 4901e04c3fSmrgPUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = { 5001e04c3fSmrg .common = { 5101e04c3fSmrg .tag = HARDWARE_MODULE_TAG, 5201e04c3fSmrg .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1, 5301e04c3fSmrg .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0), 5401e04c3fSmrg .id = HWVULKAN_HARDWARE_MODULE_ID, 5501e04c3fSmrg .name = "Intel Vulkan HAL", 5601e04c3fSmrg .author = "Intel", 5701e04c3fSmrg .methods = &(hw_module_methods_t) { 5801e04c3fSmrg .open = anv_hal_open, 5901e04c3fSmrg }, 6001e04c3fSmrg }, 6101e04c3fSmrg}; 6201e04c3fSmrg 6301e04c3fSmrg/* If any bits in test_mask are set, then unset them and return true. */ 6401e04c3fSmrgstatic inline bool 6501e04c3fSmrgunmask32(uint32_t *inout_mask, uint32_t test_mask) 6601e04c3fSmrg{ 6701e04c3fSmrg uint32_t orig_mask = *inout_mask; 6801e04c3fSmrg *inout_mask &= ~test_mask; 6901e04c3fSmrg return *inout_mask != orig_mask; 7001e04c3fSmrg} 7101e04c3fSmrg 7201e04c3fSmrgstatic int 7301e04c3fSmrganv_hal_open(const struct hw_module_t* mod, const char* id, 7401e04c3fSmrg struct hw_device_t** dev) 7501e04c3fSmrg{ 7601e04c3fSmrg assert(mod == &HAL_MODULE_INFO_SYM.common); 7701e04c3fSmrg assert(strcmp(id, HWVULKAN_DEVICE_0) == 0); 7801e04c3fSmrg 7901e04c3fSmrg hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev)); 8001e04c3fSmrg if (!hal_dev) 8101e04c3fSmrg return -1; 8201e04c3fSmrg 8301e04c3fSmrg *hal_dev = (hwvulkan_device_t) { 8401e04c3fSmrg .common = { 8501e04c3fSmrg .tag = HARDWARE_DEVICE_TAG, 8601e04c3fSmrg .version = HWVULKAN_DEVICE_API_VERSION_0_1, 8701e04c3fSmrg .module = &HAL_MODULE_INFO_SYM.common, 8801e04c3fSmrg .close = anv_hal_close, 8901e04c3fSmrg }, 9001e04c3fSmrg .EnumerateInstanceExtensionProperties = anv_EnumerateInstanceExtensionProperties, 9101e04c3fSmrg .CreateInstance = anv_CreateInstance, 9201e04c3fSmrg .GetInstanceProcAddr = anv_GetInstanceProcAddr, 9301e04c3fSmrg }; 9401e04c3fSmrg 9501e04c3fSmrg *dev = &hal_dev->common; 9601e04c3fSmrg return 0; 9701e04c3fSmrg} 9801e04c3fSmrg 9901e04c3fSmrgstatic int 10001e04c3fSmrganv_hal_close(struct hw_device_t *dev) 10101e04c3fSmrg{ 10201e04c3fSmrg /* hwvulkan.h claims that hw_device_t::close() is never called. */ 10301e04c3fSmrg return -1; 10401e04c3fSmrg} 10501e04c3fSmrg 1069f464c52Smaya#if ANDROID_API_LEVEL >= 26 1077ec681f3Smrg#include <vndk/hardware_buffer.h> 1087ec681f3Smrg/* See i915_private_android_types.h in minigbm. */ 1097ec681f3Smrg#define HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL 0x100 1107ec681f3Smrg 1117ec681f3Smrgenum { 1127ec681f3Smrg /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */ 1137ec681f3Smrg BUFFER_USAGE_CAMERA_MASK = 0x00060000U, 1147ec681f3Smrg}; 1157ec681f3Smrg 1167ec681f3Smrginline VkFormat 1177ec681f3Smrgvk_format_from_android(unsigned android_format, unsigned android_usage) 1187ec681f3Smrg{ 1197ec681f3Smrg switch (android_format) { 1207ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: 1217ec681f3Smrg return VK_FORMAT_R8G8B8A8_UNORM; 1227ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: 1237ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: 1247ec681f3Smrg return VK_FORMAT_R8G8B8_UNORM; 1257ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: 1267ec681f3Smrg return VK_FORMAT_R5G6B5_UNORM_PACK16; 1277ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: 1287ec681f3Smrg return VK_FORMAT_R16G16B16A16_SFLOAT; 1297ec681f3Smrg case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: 1307ec681f3Smrg return VK_FORMAT_A2B10G10R10_UNORM_PACK32; 1317ec681f3Smrg case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: 1327ec681f3Smrg case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL: 1337ec681f3Smrg return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; 1347ec681f3Smrg case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED: 1357ec681f3Smrg if (android_usage & BUFFER_USAGE_CAMERA_MASK) 1367ec681f3Smrg return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; 1377ec681f3Smrg else 1387ec681f3Smrg return VK_FORMAT_R8G8B8_UNORM; 1397ec681f3Smrg case AHARDWAREBUFFER_FORMAT_BLOB: 1407ec681f3Smrg default: 1417ec681f3Smrg return VK_FORMAT_UNDEFINED; 1427ec681f3Smrg } 1437ec681f3Smrg} 1447ec681f3Smrg 1457ec681f3Smrgstatic inline unsigned 1467ec681f3Smrgandroid_format_from_vk(unsigned vk_format) 1477ec681f3Smrg{ 1487ec681f3Smrg switch (vk_format) { 1497ec681f3Smrg case VK_FORMAT_R8G8B8A8_UNORM: 1507ec681f3Smrg return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; 1517ec681f3Smrg case VK_FORMAT_R8G8B8_UNORM: 1527ec681f3Smrg return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; 1537ec681f3Smrg case VK_FORMAT_R5G6B5_UNORM_PACK16: 1547ec681f3Smrg return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; 1557ec681f3Smrg case VK_FORMAT_R16G16B16A16_SFLOAT: 1567ec681f3Smrg return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; 1577ec681f3Smrg case VK_FORMAT_A2B10G10R10_UNORM_PACK32: 1587ec681f3Smrg return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; 1597ec681f3Smrg case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1607ec681f3Smrg#ifdef HAVE_CROS_GRALLOC 1617ec681f3Smrg return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420; 1627ec681f3Smrg#else 1637ec681f3Smrg return HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL; 1647ec681f3Smrg#endif 1657ec681f3Smrg default: 1667ec681f3Smrg return AHARDWAREBUFFER_FORMAT_BLOB; 1677ec681f3Smrg } 1687ec681f3Smrg} 1697ec681f3Smrg 1707ec681f3Smrgstatic VkFormatFeatureFlags 1717ec681f3Smrgfeatures2_to_features(VkFormatFeatureFlags2KHR features2) 1727ec681f3Smrg{ 1737ec681f3Smrg return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 1747ec681f3Smrg} 1757ec681f3Smrg 1769f464c52Smayastatic VkResult 1777ec681f3Smrgget_ahw_buffer_format_properties2( 1789f464c52Smaya VkDevice device_h, 1799f464c52Smaya const struct AHardwareBuffer *buffer, 1807ec681f3Smrg VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties) 1819f464c52Smaya{ 1829f464c52Smaya ANV_FROM_HANDLE(anv_device, device, device_h); 1839f464c52Smaya 1849f464c52Smaya /* Get a description of buffer contents . */ 1859f464c52Smaya AHardwareBuffer_Desc desc; 1869f464c52Smaya AHardwareBuffer_describe(buffer, &desc); 1879f464c52Smaya 1889f464c52Smaya /* Verify description. */ 1899f464c52Smaya uint64_t gpu_usage = 1909f464c52Smaya AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | 1919f464c52Smaya AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | 1929f464c52Smaya AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER; 1939f464c52Smaya 1949f464c52Smaya /* "Buffer must be a valid Android hardware buffer object with at least 1959f464c52Smaya * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags." 1969f464c52Smaya */ 1979f464c52Smaya if (!(desc.usage & (gpu_usage))) 1989f464c52Smaya return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1999f464c52Smaya 2009f464c52Smaya /* Fill properties fields based on description. */ 2017ec681f3Smrg VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties; 2029f464c52Smaya 2039f464c52Smaya p->format = vk_format_from_android(desc.format, desc.usage); 2049f464c52Smaya 2059f464c52Smaya const struct anv_format *anv_format = anv_get_format(p->format); 2069f464c52Smaya p->externalFormat = (uint64_t) (uintptr_t) anv_format; 2079f464c52Smaya 2089f464c52Smaya /* Default to OPTIMAL tiling but set to linear in case 2099f464c52Smaya * of AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER usage. 2109f464c52Smaya */ 2119f464c52Smaya VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; 2129f464c52Smaya 2139f464c52Smaya if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) 2149f464c52Smaya tiling = VK_IMAGE_TILING_LINEAR; 2159f464c52Smaya 2169f464c52Smaya p->formatFeatures = 2177ec681f3Smrg anv_get_image_format_features2(&device->info, p->format, anv_format, 2187ec681f3Smrg tiling, NULL); 2199f464c52Smaya 2209f464c52Smaya /* "Images can be created with an external format even if the Android hardware 2219f464c52Smaya * buffer has a format which has an equivalent Vulkan format to enable 2229f464c52Smaya * consistent handling of images from sources that might use either category 2239f464c52Smaya * of format. However, all images created with an external format are subject 2249f464c52Smaya * to the valid usage requirements associated with external formats, even if 2259f464c52Smaya * the Android hardware buffer’s format has a Vulkan equivalent." 2269f464c52Smaya * 2279f464c52Smaya * "The formatFeatures member *must* include 2289f464c52Smaya * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of 2299f464c52Smaya * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or 2309f464c52Smaya * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT" 2319f464c52Smaya */ 2329f464c52Smaya p->formatFeatures |= 2337ec681f3Smrg VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR; 2349f464c52Smaya 2359f464c52Smaya /* "Implementations may not always be able to determine the color model, 2369f464c52Smaya * numerical range, or chroma offsets of the image contents, so the values 2379f464c52Smaya * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions. 2389f464c52Smaya * Applications should treat these values as sensible defaults to use in 2399f464c52Smaya * the absence of more reliable information obtained through some other 2409f464c52Smaya * means." 2419f464c52Smaya */ 2429f464c52Smaya p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY; 2439f464c52Smaya p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY; 2449f464c52Smaya p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY; 2459f464c52Smaya p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY; 2469f464c52Smaya 2479f464c52Smaya p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601; 2489f464c52Smaya p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL; 2499f464c52Smaya 2509f464c52Smaya p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT; 2519f464c52Smaya p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT; 2529f464c52Smaya 2539f464c52Smaya return VK_SUCCESS; 2549f464c52Smaya} 2559f464c52Smaya 2569f464c52SmayaVkResult 2579f464c52Smayaanv_GetAndroidHardwareBufferPropertiesANDROID( 2589f464c52Smaya VkDevice device_h, 2599f464c52Smaya const struct AHardwareBuffer *buffer, 2609f464c52Smaya VkAndroidHardwareBufferPropertiesANDROID *pProperties) 2619f464c52Smaya{ 2629f464c52Smaya ANV_FROM_HANDLE(anv_device, dev, device_h); 2639f464c52Smaya 2649f464c52Smaya VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop = 2659f464c52Smaya vk_find_struct(pProperties->pNext, 2669f464c52Smaya ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID); 2679f464c52Smaya /* Fill format properties of an Android hardware buffer. */ 2687ec681f3Smrg if (format_prop) { 2697ec681f3Smrg VkAndroidHardwareBufferFormatProperties2ANDROID format_prop2 = { 2707ec681f3Smrg .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID, 2717ec681f3Smrg }; 2727ec681f3Smrg get_ahw_buffer_format_properties2(device_h, buffer, &format_prop2); 2737ec681f3Smrg 2747ec681f3Smrg format_prop->format = format_prop2.format; 2757ec681f3Smrg format_prop->externalFormat = format_prop2.externalFormat; 2767ec681f3Smrg format_prop->formatFeatures = 2777ec681f3Smrg features2_to_features(format_prop2.formatFeatures); 2787ec681f3Smrg format_prop->samplerYcbcrConversionComponents = 2797ec681f3Smrg format_prop2.samplerYcbcrConversionComponents; 2807ec681f3Smrg format_prop->suggestedYcbcrModel = format_prop2.suggestedYcbcrModel; 2817ec681f3Smrg format_prop->suggestedYcbcrRange = format_prop2.suggestedYcbcrRange; 2827ec681f3Smrg format_prop->suggestedXChromaOffset = format_prop2.suggestedXChromaOffset; 2837ec681f3Smrg format_prop->suggestedYChromaOffset = format_prop2.suggestedYChromaOffset; 2847ec681f3Smrg } 2857ec681f3Smrg 2867ec681f3Smrg VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 = 2877ec681f3Smrg vk_find_struct(pProperties->pNext, 2887ec681f3Smrg ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID); 2897ec681f3Smrg if (format_prop2) 2907ec681f3Smrg get_ahw_buffer_format_properties2(device_h, buffer, format_prop2); 2919f464c52Smaya 2929f464c52Smaya /* NOTE - We support buffers with only one handle but do not error on 2939f464c52Smaya * multiple handle case. Reason is that we want to support YUV formats 2949f464c52Smaya * where we have many logical planes but they all point to the same 2959f464c52Smaya * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM. 2969f464c52Smaya */ 2979f464c52Smaya const native_handle_t *handle = 2989f464c52Smaya AHardwareBuffer_getNativeHandle(buffer); 2999f464c52Smaya int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1; 3009f464c52Smaya if (dma_buf < 0) 3019f464c52Smaya return VK_ERROR_INVALID_EXTERNAL_HANDLE; 3029f464c52Smaya 3039f464c52Smaya /* All memory types. */ 3047ec681f3Smrg uint32_t memory_types = (1ull << dev->physical->memory.type_count) - 1; 3059f464c52Smaya 3069f464c52Smaya pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END); 3079f464c52Smaya pProperties->memoryTypeBits = memory_types; 3089f464c52Smaya 3099f464c52Smaya return VK_SUCCESS; 3109f464c52Smaya} 3119f464c52Smaya 3129f464c52SmayaVkResult 3139f464c52Smayaanv_GetMemoryAndroidHardwareBufferANDROID( 3149f464c52Smaya VkDevice device_h, 3159f464c52Smaya const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo, 3169f464c52Smaya struct AHardwareBuffer **pBuffer) 3179f464c52Smaya{ 3189f464c52Smaya ANV_FROM_HANDLE(anv_device_memory, mem, pInfo->memory); 3199f464c52Smaya 3209f464c52Smaya /* Some quotes from Vulkan spec: 3219f464c52Smaya * 3229f464c52Smaya * "If the device memory was created by importing an Android hardware 3239f464c52Smaya * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same 3249f464c52Smaya * Android hardware buffer object." 3259f464c52Smaya * 3269f464c52Smaya * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must 3279f464c52Smaya * have been included in VkExportMemoryAllocateInfo::handleTypes when 3289f464c52Smaya * memory was created." 3299f464c52Smaya */ 3309f464c52Smaya if (mem->ahw) { 3319f464c52Smaya *pBuffer = mem->ahw; 3329f464c52Smaya /* Increase refcount. */ 3339f464c52Smaya AHardwareBuffer_acquire(mem->ahw); 3349f464c52Smaya return VK_SUCCESS; 3359f464c52Smaya } 3369f464c52Smaya 3379f464c52Smaya return VK_ERROR_OUT_OF_HOST_MEMORY; 3389f464c52Smaya} 3399f464c52Smaya 3409f464c52Smaya#endif 3419f464c52Smaya 3429f464c52Smaya/* Construct ahw usage mask from image usage bits, see 3439f464c52Smaya * 'AHardwareBuffer Usage Equivalence' in Vulkan spec. 3449f464c52Smaya */ 3459f464c52Smayauint64_t 3469f464c52Smayaanv_ahw_usage_from_vk_usage(const VkImageCreateFlags vk_create, 3479f464c52Smaya const VkImageUsageFlags vk_usage) 3489f464c52Smaya{ 3499f464c52Smaya uint64_t ahw_usage = 0; 3509f464c52Smaya#if ANDROID_API_LEVEL >= 26 3519f464c52Smaya if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) 3529f464c52Smaya ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 3539f464c52Smaya 3549f464c52Smaya if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) 3559f464c52Smaya ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 3569f464c52Smaya 3579f464c52Smaya if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 3589f464c52Smaya ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT; 3599f464c52Smaya 3609f464c52Smaya if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 3619f464c52Smaya ahw_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP; 3629f464c52Smaya 3639f464c52Smaya if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT) 3649f464c52Smaya ahw_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT; 3659f464c52Smaya 3669f464c52Smaya /* No usage bits set - set at least one GPU usage. */ 3679f464c52Smaya if (ahw_usage == 0) 3689f464c52Smaya ahw_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 3699f464c52Smaya#endif 3709f464c52Smaya return ahw_usage; 3719f464c52Smaya} 3729f464c52Smaya 3739f464c52Smaya/* 3749f464c52Smaya * Called from anv_AllocateMemory when import AHardwareBuffer. 3759f464c52Smaya */ 3769f464c52SmayaVkResult 3779f464c52Smayaanv_import_ahw_memory(VkDevice device_h, 3789f464c52Smaya struct anv_device_memory *mem, 3799f464c52Smaya const VkImportAndroidHardwareBufferInfoANDROID *info) 3809f464c52Smaya{ 3819f464c52Smaya#if ANDROID_API_LEVEL >= 26 3829f464c52Smaya ANV_FROM_HANDLE(anv_device, device, device_h); 3839f464c52Smaya 3849f464c52Smaya /* Import from AHardwareBuffer to anv_device_memory. */ 3859f464c52Smaya const native_handle_t *handle = 3869f464c52Smaya AHardwareBuffer_getNativeHandle(info->buffer); 3879f464c52Smaya 3889f464c52Smaya /* NOTE - We support buffers with only one handle but do not error on 3899f464c52Smaya * multiple handle case. Reason is that we want to support YUV formats 3909f464c52Smaya * where we have many logical planes but they all point to the same 3919f464c52Smaya * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM. 3929f464c52Smaya */ 3939f464c52Smaya int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1; 3949f464c52Smaya if (dma_buf < 0) 3959f464c52Smaya return VK_ERROR_INVALID_EXTERNAL_HANDLE; 3969f464c52Smaya 3977ec681f3Smrg VkResult result = anv_device_import_bo(device, dma_buf, 0, 3987ec681f3Smrg 0 /* client_address */, 3997ec681f3Smrg &mem->bo); 4007ec681f3Smrg assert(result == VK_SUCCESS); 4019f464c52Smaya 4029f464c52Smaya /* "If the vkAllocateMemory command succeeds, the implementation must 4039f464c52Smaya * acquire a reference to the imported hardware buffer, which it must 4049f464c52Smaya * release when the device memory object is freed. If the command fails, 4059f464c52Smaya * the implementation must not retain a reference." 4069f464c52Smaya */ 4079f464c52Smaya AHardwareBuffer_acquire(info->buffer); 4089f464c52Smaya mem->ahw = info->buffer; 4099f464c52Smaya 4109f464c52Smaya return VK_SUCCESS; 4119f464c52Smaya#else 4129f464c52Smaya return VK_ERROR_EXTENSION_NOT_PRESENT; 4139f464c52Smaya#endif 4149f464c52Smaya} 4159f464c52Smaya 4169f464c52SmayaVkResult 4179f464c52Smayaanv_create_ahw_memory(VkDevice device_h, 4189f464c52Smaya struct anv_device_memory *mem, 4199f464c52Smaya const VkMemoryAllocateInfo *pAllocateInfo) 4209f464c52Smaya{ 4219f464c52Smaya#if ANDROID_API_LEVEL >= 26 4229f464c52Smaya const VkMemoryDedicatedAllocateInfo *dedicated_info = 4239f464c52Smaya vk_find_struct_const(pAllocateInfo->pNext, 4249f464c52Smaya MEMORY_DEDICATED_ALLOCATE_INFO); 4259f464c52Smaya 4269f464c52Smaya uint32_t w = 0; 4279f464c52Smaya uint32_t h = 1; 4289f464c52Smaya uint32_t layers = 1; 4299f464c52Smaya uint32_t format = 0; 4309f464c52Smaya uint64_t usage = 0; 4319f464c52Smaya 4329f464c52Smaya /* If caller passed dedicated information. */ 4339f464c52Smaya if (dedicated_info && dedicated_info->image) { 4349f464c52Smaya ANV_FROM_HANDLE(anv_image, image, dedicated_info->image); 4357ec681f3Smrg w = image->vk.extent.width; 4367ec681f3Smrg h = image->vk.extent.height; 4377ec681f3Smrg layers = image->vk.array_layers; 4387ec681f3Smrg format = android_format_from_vk(image->vk.format); 4397ec681f3Smrg usage = anv_ahw_usage_from_vk_usage(image->vk.create_flags, image->vk.usage); 4409f464c52Smaya } else if (dedicated_info && dedicated_info->buffer) { 4419f464c52Smaya ANV_FROM_HANDLE(anv_buffer, buffer, dedicated_info->buffer); 4429f464c52Smaya w = buffer->size; 4439f464c52Smaya format = AHARDWAREBUFFER_FORMAT_BLOB; 4449f464c52Smaya usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | 4459f464c52Smaya AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; 4469f464c52Smaya } else { 4479f464c52Smaya w = pAllocateInfo->allocationSize; 4489f464c52Smaya format = AHARDWAREBUFFER_FORMAT_BLOB; 4499f464c52Smaya usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | 4509f464c52Smaya AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; 4519f464c52Smaya } 4529f464c52Smaya 4539f464c52Smaya struct AHardwareBuffer *ahw = NULL; 4549f464c52Smaya struct AHardwareBuffer_Desc desc = { 4559f464c52Smaya .width = w, 4569f464c52Smaya .height = h, 4579f464c52Smaya .layers = layers, 4589f464c52Smaya .format = format, 4599f464c52Smaya .usage = usage, 4609f464c52Smaya }; 4619f464c52Smaya 4629f464c52Smaya if (AHardwareBuffer_allocate(&desc, &ahw) != 0) 4639f464c52Smaya return VK_ERROR_OUT_OF_HOST_MEMORY; 4649f464c52Smaya 4657ec681f3Smrg const VkImportAndroidHardwareBufferInfoANDROID import_info = { 4667ec681f3Smrg .buffer = ahw, 4679f464c52Smaya }; 4687ec681f3Smrg VkResult result = anv_import_ahw_memory(device_h, mem, &import_info); 4699f464c52Smaya 4707ec681f3Smrg /* Release a reference to avoid leak for AHB allocation. */ 4717ec681f3Smrg AHardwareBuffer_release(ahw); 4729f464c52Smaya 4737ec681f3Smrg return result; 4749f464c52Smaya#else 4759f464c52Smaya return VK_ERROR_EXTENSION_NOT_PRESENT; 4769f464c52Smaya#endif 4779f464c52Smaya 4787ec681f3Smrg} 4799f464c52Smaya 48001e04c3fSmrgVkResult 4817ec681f3Smrganv_image_init_from_gralloc(struct anv_device *device, 4827ec681f3Smrg struct anv_image *image, 4837ec681f3Smrg const VkImageCreateInfo *base_info, 4847ec681f3Smrg const VkNativeBufferANDROID *gralloc_info) 48501e04c3fSmrg{ 48601e04c3fSmrg struct anv_bo *bo = NULL; 48701e04c3fSmrg VkResult result; 48801e04c3fSmrg 48901e04c3fSmrg struct anv_image_create_info anv_info = { 49001e04c3fSmrg .vk_info = base_info, 49101e04c3fSmrg .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, 49201e04c3fSmrg }; 49301e04c3fSmrg 49401e04c3fSmrg if (gralloc_info->handle->numFds != 1) { 4957ec681f3Smrg return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 49601e04c3fSmrg "VkNativeBufferANDROID::handle::numFds is %d, " 49701e04c3fSmrg "expected 1", gralloc_info->handle->numFds); 49801e04c3fSmrg } 49901e04c3fSmrg 50001e04c3fSmrg /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf 50101e04c3fSmrg * must exceed that of the gralloc handle, and we do not own the gralloc 50201e04c3fSmrg * handle. 50301e04c3fSmrg */ 50401e04c3fSmrg int dma_buf = gralloc_info->handle->data[0]; 50501e04c3fSmrg 5067ec681f3Smrg /* We need to set the WRITE flag on window system buffers so that GEM will 5077ec681f3Smrg * know we're writing to them and synchronize uses on other rings (for 5087ec681f3Smrg * example, if the display server uses the blitter ring). 5097ec681f3Smrg * 5107ec681f3Smrg * If this function fails and if the imported bo was resident in the cache, 5117ec681f3Smrg * we should avoid updating the bo's flags. Therefore, we defer updating 5127ec681f3Smrg * the flags until success is certain. 5137ec681f3Smrg * 5147ec681f3Smrg */ 5157ec681f3Smrg result = anv_device_import_bo(device, dma_buf, 5167ec681f3Smrg ANV_BO_ALLOC_IMPLICIT_SYNC | 5177ec681f3Smrg ANV_BO_ALLOC_IMPLICIT_WRITE, 5187ec681f3Smrg 0 /* client_address */, 5197ec681f3Smrg &bo); 52001e04c3fSmrg if (result != VK_SUCCESS) { 5217ec681f3Smrg return vk_errorf(device, result, 52201e04c3fSmrg "failed to import dma-buf from VkNativeBufferANDROID"); 52301e04c3fSmrg } 52401e04c3fSmrg 52501e04c3fSmrg int i915_tiling = anv_gem_get_tiling(device, bo->gem_handle); 52601e04c3fSmrg switch (i915_tiling) { 52701e04c3fSmrg case I915_TILING_NONE: 52801e04c3fSmrg anv_info.isl_tiling_flags = ISL_TILING_LINEAR_BIT; 52901e04c3fSmrg break; 53001e04c3fSmrg case I915_TILING_X: 53101e04c3fSmrg anv_info.isl_tiling_flags = ISL_TILING_X_BIT; 53201e04c3fSmrg break; 53301e04c3fSmrg case I915_TILING_Y: 53401e04c3fSmrg anv_info.isl_tiling_flags = ISL_TILING_Y0_BIT; 53501e04c3fSmrg break; 53601e04c3fSmrg case -1: 5377ec681f3Smrg result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 53801e04c3fSmrg "DRM_IOCTL_I915_GEM_GET_TILING failed for " 53901e04c3fSmrg "VkNativeBufferANDROID"); 54001e04c3fSmrg goto fail_tiling; 54101e04c3fSmrg default: 5427ec681f3Smrg result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 54301e04c3fSmrg "DRM_IOCTL_I915_GEM_GET_TILING returned unknown " 54401e04c3fSmrg "tiling %d for VkNativeBufferANDROID", i915_tiling); 54501e04c3fSmrg goto fail_tiling; 54601e04c3fSmrg } 54701e04c3fSmrg 54801e04c3fSmrg enum isl_format format = anv_get_isl_format(&device->info, 54901e04c3fSmrg base_info->format, 55001e04c3fSmrg VK_IMAGE_ASPECT_COLOR_BIT, 55101e04c3fSmrg base_info->tiling); 55201e04c3fSmrg assert(format != ISL_FORMAT_UNSUPPORTED); 55301e04c3fSmrg 5547ec681f3Smrg result = anv_image_init(device, image, &anv_info); 55501e04c3fSmrg if (result != VK_SUCCESS) 5567ec681f3Smrg goto fail_init; 55701e04c3fSmrg 5587ec681f3Smrg VkMemoryRequirements2 mem_reqs = { 5597ec681f3Smrg .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, 5607ec681f3Smrg }; 5617ec681f3Smrg 5627ec681f3Smrg anv_image_get_memory_requirements(device, image, image->vk.aspects, 5637ec681f3Smrg &mem_reqs); 5647ec681f3Smrg 5657ec681f3Smrg VkDeviceSize aligned_image_size = 5667ec681f3Smrg align_u64(mem_reqs.memoryRequirements.size, 5677ec681f3Smrg mem_reqs.memoryRequirements.alignment); 5687ec681f3Smrg 5697ec681f3Smrg if (bo->size < aligned_image_size) { 5707ec681f3Smrg result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 57101e04c3fSmrg "dma-buf from VkNativeBufferANDROID is too small for " 57201e04c3fSmrg "VkImage: %"PRIu64"B < %"PRIu64"B", 5737ec681f3Smrg bo->size, aligned_image_size); 57401e04c3fSmrg goto fail_size; 57501e04c3fSmrg } 57601e04c3fSmrg 5777ec681f3Smrg assert(!image->disjoint); 57801e04c3fSmrg assert(image->n_planes == 1); 5797ec681f3Smrg assert(image->planes[0].primary_surface.memory_range.binding == 5807ec681f3Smrg ANV_IMAGE_MEMORY_BINDING_MAIN); 5817ec681f3Smrg assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo == NULL); 5827ec681f3Smrg assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.offset == 0); 5837ec681f3Smrg image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo = bo; 5847ec681f3Smrg image->from_gralloc = true; 58501e04c3fSmrg 5867ec681f3Smrg return VK_SUCCESS; 5877ec681f3Smrg 5887ec681f3Smrg fail_size: 5897ec681f3Smrg anv_image_finish(image); 5907ec681f3Smrg fail_init: 5917ec681f3Smrg fail_tiling: 5927ec681f3Smrg anv_device_release_bo(device, bo); 5937ec681f3Smrg 5947ec681f3Smrg return result; 5957ec681f3Smrg} 5967ec681f3Smrg 5977ec681f3SmrgVkResult 5987ec681f3Smrganv_image_bind_from_gralloc(struct anv_device *device, 5997ec681f3Smrg struct anv_image *image, 6007ec681f3Smrg const VkNativeBufferANDROID *gralloc_info) 6017ec681f3Smrg{ 6027ec681f3Smrg /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf 6037ec681f3Smrg * must exceed that of the gralloc handle, and we do not own the gralloc 6047ec681f3Smrg * handle. 6057ec681f3Smrg */ 6067ec681f3Smrg int dma_buf = gralloc_info->handle->data[0]; 60701e04c3fSmrg 60801e04c3fSmrg /* We need to set the WRITE flag on window system buffers so that GEM will 60901e04c3fSmrg * know we're writing to them and synchronize uses on other rings (for 61001e04c3fSmrg * example, if the display server uses the blitter ring). 61101e04c3fSmrg * 61201e04c3fSmrg * If this function fails and if the imported bo was resident in the cache, 61301e04c3fSmrg * we should avoid updating the bo's flags. Therefore, we defer updating 61401e04c3fSmrg * the flags until success is certain. 61501e04c3fSmrg * 61601e04c3fSmrg */ 6177ec681f3Smrg struct anv_bo *bo = NULL; 6187ec681f3Smrg VkResult result = anv_device_import_bo(device, dma_buf, 6197ec681f3Smrg ANV_BO_ALLOC_IMPLICIT_SYNC | 6207ec681f3Smrg ANV_BO_ALLOC_IMPLICIT_WRITE, 6217ec681f3Smrg 0 /* client_address */, 6227ec681f3Smrg &bo); 6237ec681f3Smrg if (result != VK_SUCCESS) { 6247ec681f3Smrg return vk_errorf(device, result, 6257ec681f3Smrg "failed to import dma-buf from VkNativeBufferANDROID"); 6267ec681f3Smrg } 62701e04c3fSmrg 6287ec681f3Smrg uint64_t img_size = image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].memory_range.size; 6297ec681f3Smrg if (img_size < bo->size) { 6307ec681f3Smrg result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE, 6317ec681f3Smrg "dma-buf from VkNativeBufferANDROID is too small for " 6327ec681f3Smrg "VkImage: %"PRIu64"B < %"PRIu64"B", 6337ec681f3Smrg bo->size, img_size); 6347ec681f3Smrg anv_device_release_bo(device, bo); 6357ec681f3Smrg return result; 6367ec681f3Smrg } 63701e04c3fSmrg 6387ec681f3Smrg assert(!image->disjoint); 6397ec681f3Smrg assert(image->n_planes == 1); 6407ec681f3Smrg assert(image->planes[0].primary_surface.memory_range.binding == 6417ec681f3Smrg ANV_IMAGE_MEMORY_BINDING_MAIN); 6427ec681f3Smrg assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo == NULL); 6437ec681f3Smrg assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.offset == 0); 6447ec681f3Smrg image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo = bo; 6457ec681f3Smrg image->from_gralloc = true; 64601e04c3fSmrg 6477ec681f3Smrg return VK_SUCCESS; 64801e04c3fSmrg} 64901e04c3fSmrg 6507ec681f3Smrgstatic VkResult 6517ec681f3Smrgformat_supported_with_usage(VkDevice device_h, VkFormat format, 6527ec681f3Smrg VkImageUsageFlags imageUsage) 65301e04c3fSmrg{ 65401e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, device_h); 6557ec681f3Smrg VkPhysicalDevice phys_dev_h = anv_physical_device_to_handle(device->physical); 65601e04c3fSmrg VkResult result; 65701e04c3fSmrg 6589f464c52Smaya const VkPhysicalDeviceImageFormatInfo2 image_format_info = { 6599f464c52Smaya .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 66001e04c3fSmrg .format = format, 66101e04c3fSmrg .type = VK_IMAGE_TYPE_2D, 66201e04c3fSmrg .tiling = VK_IMAGE_TILING_OPTIMAL, 66301e04c3fSmrg .usage = imageUsage, 66401e04c3fSmrg }; 66501e04c3fSmrg 6669f464c52Smaya VkImageFormatProperties2 image_format_props = { 6679f464c52Smaya .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, 66801e04c3fSmrg }; 66901e04c3fSmrg 67001e04c3fSmrg /* Check that requested format and usage are supported. */ 67101e04c3fSmrg result = anv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, 67201e04c3fSmrg &image_format_info, &image_format_props); 67301e04c3fSmrg if (result != VK_SUCCESS) { 6747ec681f3Smrg return vk_errorf(device, result, 67501e04c3fSmrg "anv_GetPhysicalDeviceImageFormatProperties2 failed " 67601e04c3fSmrg "inside %s", __func__); 67701e04c3fSmrg } 6787ec681f3Smrg return VK_SUCCESS; 6797ec681f3Smrg} 6807ec681f3Smrg 6817ec681f3Smrg 6827ec681f3Smrgstatic VkResult 6837ec681f3Smrgsetup_gralloc0_usage(struct anv_device *device, VkFormat format, 6847ec681f3Smrg VkImageUsageFlags imageUsage, int *grallocUsage) 6857ec681f3Smrg{ 6867ec681f3Smrg /* WARNING: Android's libvulkan.so hardcodes the VkImageUsageFlags 6877ec681f3Smrg * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags. 6887ec681f3Smrg * The relevant code in libvulkan/swapchain.cpp contains this fun comment: 6897ec681f3Smrg * 6907ec681f3Smrg * TODO(jessehall): I think these are right, but haven't thought hard 6917ec681f3Smrg * about it. Do we need to query the driver for support of any of 6927ec681f3Smrg * these? 6937ec681f3Smrg * 6947ec681f3Smrg * Any disagreement between this function and the hardcoded 6957ec681f3Smrg * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests 6967ec681f3Smrg * dEQP-VK.wsi.android.swapchain.*.image_usage to fail. 6977ec681f3Smrg */ 69801e04c3fSmrg 69901e04c3fSmrg if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | 70001e04c3fSmrg VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) 70101e04c3fSmrg *grallocUsage |= GRALLOC_USAGE_HW_RENDER; 70201e04c3fSmrg 70301e04c3fSmrg if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 70401e04c3fSmrg VK_IMAGE_USAGE_SAMPLED_BIT | 70501e04c3fSmrg VK_IMAGE_USAGE_STORAGE_BIT | 70601e04c3fSmrg VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) 70701e04c3fSmrg *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE; 70801e04c3fSmrg 70901e04c3fSmrg /* All VkImageUsageFlags not explicitly checked here are unsupported for 71001e04c3fSmrg * gralloc swapchains. 71101e04c3fSmrg */ 71201e04c3fSmrg if (imageUsage != 0) { 7137ec681f3Smrg return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED, 71401e04c3fSmrg "unsupported VkImageUsageFlags(0x%x) for gralloc " 71501e04c3fSmrg "swapchain", imageUsage); 71601e04c3fSmrg } 71701e04c3fSmrg 71801e04c3fSmrg /* The below formats support GRALLOC_USAGE_HW_FB (that is, display 71901e04c3fSmrg * scanout). This short list of formats is univserally supported on Intel 72001e04c3fSmrg * but is incomplete. The full set of supported formats is dependent on 72101e04c3fSmrg * kernel and hardware. 72201e04c3fSmrg * 72301e04c3fSmrg * FINISHME: Advertise all display-supported formats. 72401e04c3fSmrg */ 72501e04c3fSmrg switch (format) { 72601e04c3fSmrg case VK_FORMAT_B8G8R8A8_UNORM: 7277ec681f3Smrg case VK_FORMAT_R5G6B5_UNORM_PACK16: 72801e04c3fSmrg case VK_FORMAT_R8G8B8A8_UNORM: 72901e04c3fSmrg case VK_FORMAT_R8G8B8A8_SRGB: 73001e04c3fSmrg *grallocUsage |= GRALLOC_USAGE_HW_FB | 73101e04c3fSmrg GRALLOC_USAGE_HW_COMPOSER | 73201e04c3fSmrg GRALLOC_USAGE_EXTERNAL_DISP; 73301e04c3fSmrg break; 73401e04c3fSmrg default: 7357ec681f3Smrg mesa_logw("%s: unsupported format=%d", __func__, format); 73601e04c3fSmrg } 73701e04c3fSmrg 73801e04c3fSmrg if (*grallocUsage == 0) 73901e04c3fSmrg return VK_ERROR_FORMAT_NOT_SUPPORTED; 74001e04c3fSmrg 74101e04c3fSmrg return VK_SUCCESS; 74201e04c3fSmrg} 74301e04c3fSmrg 7447ec681f3Smrg#if ANDROID_API_LEVEL >= 26 7457ec681f3SmrgVkResult anv_GetSwapchainGrallocUsage2ANDROID( 7467ec681f3Smrg VkDevice device_h, 7477ec681f3Smrg VkFormat format, 7487ec681f3Smrg VkImageUsageFlags imageUsage, 7497ec681f3Smrg VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, 7507ec681f3Smrg uint64_t* grallocConsumerUsage, 7517ec681f3Smrg uint64_t* grallocProducerUsage) 7527ec681f3Smrg{ 7537ec681f3Smrg ANV_FROM_HANDLE(anv_device, device, device_h); 7547ec681f3Smrg VkResult result; 7557ec681f3Smrg 7567ec681f3Smrg *grallocConsumerUsage = 0; 7577ec681f3Smrg *grallocProducerUsage = 0; 7587ec681f3Smrg mesa_logd("%s: format=%d, usage=0x%x", __func__, format, imageUsage); 7597ec681f3Smrg 7607ec681f3Smrg result = format_supported_with_usage(device_h, format, imageUsage); 7617ec681f3Smrg if (result != VK_SUCCESS) 7627ec681f3Smrg return result; 7637ec681f3Smrg 7647ec681f3Smrg int32_t grallocUsage = 0; 7657ec681f3Smrg result = setup_gralloc0_usage(device, format, imageUsage, &grallocUsage); 7667ec681f3Smrg if (result != VK_SUCCESS) 7677ec681f3Smrg return result; 7687ec681f3Smrg 7697ec681f3Smrg /* Setup gralloc1 usage flags from gralloc0 flags. */ 7707ec681f3Smrg 7717ec681f3Smrg if (grallocUsage & GRALLOC_USAGE_HW_RENDER) { 7727ec681f3Smrg *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET; 7737ec681f3Smrg *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET; 7747ec681f3Smrg } 7757ec681f3Smrg 7767ec681f3Smrg if (grallocUsage & GRALLOC_USAGE_HW_TEXTURE) { 7777ec681f3Smrg *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE; 7787ec681f3Smrg } 7797ec681f3Smrg 7807ec681f3Smrg if (grallocUsage & (GRALLOC_USAGE_HW_FB | 7817ec681f3Smrg GRALLOC_USAGE_HW_COMPOSER | 7827ec681f3Smrg GRALLOC_USAGE_EXTERNAL_DISP)) { 7837ec681f3Smrg *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET; 7847ec681f3Smrg *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER; 7857ec681f3Smrg } 7867ec681f3Smrg 7877ec681f3Smrg return VK_SUCCESS; 7887ec681f3Smrg} 7897ec681f3Smrg#endif 7907ec681f3Smrg 7917ec681f3SmrgVkResult anv_GetSwapchainGrallocUsageANDROID( 7927ec681f3Smrg VkDevice device_h, 7937ec681f3Smrg VkFormat format, 7947ec681f3Smrg VkImageUsageFlags imageUsage, 7957ec681f3Smrg int* grallocUsage) 7967ec681f3Smrg{ 7977ec681f3Smrg ANV_FROM_HANDLE(anv_device, device, device_h); 7987ec681f3Smrg VkResult result; 7997ec681f3Smrg 8007ec681f3Smrg *grallocUsage = 0; 8017ec681f3Smrg mesa_logd("%s: format=%d, usage=0x%x", __func__, format, imageUsage); 8027ec681f3Smrg 8037ec681f3Smrg result = format_supported_with_usage(device_h, format, imageUsage); 8047ec681f3Smrg if (result != VK_SUCCESS) 8057ec681f3Smrg return result; 8067ec681f3Smrg 8077ec681f3Smrg return setup_gralloc0_usage(device, format, imageUsage, grallocUsage); 8087ec681f3Smrg} 8097ec681f3Smrg 81001e04c3fSmrgVkResult 81101e04c3fSmrganv_AcquireImageANDROID( 81201e04c3fSmrg VkDevice device_h, 81301e04c3fSmrg VkImage image_h, 81401e04c3fSmrg int nativeFenceFd, 81501e04c3fSmrg VkSemaphore semaphore_h, 81601e04c3fSmrg VkFence fence_h) 81701e04c3fSmrg{ 81801e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, device_h); 81901e04c3fSmrg VkResult result = VK_SUCCESS; 82001e04c3fSmrg 8217ec681f3Smrg /* From https://source.android.com/devices/graphics/implement-vulkan : 8227ec681f3Smrg * 8237ec681f3Smrg * "The driver takes ownership of the fence file descriptor and closes 8247ec681f3Smrg * the fence file descriptor when no longer needed. The driver must do 8257ec681f3Smrg * so even if neither a semaphore or fence object is provided, or even 8267ec681f3Smrg * if vkAcquireImageANDROID fails and returns an error." 8277ec681f3Smrg * 8287ec681f3Smrg * The Vulkan spec for VkImportFence/SemaphoreFdKHR(), however, requires 8297ec681f3Smrg * the file descriptor to be left alone on failure. 8307ec681f3Smrg */ 8317ec681f3Smrg int semaphore_fd = -1, fence_fd = -1; 8327ec681f3Smrg if (nativeFenceFd >= 0) { 8337ec681f3Smrg if (semaphore_h != VK_NULL_HANDLE && fence_h != VK_NULL_HANDLE) { 8347ec681f3Smrg /* We have both so we have to import the sync file twice. One of 8357ec681f3Smrg * them needs to be a dup. 8367ec681f3Smrg */ 8377ec681f3Smrg semaphore_fd = nativeFenceFd; 8387ec681f3Smrg fence_fd = dup(nativeFenceFd); 8397ec681f3Smrg if (fence_fd < 0) { 8407ec681f3Smrg VkResult err = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS : 8417ec681f3Smrg VK_ERROR_OUT_OF_HOST_MEMORY; 8427ec681f3Smrg close(nativeFenceFd); 8437ec681f3Smrg return vk_error(device, err); 8447ec681f3Smrg } 8457ec681f3Smrg } else if (semaphore_h != VK_NULL_HANDLE) { 8467ec681f3Smrg semaphore_fd = nativeFenceFd; 8477ec681f3Smrg } else if (fence_h != VK_NULL_HANDLE) { 8487ec681f3Smrg fence_fd = nativeFenceFd; 8497ec681f3Smrg } else { 8507ec681f3Smrg /* Nothing to import into so we have to close the file */ 8517ec681f3Smrg close(nativeFenceFd); 85201e04c3fSmrg } 85301e04c3fSmrg } 85401e04c3fSmrg 8557ec681f3Smrg if (semaphore_h != VK_NULL_HANDLE) { 8567ec681f3Smrg const VkImportSemaphoreFdInfoKHR info = { 8577ec681f3Smrg .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, 8587ec681f3Smrg .semaphore = semaphore_h, 8597ec681f3Smrg .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, 8607ec681f3Smrg .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, 8617ec681f3Smrg .fd = semaphore_fd, 86201e04c3fSmrg }; 8637ec681f3Smrg result = anv_ImportSemaphoreFdKHR(device_h, &info); 8647ec681f3Smrg if (result == VK_SUCCESS) 8657ec681f3Smrg semaphore_fd = -1; /* ANV took ownership */ 8667ec681f3Smrg } 86701e04c3fSmrg 8687ec681f3Smrg if (result == VK_SUCCESS && fence_h != VK_NULL_HANDLE) { 8697ec681f3Smrg const VkImportFenceFdInfoKHR info = { 8707ec681f3Smrg .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, 8717ec681f3Smrg .fence = fence_h, 8727ec681f3Smrg .flags = VK_FENCE_IMPORT_TEMPORARY_BIT, 8737ec681f3Smrg .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, 8747ec681f3Smrg .fd = fence_fd, 8757ec681f3Smrg }; 8767ec681f3Smrg result = anv_ImportFenceFdKHR(device_h, &info); 8777ec681f3Smrg if (result == VK_SUCCESS) 8787ec681f3Smrg fence_fd = -1; /* ANV took ownership */ 87901e04c3fSmrg } 88001e04c3fSmrg 8817ec681f3Smrg if (semaphore_fd >= 0) 8827ec681f3Smrg close(semaphore_fd); 8837ec681f3Smrg if (fence_fd >= 0) 8847ec681f3Smrg close(fence_fd); 8857ec681f3Smrg 8867ec681f3Smrg return result; 88701e04c3fSmrg} 88801e04c3fSmrg 88901e04c3fSmrgVkResult 89001e04c3fSmrganv_QueueSignalReleaseImageANDROID( 89101e04c3fSmrg VkQueue queue, 89201e04c3fSmrg uint32_t waitSemaphoreCount, 89301e04c3fSmrg const VkSemaphore* pWaitSemaphores, 89401e04c3fSmrg VkImage image, 89501e04c3fSmrg int* pNativeFenceFd) 89601e04c3fSmrg{ 89701e04c3fSmrg VkResult result; 89801e04c3fSmrg 89901e04c3fSmrg if (waitSemaphoreCount == 0) 90001e04c3fSmrg goto done; 90101e04c3fSmrg 9027ec681f3Smrg result = vk_common_QueueSubmit(queue, 1, 90301e04c3fSmrg &(VkSubmitInfo) { 90401e04c3fSmrg .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 90501e04c3fSmrg .waitSemaphoreCount = 1, 90601e04c3fSmrg .pWaitSemaphores = pWaitSemaphores, 9077ec681f3Smrg .pWaitDstStageMask = &(VkPipelineStageFlags) { 9087ec681f3Smrg VK_PIPELINE_STAGE_ALL_COMMANDS_BIT 9097ec681f3Smrg }, 91001e04c3fSmrg }, 91101e04c3fSmrg (VkFence) VK_NULL_HANDLE); 91201e04c3fSmrg if (result != VK_SUCCESS) 91301e04c3fSmrg return result; 91401e04c3fSmrg 91501e04c3fSmrg done: 91601e04c3fSmrg if (pNativeFenceFd) { 91701e04c3fSmrg /* We can rely implicit on sync because above we submitted all 91801e04c3fSmrg * semaphores to the queue. 91901e04c3fSmrg */ 92001e04c3fSmrg *pNativeFenceFd = -1; 92101e04c3fSmrg } 92201e04c3fSmrg 92301e04c3fSmrg return VK_SUCCESS; 92401e04c3fSmrg} 925