1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2021 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv and radv which are: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * Copyright © 2016 Red Hat 8bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vn_android.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include <dlfcn.h> 14bf215546Sopenharmony_ci#include <hardware/gralloc.h> 15bf215546Sopenharmony_ci#include <hardware/hwvulkan.h> 16bf215546Sopenharmony_ci#include <vndk/hardware_buffer.h> 17bf215546Sopenharmony_ci#include <vulkan/vk_icd.h> 18bf215546Sopenharmony_ci 19bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 20bf215546Sopenharmony_ci#include "util/libsync.h" 21bf215546Sopenharmony_ci#include "util/os_file.h" 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci#include "vn_buffer.h" 24bf215546Sopenharmony_ci#include "vn_device.h" 25bf215546Sopenharmony_ci#include "vn_device_memory.h" 26bf215546Sopenharmony_ci#include "vn_image.h" 27bf215546Sopenharmony_ci#include "vn_instance.h" 28bf215546Sopenharmony_ci#include "vn_physical_device.h" 29bf215546Sopenharmony_ci#include "vn_queue.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci/* perform options supported by CrOS Gralloc */ 32bf215546Sopenharmony_ci#define CROS_GRALLOC_DRM_GET_BUFFER_INFO 4 33bf215546Sopenharmony_ci#define CROS_GRALLOC_DRM_GET_USAGE 5 34bf215546Sopenharmony_ci#define CROS_GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT 0x1 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistruct vn_android_gralloc { 37bf215546Sopenharmony_ci const gralloc_module_t *module; 38bf215546Sopenharmony_ci uint32_t front_rendering_usage; 39bf215546Sopenharmony_ci}; 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_cistatic struct vn_android_gralloc _vn_android_gralloc; 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cistatic int 44bf215546Sopenharmony_civn_android_gralloc_init() 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci static const char CROS_GRALLOC_MODULE_NAME[] = "CrOS Gralloc"; 47bf215546Sopenharmony_ci const gralloc_module_t *gralloc = NULL; 48bf215546Sopenharmony_ci uint32_t front_rendering_usage = 0; 49bf215546Sopenharmony_ci int ret; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci /* get gralloc module for gralloc buffer info query */ 52bf215546Sopenharmony_ci ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, 53bf215546Sopenharmony_ci (const hw_module_t **)&gralloc); 54bf215546Sopenharmony_ci if (ret) { 55bf215546Sopenharmony_ci vn_log(NULL, "failed to open gralloc module(ret=%d)", ret); 56bf215546Sopenharmony_ci return ret; 57bf215546Sopenharmony_ci } 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci if (strcmp(gralloc->common.name, CROS_GRALLOC_MODULE_NAME) != 0) { 60bf215546Sopenharmony_ci dlclose(gralloc->common.dso); 61bf215546Sopenharmony_ci vn_log(NULL, "unexpected gralloc (name: %s)", gralloc->common.name); 62bf215546Sopenharmony_ci return -1; 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci if (!gralloc->perform) { 66bf215546Sopenharmony_ci dlclose(gralloc->common.dso); 67bf215546Sopenharmony_ci vn_log(NULL, "missing required gralloc helper: perform"); 68bf215546Sopenharmony_ci return -1; 69bf215546Sopenharmony_ci } 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci if (gralloc->perform(gralloc, CROS_GRALLOC_DRM_GET_USAGE, 72bf215546Sopenharmony_ci CROS_GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT, 73bf215546Sopenharmony_ci &front_rendering_usage) == 0) { 74bf215546Sopenharmony_ci assert(front_rendering_usage); 75bf215546Sopenharmony_ci _vn_android_gralloc.front_rendering_usage = front_rendering_usage; 76bf215546Sopenharmony_ci } 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci _vn_android_gralloc.module = gralloc; 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci return 0; 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_cistatic inline void 84bf215546Sopenharmony_civn_android_gralloc_fini() 85bf215546Sopenharmony_ci{ 86bf215546Sopenharmony_ci dlclose(_vn_android_gralloc.module->common.dso); 87bf215546Sopenharmony_ci} 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ciuint32_t 90bf215546Sopenharmony_civn_android_gralloc_get_shared_present_usage() 91bf215546Sopenharmony_ci{ 92bf215546Sopenharmony_ci return _vn_android_gralloc.front_rendering_usage; 93bf215546Sopenharmony_ci} 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_cistruct cros_gralloc0_buffer_info { 96bf215546Sopenharmony_ci uint32_t drm_fourcc; 97bf215546Sopenharmony_ci int num_fds; /* ignored */ 98bf215546Sopenharmony_ci int fds[4]; /* ignored */ 99bf215546Sopenharmony_ci uint64_t modifier; 100bf215546Sopenharmony_ci uint32_t offset[4]; 101bf215546Sopenharmony_ci uint32_t stride[4]; 102bf215546Sopenharmony_ci}; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistruct vn_android_gralloc_buffer_properties { 105bf215546Sopenharmony_ci uint32_t drm_fourcc; 106bf215546Sopenharmony_ci uint64_t modifier; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci /* plane order matches VkImageDrmFormatModifierExplicitCreateInfoEXT */ 109bf215546Sopenharmony_ci uint32_t offset[4]; 110bf215546Sopenharmony_ci uint32_t stride[4]; 111bf215546Sopenharmony_ci}; 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_cistatic bool 114bf215546Sopenharmony_civn_android_gralloc_get_buffer_properties( 115bf215546Sopenharmony_ci buffer_handle_t handle, 116bf215546Sopenharmony_ci struct vn_android_gralloc_buffer_properties *out_props) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci const gralloc_module_t *gralloc = _vn_android_gralloc.module; 119bf215546Sopenharmony_ci struct cros_gralloc0_buffer_info info; 120bf215546Sopenharmony_ci if (gralloc->perform(gralloc, CROS_GRALLOC_DRM_GET_BUFFER_INFO, handle, 121bf215546Sopenharmony_ci &info) != 0) { 122bf215546Sopenharmony_ci vn_log(NULL, "CROS_GRALLOC_DRM_GET_BUFFER_INFO failed"); 123bf215546Sopenharmony_ci return false; 124bf215546Sopenharmony_ci } 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci if (info.modifier == DRM_FORMAT_MOD_INVALID) { 127bf215546Sopenharmony_ci vn_log(NULL, "Unexpected DRM_FORMAT_MOD_INVALID"); 128bf215546Sopenharmony_ci return false; 129bf215546Sopenharmony_ci } 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci out_props->drm_fourcc = info.drm_fourcc; 132bf215546Sopenharmony_ci for (uint32_t i = 0; i < 4; i++) { 133bf215546Sopenharmony_ci out_props->stride[i] = info.stride[i]; 134bf215546Sopenharmony_ci out_props->offset[i] = info.offset[i]; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci /* YVU420 has a chroma order of CrCb. So we must swap the planes for CrCb 138bf215546Sopenharmony_ci * to align with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM. This is to serve 139bf215546Sopenharmony_ci * VkImageDrmFormatModifierExplicitCreateInfoEXT explicit plane layouts. 140bf215546Sopenharmony_ci */ 141bf215546Sopenharmony_ci if (info.drm_fourcc == DRM_FORMAT_YVU420) { 142bf215546Sopenharmony_ci out_props->stride[1] = info.stride[2]; 143bf215546Sopenharmony_ci out_props->offset[1] = info.offset[2]; 144bf215546Sopenharmony_ci out_props->stride[2] = info.stride[1]; 145bf215546Sopenharmony_ci out_props->offset[2] = info.offset[1]; 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci out_props->modifier = info.modifier; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci return true; 151bf215546Sopenharmony_ci} 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_cistatic int 154bf215546Sopenharmony_civn_android_gralloc_get_dma_buf_fd(const native_handle_t *handle) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci /* There can be multiple fds wrapped inside a native_handle_t, but we 157bf215546Sopenharmony_ci * expect the 1st one pointing to the dma_buf. For multi-planar format, 158bf215546Sopenharmony_ci * there should only exist one undelying dma_buf. The other fd(s) could be 159bf215546Sopenharmony_ci * dups to the same dma_buf or point to the shared memory used to store 160bf215546Sopenharmony_ci * gralloc buffer metadata. 161bf215546Sopenharmony_ci */ 162bf215546Sopenharmony_ci assert(handle); 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci if (handle->numFds < 1) { 165bf215546Sopenharmony_ci vn_log(NULL, "handle->numFds is %d, expected >= 1", handle->numFds); 166bf215546Sopenharmony_ci return -1; 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci if (handle->data[0] < 0) { 170bf215546Sopenharmony_ci vn_log(NULL, "handle->data[0] < 0"); 171bf215546Sopenharmony_ci return -1; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci return handle->data[0]; 175bf215546Sopenharmony_ci} 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_cistatic int 178bf215546Sopenharmony_civn_hal_open(const struct hw_module_t *mod, 179bf215546Sopenharmony_ci const char *id, 180bf215546Sopenharmony_ci struct hw_device_t **dev); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_cistatic void UNUSED 183bf215546Sopenharmony_cistatic_asserts(void) 184bf215546Sopenharmony_ci{ 185bf215546Sopenharmony_ci STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC); 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ciPUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = { 189bf215546Sopenharmony_ci .common = { 190bf215546Sopenharmony_ci .tag = HARDWARE_MODULE_TAG, 191bf215546Sopenharmony_ci .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1, 192bf215546Sopenharmony_ci .hal_api_version = HARDWARE_HAL_API_VERSION, 193bf215546Sopenharmony_ci .id = HWVULKAN_HARDWARE_MODULE_ID, 194bf215546Sopenharmony_ci .name = "Venus Vulkan HAL", 195bf215546Sopenharmony_ci .author = "Google LLC", 196bf215546Sopenharmony_ci .methods = &(hw_module_methods_t) { 197bf215546Sopenharmony_ci .open = vn_hal_open, 198bf215546Sopenharmony_ci }, 199bf215546Sopenharmony_ci }, 200bf215546Sopenharmony_ci}; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_cistatic int 203bf215546Sopenharmony_civn_hal_close(UNUSED struct hw_device_t *dev) 204bf215546Sopenharmony_ci{ 205bf215546Sopenharmony_ci vn_android_gralloc_fini(); 206bf215546Sopenharmony_ci return 0; 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_cistatic hwvulkan_device_t vn_hal_dev = { 210bf215546Sopenharmony_ci .common = { 211bf215546Sopenharmony_ci .tag = HARDWARE_DEVICE_TAG, 212bf215546Sopenharmony_ci .version = HWVULKAN_DEVICE_API_VERSION_0_1, 213bf215546Sopenharmony_ci .module = &HAL_MODULE_INFO_SYM.common, 214bf215546Sopenharmony_ci .close = vn_hal_close, 215bf215546Sopenharmony_ci }, 216bf215546Sopenharmony_ci .EnumerateInstanceExtensionProperties = vn_EnumerateInstanceExtensionProperties, 217bf215546Sopenharmony_ci .CreateInstance = vn_CreateInstance, 218bf215546Sopenharmony_ci .GetInstanceProcAddr = vn_GetInstanceProcAddr, 219bf215546Sopenharmony_ci}; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_cistatic int 222bf215546Sopenharmony_civn_hal_open(const struct hw_module_t *mod, 223bf215546Sopenharmony_ci const char *id, 224bf215546Sopenharmony_ci struct hw_device_t **dev) 225bf215546Sopenharmony_ci{ 226bf215546Sopenharmony_ci int ret; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci assert(mod == &HAL_MODULE_INFO_SYM.common); 229bf215546Sopenharmony_ci assert(strcmp(id, HWVULKAN_DEVICE_0) == 0); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci ret = vn_android_gralloc_init(); 232bf215546Sopenharmony_ci if (ret) 233bf215546Sopenharmony_ci return ret; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci *dev = &vn_hal_dev.common; 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci return 0; 238bf215546Sopenharmony_ci} 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_cistatic uint32_t 241bf215546Sopenharmony_civn_android_ahb_format_from_vk_format(VkFormat format) 242bf215546Sopenharmony_ci{ 243bf215546Sopenharmony_ci /* Only non-external AHB compatible formats are expected at: 244bf215546Sopenharmony_ci * - image format query 245bf215546Sopenharmony_ci * - memory export allocation 246bf215546Sopenharmony_ci */ 247bf215546Sopenharmony_ci switch (format) { 248bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8A8_UNORM: 249bf215546Sopenharmony_ci return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; 250bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8_UNORM: 251bf215546Sopenharmony_ci return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM; 252bf215546Sopenharmony_ci case VK_FORMAT_R5G6B5_UNORM_PACK16: 253bf215546Sopenharmony_ci return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM; 254bf215546Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SFLOAT: 255bf215546Sopenharmony_ci return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT; 256bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_UNORM_PACK32: 257bf215546Sopenharmony_ci return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM; 258bf215546Sopenharmony_ci default: 259bf215546Sopenharmony_ci return 0; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ciconst VkFormat * 264bf215546Sopenharmony_civn_android_format_to_view_formats(VkFormat format, uint32_t *out_count) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci /* For AHB image prop query and creation, venus overrides the tiling to 267bf215546Sopenharmony_ci * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, which requires to chain 268bf215546Sopenharmony_ci * VkImageFormatListCreateInfo struct in the corresponding pNext when the 269bf215546Sopenharmony_ci * VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is set. Those AHB images are assumed 270bf215546Sopenharmony_ci * to be mutable no more than sRGB-ness, and the implementations can fail 271bf215546Sopenharmony_ci * whenever going beyond. 272bf215546Sopenharmony_ci * 273bf215546Sopenharmony_ci * This helper provides the view formats that have sRGB variants for the 274bf215546Sopenharmony_ci * image format that venus supports. 275bf215546Sopenharmony_ci */ 276bf215546Sopenharmony_ci static const VkFormat view_formats_r8g8b8a8[] = { 277bf215546Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB 278bf215546Sopenharmony_ci }; 279bf215546Sopenharmony_ci static const VkFormat view_formats_r8g8b8[] = { VK_FORMAT_R8G8B8_UNORM, 280bf215546Sopenharmony_ci VK_FORMAT_R8G8B8_SRGB }; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci switch (format) { 283bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8A8_UNORM: 284bf215546Sopenharmony_ci *out_count = ARRAY_SIZE(view_formats_r8g8b8a8); 285bf215546Sopenharmony_ci return view_formats_r8g8b8a8; 286bf215546Sopenharmony_ci break; 287bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8_UNORM: 288bf215546Sopenharmony_ci *out_count = ARRAY_SIZE(view_formats_r8g8b8); 289bf215546Sopenharmony_ci return view_formats_r8g8b8; 290bf215546Sopenharmony_ci break; 291bf215546Sopenharmony_ci default: 292bf215546Sopenharmony_ci /* let the caller handle the fallback case */ 293bf215546Sopenharmony_ci *out_count = 0; 294bf215546Sopenharmony_ci return NULL; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci} 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ciVkFormat 299bf215546Sopenharmony_civn_android_drm_format_to_vk_format(uint32_t format) 300bf215546Sopenharmony_ci{ 301bf215546Sopenharmony_ci switch (format) { 302bf215546Sopenharmony_ci case DRM_FORMAT_ABGR8888: 303bf215546Sopenharmony_ci case DRM_FORMAT_XBGR8888: 304bf215546Sopenharmony_ci return VK_FORMAT_R8G8B8A8_UNORM; 305bf215546Sopenharmony_ci case DRM_FORMAT_BGR888: 306bf215546Sopenharmony_ci return VK_FORMAT_R8G8B8_UNORM; 307bf215546Sopenharmony_ci case DRM_FORMAT_RGB565: 308bf215546Sopenharmony_ci return VK_FORMAT_R5G6B5_UNORM_PACK16; 309bf215546Sopenharmony_ci case DRM_FORMAT_ABGR16161616F: 310bf215546Sopenharmony_ci return VK_FORMAT_R16G16B16A16_SFLOAT; 311bf215546Sopenharmony_ci case DRM_FORMAT_ABGR2101010: 312bf215546Sopenharmony_ci return VK_FORMAT_A2B10G10R10_UNORM_PACK32; 313bf215546Sopenharmony_ci case DRM_FORMAT_YVU420: 314bf215546Sopenharmony_ci return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; 315bf215546Sopenharmony_ci case DRM_FORMAT_NV12: 316bf215546Sopenharmony_ci return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM; 317bf215546Sopenharmony_ci default: 318bf215546Sopenharmony_ci return VK_FORMAT_UNDEFINED; 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci} 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_cistatic bool 323bf215546Sopenharmony_civn_android_drm_format_is_yuv(uint32_t format) 324bf215546Sopenharmony_ci{ 325bf215546Sopenharmony_ci assert(vn_android_drm_format_to_vk_format(format) != VK_FORMAT_UNDEFINED); 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci switch (format) { 328bf215546Sopenharmony_ci case DRM_FORMAT_YVU420: 329bf215546Sopenharmony_ci case DRM_FORMAT_NV12: 330bf215546Sopenharmony_ci return true; 331bf215546Sopenharmony_ci default: 332bf215546Sopenharmony_ci return false; 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci} 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ciuint64_t 337bf215546Sopenharmony_civn_android_get_ahb_usage(const VkImageUsageFlags usage, 338bf215546Sopenharmony_ci const VkImageCreateFlags flags) 339bf215546Sopenharmony_ci{ 340bf215546Sopenharmony_ci uint64_t ahb_usage = 0; 341bf215546Sopenharmony_ci if (usage & 342bf215546Sopenharmony_ci (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) 343bf215546Sopenharmony_ci ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci if (usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 346bf215546Sopenharmony_ci VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) 347bf215546Sopenharmony_ci ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci if (flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 350bf215546Sopenharmony_ci ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci if (flags & VK_IMAGE_CREATE_PROTECTED_BIT) 353bf215546Sopenharmony_ci ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci /* must include at least one GPU usage flag */ 356bf215546Sopenharmony_ci if (ahb_usage == 0) 357bf215546Sopenharmony_ci ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci return ahb_usage; 360bf215546Sopenharmony_ci} 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ciVkResult 363bf215546Sopenharmony_civn_GetSwapchainGrallocUsage2ANDROID( 364bf215546Sopenharmony_ci VkDevice device, 365bf215546Sopenharmony_ci VkFormat format, 366bf215546Sopenharmony_ci VkImageUsageFlags imageUsage, 367bf215546Sopenharmony_ci VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, 368bf215546Sopenharmony_ci uint64_t *grallocConsumerUsage, 369bf215546Sopenharmony_ci uint64_t *grallocProducerUsage) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci if (VN_DEBUG(WSI)) { 374bf215546Sopenharmony_ci vn_log(dev->instance, 375bf215546Sopenharmony_ci "format=%d, imageUsage=0x%x, swapchainImageUsage=0x%x", format, 376bf215546Sopenharmony_ci imageUsage, swapchainImageUsage); 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci *grallocConsumerUsage = 0; 380bf215546Sopenharmony_ci *grallocProducerUsage = 0; 381bf215546Sopenharmony_ci if (imageUsage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT | 382bf215546Sopenharmony_ci VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) 383bf215546Sopenharmony_ci *grallocProducerUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci if (imageUsage & 386bf215546Sopenharmony_ci (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | 387bf215546Sopenharmony_ci VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) 388bf215546Sopenharmony_ci *grallocProducerUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID) 391bf215546Sopenharmony_ci *grallocProducerUsage |= vn_android_gralloc_get_shared_present_usage(); 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci return VK_SUCCESS; 394bf215546Sopenharmony_ci} 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_cistatic VkResult 397bf215546Sopenharmony_civn_android_get_modifier_properties(struct vn_device *dev, 398bf215546Sopenharmony_ci VkFormat format, 399bf215546Sopenharmony_ci uint64_t modifier, 400bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 401bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesEXT *out_props) 402bf215546Sopenharmony_ci{ 403bf215546Sopenharmony_ci VkPhysicalDevice physical_device = 404bf215546Sopenharmony_ci vn_physical_device_to_handle(dev->physical_device); 405bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT mod_prop_list = { 406bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, 407bf215546Sopenharmony_ci .pNext = NULL, 408bf215546Sopenharmony_ci .drmFormatModifierCount = 0, 409bf215546Sopenharmony_ci .pDrmFormatModifierProperties = NULL, 410bf215546Sopenharmony_ci }; 411bf215546Sopenharmony_ci VkFormatProperties2 format_prop = { 412bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, 413bf215546Sopenharmony_ci .pNext = &mod_prop_list, 414bf215546Sopenharmony_ci }; 415bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesEXT *mod_props = NULL; 416bf215546Sopenharmony_ci bool modifier_found = false; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci vn_GetPhysicalDeviceFormatProperties2(physical_device, format, 419bf215546Sopenharmony_ci &format_prop); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci if (!mod_prop_list.drmFormatModifierCount) { 422bf215546Sopenharmony_ci vn_log(dev->instance, "No compatible modifier for VkFormat(%u)", 423bf215546Sopenharmony_ci format); 424bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 425bf215546Sopenharmony_ci } 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci mod_props = vk_zalloc( 428bf215546Sopenharmony_ci alloc, sizeof(*mod_props) * mod_prop_list.drmFormatModifierCount, 429bf215546Sopenharmony_ci VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 430bf215546Sopenharmony_ci if (!mod_props) 431bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci mod_prop_list.pDrmFormatModifierProperties = mod_props; 434bf215546Sopenharmony_ci vn_GetPhysicalDeviceFormatProperties2(physical_device, format, 435bf215546Sopenharmony_ci &format_prop); 436bf215546Sopenharmony_ci 437bf215546Sopenharmony_ci for (uint32_t i = 0; i < mod_prop_list.drmFormatModifierCount; i++) { 438bf215546Sopenharmony_ci if (mod_props[i].drmFormatModifier == modifier) { 439bf215546Sopenharmony_ci *out_props = mod_props[i]; 440bf215546Sopenharmony_ci modifier_found = true; 441bf215546Sopenharmony_ci break; 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci vk_free(alloc, mod_props); 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci if (!modifier_found) { 448bf215546Sopenharmony_ci vn_log(dev->instance, 449bf215546Sopenharmony_ci "No matching modifier(%" PRIu64 ") properties for VkFormat(%u)", 450bf215546Sopenharmony_ci modifier, format); 451bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci return VK_SUCCESS; 455bf215546Sopenharmony_ci} 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_cistruct vn_android_image_builder { 458bf215546Sopenharmony_ci VkImageCreateInfo create; 459bf215546Sopenharmony_ci VkSubresourceLayout layouts[4]; 460bf215546Sopenharmony_ci VkImageDrmFormatModifierExplicitCreateInfoEXT modifier; 461bf215546Sopenharmony_ci VkExternalMemoryImageCreateInfo external; 462bf215546Sopenharmony_ci VkImageFormatListCreateInfo list; 463bf215546Sopenharmony_ci}; 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_cistatic VkResult 466bf215546Sopenharmony_civn_android_get_image_builder(struct vn_device *dev, 467bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 468bf215546Sopenharmony_ci const native_handle_t *handle, 469bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 470bf215546Sopenharmony_ci struct vn_android_image_builder *out_builder) 471bf215546Sopenharmony_ci{ 472bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 473bf215546Sopenharmony_ci struct vn_android_gralloc_buffer_properties buf_props; 474bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesEXT mod_props; 475bf215546Sopenharmony_ci uint32_t vcount = 0; 476bf215546Sopenharmony_ci const VkFormat *vformats = NULL; 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci /* Android image builder is only used by ANB or AHB. For ANB, Android 479bf215546Sopenharmony_ci * Vulkan loader will never pass the below structs. For AHB, struct 480bf215546Sopenharmony_ci * vn_image_create_deferred_info will never carry below either. 481bf215546Sopenharmony_ci */ 482bf215546Sopenharmony_ci assert(!vk_find_struct_const( 483bf215546Sopenharmony_ci create_info->pNext, 484bf215546Sopenharmony_ci IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT)); 485bf215546Sopenharmony_ci assert(!vk_find_struct_const(create_info->pNext, 486bf215546Sopenharmony_ci EXTERNAL_MEMORY_IMAGE_CREATE_INFO)); 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci if (!vn_android_gralloc_get_buffer_properties(handle, &buf_props)) 489bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci result = vn_android_get_modifier_properties( 492bf215546Sopenharmony_ci dev, create_info->format, buf_props.modifier, alloc, &mod_props); 493bf215546Sopenharmony_ci if (result != VK_SUCCESS) 494bf215546Sopenharmony_ci return result; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci /* fill VkImageCreateInfo */ 497bf215546Sopenharmony_ci memset(out_builder, 0, sizeof(*out_builder)); 498bf215546Sopenharmony_ci out_builder->create = *create_info; 499bf215546Sopenharmony_ci out_builder->create.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci /* fill VkImageDrmFormatModifierExplicitCreateInfoEXT */ 502bf215546Sopenharmony_ci for (uint32_t i = 0; i < mod_props.drmFormatModifierPlaneCount; i++) { 503bf215546Sopenharmony_ci out_builder->layouts[i].offset = buf_props.offset[i]; 504bf215546Sopenharmony_ci out_builder->layouts[i].rowPitch = buf_props.stride[i]; 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci out_builder->modifier = (VkImageDrmFormatModifierExplicitCreateInfoEXT){ 507bf215546Sopenharmony_ci .sType = 508bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT, 509bf215546Sopenharmony_ci .pNext = out_builder->create.pNext, 510bf215546Sopenharmony_ci .drmFormatModifier = buf_props.modifier, 511bf215546Sopenharmony_ci .drmFormatModifierPlaneCount = mod_props.drmFormatModifierPlaneCount, 512bf215546Sopenharmony_ci .pPlaneLayouts = out_builder->layouts, 513bf215546Sopenharmony_ci }; 514bf215546Sopenharmony_ci out_builder->create.pNext = &out_builder->modifier; 515bf215546Sopenharmony_ci 516bf215546Sopenharmony_ci /* fill VkExternalMemoryImageCreateInfo */ 517bf215546Sopenharmony_ci out_builder->external = (VkExternalMemoryImageCreateInfo){ 518bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, 519bf215546Sopenharmony_ci .pNext = out_builder->create.pNext, 520bf215546Sopenharmony_ci .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 521bf215546Sopenharmony_ci }; 522bf215546Sopenharmony_ci out_builder->create.pNext = &out_builder->external; 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci /* fill VkImageFormatListCreateInfo if needed 525bf215546Sopenharmony_ci * 526bf215546Sopenharmony_ci * vn_image::deferred_info only stores VkImageFormatListCreateInfo with a 527bf215546Sopenharmony_ci * non-zero viewFormatCount, and that stored struct will be respected. 528bf215546Sopenharmony_ci */ 529bf215546Sopenharmony_ci if ((create_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && 530bf215546Sopenharmony_ci !vk_find_struct_const(create_info->pNext, 531bf215546Sopenharmony_ci IMAGE_FORMAT_LIST_CREATE_INFO)) { 532bf215546Sopenharmony_ci /* 12.3. Images 533bf215546Sopenharmony_ci * 534bf215546Sopenharmony_ci * If tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and flags 535bf215546Sopenharmony_ci * contains VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, then the pNext chain 536bf215546Sopenharmony_ci * must include a VkImageFormatListCreateInfo structure with non-zero 537bf215546Sopenharmony_ci * viewFormatCount. 538bf215546Sopenharmony_ci */ 539bf215546Sopenharmony_ci vformats = 540bf215546Sopenharmony_ci vn_android_format_to_view_formats(create_info->format, &vcount); 541bf215546Sopenharmony_ci if (!vformats) { 542bf215546Sopenharmony_ci /* image builder struct persists through the image creation call */ 543bf215546Sopenharmony_ci vformats = &out_builder->create.format; 544bf215546Sopenharmony_ci vcount = 1; 545bf215546Sopenharmony_ci } 546bf215546Sopenharmony_ci out_builder->list = (VkImageFormatListCreateInfo){ 547bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, 548bf215546Sopenharmony_ci .pNext = out_builder->create.pNext, 549bf215546Sopenharmony_ci .viewFormatCount = vcount, 550bf215546Sopenharmony_ci .pViewFormats = vformats, 551bf215546Sopenharmony_ci }; 552bf215546Sopenharmony_ci out_builder->create.pNext = &out_builder->list; 553bf215546Sopenharmony_ci } 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci return VK_SUCCESS; 556bf215546Sopenharmony_ci} 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ciVkResult 559bf215546Sopenharmony_civn_android_image_from_anb(struct vn_device *dev, 560bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 561bf215546Sopenharmony_ci const VkNativeBufferANDROID *anb_info, 562bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 563bf215546Sopenharmony_ci struct vn_image **out_img) 564bf215546Sopenharmony_ci{ 565bf215546Sopenharmony_ci /* If anb_info->handle points to a classic resouce created from 566bf215546Sopenharmony_ci * virtio_gpu_cmd_resource_create_3d, anb_info->stride is the stride of the 567bf215546Sopenharmony_ci * guest shadow storage other than the host gpu storage. 568bf215546Sopenharmony_ci * 569bf215546Sopenharmony_ci * We also need to pass the correct stride to vn_CreateImage, which will be 570bf215546Sopenharmony_ci * done via VkImageDrmFormatModifierExplicitCreateInfoEXT and will require 571bf215546Sopenharmony_ci * VK_EXT_image_drm_format_modifier support in the host driver. The struct 572bf215546Sopenharmony_ci * needs host storage info which can be queried from cros gralloc. 573bf215546Sopenharmony_ci */ 574bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 575bf215546Sopenharmony_ci VkDevice device = vn_device_to_handle(dev); 576bf215546Sopenharmony_ci VkDeviceMemory memory = VK_NULL_HANDLE; 577bf215546Sopenharmony_ci VkImage image = VK_NULL_HANDLE; 578bf215546Sopenharmony_ci struct vn_image *img = NULL; 579bf215546Sopenharmony_ci uint64_t alloc_size = 0; 580bf215546Sopenharmony_ci uint32_t mem_type_bits = 0; 581bf215546Sopenharmony_ci int dma_buf_fd = -1; 582bf215546Sopenharmony_ci int dup_fd = -1; 583bf215546Sopenharmony_ci VkImageCreateInfo local_create_info; 584bf215546Sopenharmony_ci struct vn_android_image_builder builder; 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(anb_info->handle); 587bf215546Sopenharmony_ci if (dma_buf_fd < 0) { 588bf215546Sopenharmony_ci result = VK_ERROR_INVALID_EXTERNAL_HANDLE; 589bf215546Sopenharmony_ci goto fail; 590bf215546Sopenharmony_ci } 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci assert(!(create_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)); 593bf215546Sopenharmony_ci assert(!vk_find_struct_const(create_info->pNext, 594bf215546Sopenharmony_ci IMAGE_FORMAT_LIST_CREATE_INFO)); 595bf215546Sopenharmony_ci assert(!vk_find_struct_const(create_info->pNext, 596bf215546Sopenharmony_ci IMAGE_STENCIL_USAGE_CREATE_INFO)); 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci /* strip VkNativeBufferANDROID and VkSwapchainImageCreateInfoANDROID */ 599bf215546Sopenharmony_ci local_create_info = *create_info; 600bf215546Sopenharmony_ci local_create_info.pNext = NULL; 601bf215546Sopenharmony_ci result = vn_android_get_image_builder(dev, &local_create_info, 602bf215546Sopenharmony_ci anb_info->handle, alloc, &builder); 603bf215546Sopenharmony_ci if (result != VK_SUCCESS) 604bf215546Sopenharmony_ci goto fail; 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci /* encoder will strip the Android specific pNext structs */ 607bf215546Sopenharmony_ci result = vn_image_create(dev, &builder.create, alloc, &img); 608bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 609bf215546Sopenharmony_ci if (VN_DEBUG(WSI)) 610bf215546Sopenharmony_ci vn_log(dev->instance, "vn_image_create failed"); 611bf215546Sopenharmony_ci goto fail; 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci image = vn_image_to_handle(img); 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci const VkMemoryRequirements *mem_req = 617bf215546Sopenharmony_ci &img->requirements[0].memory.memoryRequirements; 618bf215546Sopenharmony_ci if (!mem_req->memoryTypeBits) { 619bf215546Sopenharmony_ci if (VN_DEBUG(WSI)) 620bf215546Sopenharmony_ci vn_log(dev->instance, "mem_req->memoryTypeBits cannot be zero"); 621bf215546Sopenharmony_ci result = VK_ERROR_INVALID_EXTERNAL_HANDLE; 622bf215546Sopenharmony_ci goto fail; 623bf215546Sopenharmony_ci } 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size, 626bf215546Sopenharmony_ci &mem_type_bits); 627bf215546Sopenharmony_ci if (result != VK_SUCCESS) 628bf215546Sopenharmony_ci goto fail; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci if (VN_DEBUG(WSI)) { 631bf215546Sopenharmony_ci vn_log(dev->instance, 632bf215546Sopenharmony_ci "size = img(%" PRIu64 ") fd(%" PRIu64 "), " 633bf215546Sopenharmony_ci "memoryTypeBits = img(0x%X) & fd(0x%X)", 634bf215546Sopenharmony_ci mem_req->size, alloc_size, mem_req->memoryTypeBits, 635bf215546Sopenharmony_ci mem_type_bits); 636bf215546Sopenharmony_ci } 637bf215546Sopenharmony_ci 638bf215546Sopenharmony_ci if (alloc_size < mem_req->size) { 639bf215546Sopenharmony_ci if (VN_DEBUG(WSI)) { 640bf215546Sopenharmony_ci vn_log(dev->instance, 641bf215546Sopenharmony_ci "alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")", 642bf215546Sopenharmony_ci alloc_size, mem_req->size); 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci result = VK_ERROR_INVALID_EXTERNAL_HANDLE; 645bf215546Sopenharmony_ci goto fail; 646bf215546Sopenharmony_ci } 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci mem_type_bits &= mem_req->memoryTypeBits; 649bf215546Sopenharmony_ci if (!mem_type_bits) { 650bf215546Sopenharmony_ci result = VK_ERROR_INVALID_EXTERNAL_HANDLE; 651bf215546Sopenharmony_ci goto fail; 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci dup_fd = os_dupfd_cloexec(dma_buf_fd); 655bf215546Sopenharmony_ci if (dup_fd < 0) { 656bf215546Sopenharmony_ci result = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS 657bf215546Sopenharmony_ci : VK_ERROR_OUT_OF_HOST_MEMORY; 658bf215546Sopenharmony_ci goto fail; 659bf215546Sopenharmony_ci } 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci const VkImportMemoryFdInfoKHR import_fd_info = { 662bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 663bf215546Sopenharmony_ci .pNext = NULL, 664bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 665bf215546Sopenharmony_ci .fd = dup_fd, 666bf215546Sopenharmony_ci }; 667bf215546Sopenharmony_ci const VkMemoryAllocateInfo memory_info = { 668bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 669bf215546Sopenharmony_ci .pNext = &import_fd_info, 670bf215546Sopenharmony_ci .allocationSize = mem_req->size, 671bf215546Sopenharmony_ci .memoryTypeIndex = ffs(mem_type_bits) - 1, 672bf215546Sopenharmony_ci }; 673bf215546Sopenharmony_ci result = vn_AllocateMemory(device, &memory_info, alloc, &memory); 674bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 675bf215546Sopenharmony_ci /* only need to close the dup_fd on import failure */ 676bf215546Sopenharmony_ci close(dup_fd); 677bf215546Sopenharmony_ci goto fail; 678bf215546Sopenharmony_ci } 679bf215546Sopenharmony_ci 680bf215546Sopenharmony_ci const VkBindImageMemoryInfo bind_info = { 681bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, 682bf215546Sopenharmony_ci .pNext = NULL, 683bf215546Sopenharmony_ci .image = image, 684bf215546Sopenharmony_ci .memory = memory, 685bf215546Sopenharmony_ci .memoryOffset = 0, 686bf215546Sopenharmony_ci }; 687bf215546Sopenharmony_ci result = vn_BindImageMemory2(device, 1, &bind_info); 688bf215546Sopenharmony_ci if (result != VK_SUCCESS) 689bf215546Sopenharmony_ci goto fail; 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci img->wsi.is_wsi = true; 692bf215546Sopenharmony_ci img->wsi.tiling_override = builder.create.tiling; 693bf215546Sopenharmony_ci img->wsi.drm_format_modifier = builder.modifier.drmFormatModifier; 694bf215546Sopenharmony_ci /* Android WSI image owns the memory */ 695bf215546Sopenharmony_ci img->wsi.memory = vn_device_memory_from_handle(memory); 696bf215546Sopenharmony_ci img->wsi.memory_owned = true; 697bf215546Sopenharmony_ci *out_img = img; 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci return VK_SUCCESS; 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_cifail: 702bf215546Sopenharmony_ci if (image != VK_NULL_HANDLE) 703bf215546Sopenharmony_ci vn_DestroyImage(device, image, alloc); 704bf215546Sopenharmony_ci if (memory != VK_NULL_HANDLE) 705bf215546Sopenharmony_ci vn_FreeMemory(device, memory, alloc); 706bf215546Sopenharmony_ci return vn_error(dev->instance, result); 707bf215546Sopenharmony_ci} 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ciVkResult 710bf215546Sopenharmony_civn_AcquireImageANDROID(VkDevice device, 711bf215546Sopenharmony_ci UNUSED VkImage image, 712bf215546Sopenharmony_ci int nativeFenceFd, 713bf215546Sopenharmony_ci VkSemaphore semaphore, 714bf215546Sopenharmony_ci VkFence fence) 715bf215546Sopenharmony_ci{ 716bf215546Sopenharmony_ci VN_TRACE_FUNC(); 717bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 718bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 719bf215546Sopenharmony_ci 720bf215546Sopenharmony_ci if (dev->instance->experimental.globalFencing == VK_FALSE) { 721bf215546Sopenharmony_ci /* Fallback when VkVenusExperimentalFeatures100000MESA::globalFencing is 722bf215546Sopenharmony_ci * VK_FALSE, out semaphore and fence are filled with already signaled 723bf215546Sopenharmony_ci * payloads, and the native fence fd is waited inside until signaled. 724bf215546Sopenharmony_ci */ 725bf215546Sopenharmony_ci if (nativeFenceFd >= 0) { 726bf215546Sopenharmony_ci int ret = sync_wait(nativeFenceFd, -1); 727bf215546Sopenharmony_ci /* Android loader expects the ICD to always close the fd */ 728bf215546Sopenharmony_ci close(nativeFenceFd); 729bf215546Sopenharmony_ci if (ret) 730bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_SURFACE_LOST_KHR); 731bf215546Sopenharmony_ci } 732bf215546Sopenharmony_ci 733bf215546Sopenharmony_ci if (semaphore != VK_NULL_HANDLE) 734bf215546Sopenharmony_ci vn_semaphore_signal_wsi(dev, vn_semaphore_from_handle(semaphore)); 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci if (fence != VK_NULL_HANDLE) 737bf215546Sopenharmony_ci vn_fence_signal_wsi(dev, vn_fence_from_handle(fence)); 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci return VK_SUCCESS; 740bf215546Sopenharmony_ci } 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci int semaphore_fd = -1; 743bf215546Sopenharmony_ci int fence_fd = -1; 744bf215546Sopenharmony_ci if (nativeFenceFd >= 0) { 745bf215546Sopenharmony_ci if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) { 746bf215546Sopenharmony_ci semaphore_fd = nativeFenceFd; 747bf215546Sopenharmony_ci fence_fd = os_dupfd_cloexec(nativeFenceFd); 748bf215546Sopenharmony_ci if (fence_fd < 0) { 749bf215546Sopenharmony_ci result = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS 750bf215546Sopenharmony_ci : VK_ERROR_OUT_OF_HOST_MEMORY; 751bf215546Sopenharmony_ci close(nativeFenceFd); 752bf215546Sopenharmony_ci return vn_error(dev->instance, result); 753bf215546Sopenharmony_ci } 754bf215546Sopenharmony_ci } else if (semaphore != VK_NULL_HANDLE) { 755bf215546Sopenharmony_ci semaphore_fd = nativeFenceFd; 756bf215546Sopenharmony_ci } else if (fence != VK_NULL_HANDLE) { 757bf215546Sopenharmony_ci fence_fd = nativeFenceFd; 758bf215546Sopenharmony_ci } else { 759bf215546Sopenharmony_ci close(nativeFenceFd); 760bf215546Sopenharmony_ci } 761bf215546Sopenharmony_ci } 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci if (semaphore != VK_NULL_HANDLE) { 764bf215546Sopenharmony_ci const VkImportSemaphoreFdInfoKHR info = { 765bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR, 766bf215546Sopenharmony_ci .pNext = NULL, 767bf215546Sopenharmony_ci .semaphore = semaphore, 768bf215546Sopenharmony_ci .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, 769bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, 770bf215546Sopenharmony_ci .fd = semaphore_fd, 771bf215546Sopenharmony_ci }; 772bf215546Sopenharmony_ci result = vn_ImportSemaphoreFdKHR(device, &info); 773bf215546Sopenharmony_ci if (result == VK_SUCCESS) 774bf215546Sopenharmony_ci semaphore_fd = -1; 775bf215546Sopenharmony_ci } 776bf215546Sopenharmony_ci 777bf215546Sopenharmony_ci if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) { 778bf215546Sopenharmony_ci const VkImportFenceFdInfoKHR info = { 779bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR, 780bf215546Sopenharmony_ci .pNext = NULL, 781bf215546Sopenharmony_ci .fence = fence, 782bf215546Sopenharmony_ci .flags = VK_FENCE_IMPORT_TEMPORARY_BIT, 783bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, 784bf215546Sopenharmony_ci .fd = fence_fd, 785bf215546Sopenharmony_ci }; 786bf215546Sopenharmony_ci result = vn_ImportFenceFdKHR(device, &info); 787bf215546Sopenharmony_ci if (result == VK_SUCCESS) 788bf215546Sopenharmony_ci fence_fd = -1; 789bf215546Sopenharmony_ci } 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci if (semaphore_fd >= 0) 792bf215546Sopenharmony_ci close(semaphore_fd); 793bf215546Sopenharmony_ci if (fence_fd >= 0) 794bf215546Sopenharmony_ci close(fence_fd); 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci return vn_result(dev->instance, result); 797bf215546Sopenharmony_ci} 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ciVkResult 800bf215546Sopenharmony_civn_QueueSignalReleaseImageANDROID(VkQueue queue, 801bf215546Sopenharmony_ci uint32_t waitSemaphoreCount, 802bf215546Sopenharmony_ci const VkSemaphore *pWaitSemaphores, 803bf215546Sopenharmony_ci VkImage image, 804bf215546Sopenharmony_ci int *pNativeFenceFd) 805bf215546Sopenharmony_ci{ 806bf215546Sopenharmony_ci VN_TRACE_FUNC(); 807bf215546Sopenharmony_ci struct vn_queue *que = vn_queue_from_handle(queue); 808bf215546Sopenharmony_ci struct vn_device *dev = que->device; 809bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 810bf215546Sopenharmony_ci VkDevice device = vn_device_to_handle(dev); 811bf215546Sopenharmony_ci VkPipelineStageFlags local_stage_masks[8]; 812bf215546Sopenharmony_ci VkPipelineStageFlags *stage_masks = local_stage_masks; 813bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 814bf215546Sopenharmony_ci int fd = -1; 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci if (waitSemaphoreCount == 0) { 817bf215546Sopenharmony_ci *pNativeFenceFd = -1; 818bf215546Sopenharmony_ci return VK_SUCCESS; 819bf215546Sopenharmony_ci } 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci if (waitSemaphoreCount > ARRAY_SIZE(local_stage_masks)) { 822bf215546Sopenharmony_ci stage_masks = 823bf215546Sopenharmony_ci vk_alloc(alloc, sizeof(*stage_masks) * waitSemaphoreCount, 824bf215546Sopenharmony_ci VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 825bf215546Sopenharmony_ci if (!stage_masks) 826bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 827bf215546Sopenharmony_ci } 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_ci for (uint32_t i = 0; i < waitSemaphoreCount; i++) 830bf215546Sopenharmony_ci stage_masks[i] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci const VkSubmitInfo submit_info = { 833bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, 834bf215546Sopenharmony_ci .pNext = NULL, 835bf215546Sopenharmony_ci .waitSemaphoreCount = waitSemaphoreCount, 836bf215546Sopenharmony_ci .pWaitSemaphores = pWaitSemaphores, 837bf215546Sopenharmony_ci .pWaitDstStageMask = stage_masks, 838bf215546Sopenharmony_ci .commandBufferCount = 0, 839bf215546Sopenharmony_ci .pCommandBuffers = NULL, 840bf215546Sopenharmony_ci .signalSemaphoreCount = 0, 841bf215546Sopenharmony_ci .pSignalSemaphores = NULL, 842bf215546Sopenharmony_ci }; 843bf215546Sopenharmony_ci /* XXX When globalFencing is supported, our implementation is not able to 844bf215546Sopenharmony_ci * reset the fence during vn_GetFenceFdKHR currently. Thus to ensure proper 845bf215546Sopenharmony_ci * host driver behavior, we pass VK_NULL_HANDLE here. 846bf215546Sopenharmony_ci */ 847bf215546Sopenharmony_ci result = vn_QueueSubmit( 848bf215546Sopenharmony_ci queue, 1, &submit_info, 849bf215546Sopenharmony_ci dev->instance->experimental.globalFencing == VK_TRUE ? VK_NULL_HANDLE 850bf215546Sopenharmony_ci : que->wait_fence); 851bf215546Sopenharmony_ci 852bf215546Sopenharmony_ci if (stage_masks != local_stage_masks) 853bf215546Sopenharmony_ci vk_free(alloc, stage_masks); 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ci if (result != VK_SUCCESS) 856bf215546Sopenharmony_ci return vn_error(dev->instance, result); 857bf215546Sopenharmony_ci 858bf215546Sopenharmony_ci if (dev->instance->experimental.globalFencing == VK_TRUE) { 859bf215546Sopenharmony_ci /* With globalFencing, the external queue fence was not passed in the 860bf215546Sopenharmony_ci * above vn_QueueSubmit to hint it to be synchronous. So we need to wait 861bf215546Sopenharmony_ci * for the ring here before vn_GetFenceFdKHR which is pure kernel ops. 862bf215546Sopenharmony_ci * Skip ring wait if async queue submit is disabled. 863bf215546Sopenharmony_ci */ 864bf215546Sopenharmony_ci if (!VN_PERF(NO_ASYNC_QUEUE_SUBMIT)) 865bf215546Sopenharmony_ci vn_instance_ring_wait(dev->instance); 866bf215546Sopenharmony_ci 867bf215546Sopenharmony_ci const VkFenceGetFdInfoKHR fd_info = { 868bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR, 869bf215546Sopenharmony_ci .pNext = NULL, 870bf215546Sopenharmony_ci .fence = que->wait_fence, 871bf215546Sopenharmony_ci .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, 872bf215546Sopenharmony_ci }; 873bf215546Sopenharmony_ci result = vn_GetFenceFdKHR(device, &fd_info, &fd); 874bf215546Sopenharmony_ci } else { 875bf215546Sopenharmony_ci result = 876bf215546Sopenharmony_ci vn_WaitForFences(device, 1, &que->wait_fence, VK_TRUE, UINT64_MAX); 877bf215546Sopenharmony_ci if (result != VK_SUCCESS) 878bf215546Sopenharmony_ci return vn_error(dev->instance, result); 879bf215546Sopenharmony_ci 880bf215546Sopenharmony_ci result = vn_ResetFences(device, 1, &que->wait_fence); 881bf215546Sopenharmony_ci } 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci if (result != VK_SUCCESS) 884bf215546Sopenharmony_ci return vn_error(dev->instance, result); 885bf215546Sopenharmony_ci 886bf215546Sopenharmony_ci *pNativeFenceFd = fd; 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci return VK_SUCCESS; 889bf215546Sopenharmony_ci} 890bf215546Sopenharmony_ci 891bf215546Sopenharmony_cistatic VkResult 892bf215546Sopenharmony_civn_android_get_ahb_format_properties( 893bf215546Sopenharmony_ci struct vn_device *dev, 894bf215546Sopenharmony_ci const struct AHardwareBuffer *ahb, 895bf215546Sopenharmony_ci VkAndroidHardwareBufferFormatPropertiesANDROID *out_props) 896bf215546Sopenharmony_ci{ 897bf215546Sopenharmony_ci AHardwareBuffer_Desc desc; 898bf215546Sopenharmony_ci VkFormat format; 899bf215546Sopenharmony_ci struct vn_android_gralloc_buffer_properties buf_props; 900bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesEXT mod_props; 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci AHardwareBuffer_describe(ahb, &desc); 903bf215546Sopenharmony_ci if (!(desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | 904bf215546Sopenharmony_ci AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER | 905bf215546Sopenharmony_ci AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER))) { 906bf215546Sopenharmony_ci vn_log(dev->instance, 907bf215546Sopenharmony_ci "AHB usage(%" PRIu64 ") must include at least one GPU bit", 908bf215546Sopenharmony_ci desc.usage); 909bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 910bf215546Sopenharmony_ci } 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci /* Handle the special AHARDWAREBUFFER_FORMAT_BLOB for VkBuffer case. */ 913bf215546Sopenharmony_ci if (desc.format == AHARDWAREBUFFER_FORMAT_BLOB) { 914bf215546Sopenharmony_ci out_props->format = VK_FORMAT_UNDEFINED; 915bf215546Sopenharmony_ci return VK_SUCCESS; 916bf215546Sopenharmony_ci } 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci if (!vn_android_gralloc_get_buffer_properties( 919bf215546Sopenharmony_ci AHardwareBuffer_getNativeHandle(ahb), &buf_props)) 920bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci /* We implement AHB extension support with EXT_image_drm_format_modifier. 923bf215546Sopenharmony_ci * It requires us to have a compatible VkFormat but not DRM formats. So if 924bf215546Sopenharmony_ci * the ahb is not intended for backing a VkBuffer, error out early if the 925bf215546Sopenharmony_ci * format is VK_FORMAT_UNDEFINED. 926bf215546Sopenharmony_ci */ 927bf215546Sopenharmony_ci format = vn_android_drm_format_to_vk_format(buf_props.drm_fourcc); 928bf215546Sopenharmony_ci if (format == VK_FORMAT_UNDEFINED) { 929bf215546Sopenharmony_ci vn_log(dev->instance, "Unknown drm_fourcc(%u) from AHB format(0x%X)", 930bf215546Sopenharmony_ci buf_props.drm_fourcc, desc.format); 931bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 932bf215546Sopenharmony_ci } 933bf215546Sopenharmony_ci 934bf215546Sopenharmony_ci VkResult result = vn_android_get_modifier_properties( 935bf215546Sopenharmony_ci dev, format, buf_props.modifier, &dev->base.base.alloc, &mod_props); 936bf215546Sopenharmony_ci if (result != VK_SUCCESS) 937bf215546Sopenharmony_ci return result; 938bf215546Sopenharmony_ci 939bf215546Sopenharmony_ci /* The spec requires that formatFeatures must include at least one of 940bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or 941bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT. 942bf215546Sopenharmony_ci */ 943bf215546Sopenharmony_ci const VkFormatFeatureFlags format_features = 944bf215546Sopenharmony_ci mod_props.drmFormatModifierTilingFeatures | 945bf215546Sopenharmony_ci VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT; 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci /* 11.2.7. Android Hardware Buffer External Memory 948bf215546Sopenharmony_ci * 949bf215546Sopenharmony_ci * Implementations may not always be able to determine the color model, 950bf215546Sopenharmony_ci * numerical range, or chroma offsets of the image contents, so the values 951bf215546Sopenharmony_ci * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions. 952bf215546Sopenharmony_ci * Applications should treat these values as sensible defaults to use in the 953bf215546Sopenharmony_ci * absence of more reliable information obtained through some other means. 954bf215546Sopenharmony_ci */ 955bf215546Sopenharmony_ci const bool is_yuv = vn_android_drm_format_is_yuv(buf_props.drm_fourcc); 956bf215546Sopenharmony_ci const VkSamplerYcbcrModelConversion model = 957bf215546Sopenharmony_ci is_yuv ? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 958bf215546Sopenharmony_ci : VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; 959bf215546Sopenharmony_ci 960bf215546Sopenharmony_ci /* ANGLE expects VK_FORMAT_UNDEFINED with externalFormat resolved from 961bf215546Sopenharmony_ci * AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED and any supported planar 962bf215546Sopenharmony_ci * AHB formats. Venus supports below explicit ones: 963bf215546Sopenharmony_ci * - AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 (DRM_FORMAT_NV12) 964bf215546Sopenharmony_ci * - AHARDWAREBUFFER_FORMAT_YV12 (DRM_FORMAT_YVU420) 965bf215546Sopenharmony_ci */ 966bf215546Sopenharmony_ci if (desc.format == AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED || is_yuv) 967bf215546Sopenharmony_ci format = VK_FORMAT_UNDEFINED; 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci *out_props = (VkAndroidHardwareBufferFormatPropertiesANDROID) { 970bf215546Sopenharmony_ci .sType = out_props->sType, 971bf215546Sopenharmony_ci .pNext = out_props->pNext, 972bf215546Sopenharmony_ci .format = format, 973bf215546Sopenharmony_ci .externalFormat = buf_props.drm_fourcc, 974bf215546Sopenharmony_ci .formatFeatures = format_features, 975bf215546Sopenharmony_ci .samplerYcbcrConversionComponents = { 976bf215546Sopenharmony_ci .r = VK_COMPONENT_SWIZZLE_IDENTITY, 977bf215546Sopenharmony_ci .g = VK_COMPONENT_SWIZZLE_IDENTITY, 978bf215546Sopenharmony_ci .b = VK_COMPONENT_SWIZZLE_IDENTITY, 979bf215546Sopenharmony_ci .a = VK_COMPONENT_SWIZZLE_IDENTITY, 980bf215546Sopenharmony_ci }, 981bf215546Sopenharmony_ci .suggestedYcbcrModel = model, 982bf215546Sopenharmony_ci /* match EGL_YUV_NARROW_RANGE_EXT used in egl platform_android */ 983bf215546Sopenharmony_ci .suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, 984bf215546Sopenharmony_ci .suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, 985bf215546Sopenharmony_ci .suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT, 986bf215546Sopenharmony_ci }; 987bf215546Sopenharmony_ci 988bf215546Sopenharmony_ci return VK_SUCCESS; 989bf215546Sopenharmony_ci} 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ciVkResult 992bf215546Sopenharmony_civn_GetAndroidHardwareBufferPropertiesANDROID( 993bf215546Sopenharmony_ci VkDevice device, 994bf215546Sopenharmony_ci const struct AHardwareBuffer *buffer, 995bf215546Sopenharmony_ci VkAndroidHardwareBufferPropertiesANDROID *pProperties) 996bf215546Sopenharmony_ci{ 997bf215546Sopenharmony_ci VN_TRACE_FUNC(); 998bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 999bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 1000bf215546Sopenharmony_ci int dma_buf_fd = -1; 1001bf215546Sopenharmony_ci uint64_t alloc_size = 0; 1002bf215546Sopenharmony_ci uint32_t mem_type_bits = 0; 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci VkAndroidHardwareBufferFormatPropertiesANDROID *format_props = 1005bf215546Sopenharmony_ci vk_find_struct(pProperties->pNext, 1006bf215546Sopenharmony_ci ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID); 1007bf215546Sopenharmony_ci if (format_props) { 1008bf215546Sopenharmony_ci result = 1009bf215546Sopenharmony_ci vn_android_get_ahb_format_properties(dev, buffer, format_props); 1010bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1011bf215546Sopenharmony_ci return vn_error(dev->instance, result); 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci dma_buf_fd = vn_android_gralloc_get_dma_buf_fd( 1015bf215546Sopenharmony_ci AHardwareBuffer_getNativeHandle(buffer)); 1016bf215546Sopenharmony_ci if (dma_buf_fd < 0) 1017bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE); 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size, 1020bf215546Sopenharmony_ci &mem_type_bits); 1021bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1022bf215546Sopenharmony_ci return vn_error(dev->instance, result); 1023bf215546Sopenharmony_ci 1024bf215546Sopenharmony_ci pProperties->allocationSize = alloc_size; 1025bf215546Sopenharmony_ci pProperties->memoryTypeBits = mem_type_bits; 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci return VK_SUCCESS; 1028bf215546Sopenharmony_ci} 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_cistatic AHardwareBuffer * 1031bf215546Sopenharmony_civn_android_ahb_allocate(uint32_t width, 1032bf215546Sopenharmony_ci uint32_t height, 1033bf215546Sopenharmony_ci uint32_t layers, 1034bf215546Sopenharmony_ci uint32_t format, 1035bf215546Sopenharmony_ci uint64_t usage) 1036bf215546Sopenharmony_ci{ 1037bf215546Sopenharmony_ci AHardwareBuffer *ahb = NULL; 1038bf215546Sopenharmony_ci AHardwareBuffer_Desc desc; 1039bf215546Sopenharmony_ci int ret = 0; 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci memset(&desc, 0, sizeof(desc)); 1042bf215546Sopenharmony_ci desc.width = width; 1043bf215546Sopenharmony_ci desc.height = height; 1044bf215546Sopenharmony_ci desc.layers = layers; 1045bf215546Sopenharmony_ci desc.format = format; 1046bf215546Sopenharmony_ci desc.usage = usage; 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci ret = AHardwareBuffer_allocate(&desc, &ahb); 1049bf215546Sopenharmony_ci if (ret) { 1050bf215546Sopenharmony_ci /* We just log the error code here for now since the platform falsely 1051bf215546Sopenharmony_ci * maps all gralloc allocation failures to oom. 1052bf215546Sopenharmony_ci */ 1053bf215546Sopenharmony_ci vn_log(NULL, "AHB alloc(w=%u,h=%u,l=%u,f=%u,u=%" PRIu64 ") failed(%d)", 1054bf215546Sopenharmony_ci width, height, layers, format, usage, ret); 1055bf215546Sopenharmony_ci return NULL; 1056bf215546Sopenharmony_ci } 1057bf215546Sopenharmony_ci 1058bf215546Sopenharmony_ci return ahb; 1059bf215546Sopenharmony_ci} 1060bf215546Sopenharmony_ci 1061bf215546Sopenharmony_cibool 1062bf215546Sopenharmony_civn_android_get_drm_format_modifier_info( 1063bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *format_info, 1064bf215546Sopenharmony_ci VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info) 1065bf215546Sopenharmony_ci{ 1066bf215546Sopenharmony_ci /* To properly fill VkPhysicalDeviceImageDrmFormatModifierInfoEXT, we have 1067bf215546Sopenharmony_ci * to allocate an ahb to retrieve the drm format modifier. For the image 1068bf215546Sopenharmony_ci * sharing mode, we assume VK_SHARING_MODE_EXCLUSIVE for now. 1069bf215546Sopenharmony_ci */ 1070bf215546Sopenharmony_ci AHardwareBuffer *ahb = NULL; 1071bf215546Sopenharmony_ci uint32_t format = 0; 1072bf215546Sopenharmony_ci uint64_t usage = 0; 1073bf215546Sopenharmony_ci struct vn_android_gralloc_buffer_properties buf_props; 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci assert(format_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT); 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci format = vn_android_ahb_format_from_vk_format(format_info->format); 1078bf215546Sopenharmony_ci if (!format) 1079bf215546Sopenharmony_ci return false; 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_ci usage = vn_android_get_ahb_usage(format_info->usage, format_info->flags); 1082bf215546Sopenharmony_ci ahb = vn_android_ahb_allocate(16, 16, 1, format, usage); 1083bf215546Sopenharmony_ci if (!ahb) 1084bf215546Sopenharmony_ci return false; 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_ci if (!vn_android_gralloc_get_buffer_properties( 1087bf215546Sopenharmony_ci AHardwareBuffer_getNativeHandle(ahb), &buf_props)) { 1088bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1089bf215546Sopenharmony_ci return false; 1090bf215546Sopenharmony_ci } 1091bf215546Sopenharmony_ci 1092bf215546Sopenharmony_ci *out_info = (VkPhysicalDeviceImageDrmFormatModifierInfoEXT){ 1093bf215546Sopenharmony_ci .sType = 1094bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, 1095bf215546Sopenharmony_ci .pNext = NULL, 1096bf215546Sopenharmony_ci .drmFormatModifier = buf_props.modifier, 1097bf215546Sopenharmony_ci .sharingMode = VK_SHARING_MODE_EXCLUSIVE, 1098bf215546Sopenharmony_ci .queueFamilyIndexCount = 0, 1099bf215546Sopenharmony_ci .pQueueFamilyIndices = NULL, 1100bf215546Sopenharmony_ci }; 1101bf215546Sopenharmony_ci 1102bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1103bf215546Sopenharmony_ci return true; 1104bf215546Sopenharmony_ci} 1105bf215546Sopenharmony_ci 1106bf215546Sopenharmony_ciVkResult 1107bf215546Sopenharmony_civn_android_image_from_ahb(struct vn_device *dev, 1108bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 1109bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 1110bf215546Sopenharmony_ci struct vn_image **out_img) 1111bf215546Sopenharmony_ci{ 1112bf215546Sopenharmony_ci const VkExternalFormatANDROID *ext_info = 1113bf215546Sopenharmony_ci vk_find_struct_const(create_info->pNext, EXTERNAL_FORMAT_ANDROID); 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci VkImageCreateInfo local_info; 1116bf215546Sopenharmony_ci if (ext_info && ext_info->externalFormat) { 1117bf215546Sopenharmony_ci assert(create_info->format == VK_FORMAT_UNDEFINED); 1118bf215546Sopenharmony_ci assert(create_info->imageType == VK_IMAGE_TYPE_2D); 1119bf215546Sopenharmony_ci assert(create_info->usage == VK_IMAGE_USAGE_SAMPLED_BIT); 1120bf215546Sopenharmony_ci assert(create_info->tiling == VK_IMAGE_TILING_OPTIMAL); 1121bf215546Sopenharmony_ci assert(!(create_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)); 1122bf215546Sopenharmony_ci 1123bf215546Sopenharmony_ci local_info = *create_info; 1124bf215546Sopenharmony_ci local_info.format = 1125bf215546Sopenharmony_ci vn_android_drm_format_to_vk_format(ext_info->externalFormat); 1126bf215546Sopenharmony_ci create_info = &local_info; 1127bf215546Sopenharmony_ci } 1128bf215546Sopenharmony_ci 1129bf215546Sopenharmony_ci return vn_image_create_deferred(dev, create_info, alloc, out_img); 1130bf215546Sopenharmony_ci} 1131bf215546Sopenharmony_ci 1132bf215546Sopenharmony_ciVkResult 1133bf215546Sopenharmony_civn_android_device_import_ahb(struct vn_device *dev, 1134bf215546Sopenharmony_ci struct vn_device_memory *mem, 1135bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 1136bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 1137bf215546Sopenharmony_ci struct AHardwareBuffer *ahb, 1138bf215546Sopenharmony_ci bool internal_ahb) 1139bf215546Sopenharmony_ci{ 1140bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo *dedicated_info = 1141bf215546Sopenharmony_ci vk_find_struct_const(alloc_info->pNext, MEMORY_DEDICATED_ALLOCATE_INFO); 1142bf215546Sopenharmony_ci const native_handle_t *handle = NULL; 1143bf215546Sopenharmony_ci int dma_buf_fd = -1; 1144bf215546Sopenharmony_ci int dup_fd = -1; 1145bf215546Sopenharmony_ci uint64_t alloc_size = 0; 1146bf215546Sopenharmony_ci uint32_t mem_type_bits = 0; 1147bf215546Sopenharmony_ci uint32_t mem_type_index = alloc_info->memoryTypeIndex; 1148bf215546Sopenharmony_ci bool force_unmappable = false; 1149bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 1150bf215546Sopenharmony_ci 1151bf215546Sopenharmony_ci handle = AHardwareBuffer_getNativeHandle(ahb); 1152bf215546Sopenharmony_ci dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(handle); 1153bf215546Sopenharmony_ci if (dma_buf_fd < 0) 1154bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size, 1157bf215546Sopenharmony_ci &mem_type_bits); 1158bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1159bf215546Sopenharmony_ci return result; 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_ci /* If ahb is for an image, finish the deferred image creation first */ 1162bf215546Sopenharmony_ci if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) { 1163bf215546Sopenharmony_ci struct vn_image *img = vn_image_from_handle(dedicated_info->image); 1164bf215546Sopenharmony_ci struct vn_android_image_builder builder; 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci result = vn_android_get_image_builder(dev, &img->deferred_info->create, 1167bf215546Sopenharmony_ci handle, alloc, &builder); 1168bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1169bf215546Sopenharmony_ci return result; 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_ci result = vn_image_init_deferred(dev, &builder.create, img); 1172bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1173bf215546Sopenharmony_ci return result; 1174bf215546Sopenharmony_ci 1175bf215546Sopenharmony_ci const VkMemoryRequirements *mem_req = 1176bf215546Sopenharmony_ci &img->requirements[0].memory.memoryRequirements; 1177bf215546Sopenharmony_ci if (alloc_size < mem_req->size) { 1178bf215546Sopenharmony_ci vn_log(dev->instance, 1179bf215546Sopenharmony_ci "alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")", 1180bf215546Sopenharmony_ci alloc_size, mem_req->size); 1181bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1182bf215546Sopenharmony_ci } 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci alloc_size = mem_req->size; 1185bf215546Sopenharmony_ci 1186bf215546Sopenharmony_ci /* XXX Workaround before spec issue #2762 gets resolved. If importing an 1187bf215546Sopenharmony_ci * internally allocated AHB from the exportable path, memoryTypeIndex is 1188bf215546Sopenharmony_ci * undefined while defaulting to zero, which can be incompatible with 1189bf215546Sopenharmony_ci * the queried memoryTypeBits from the combined memory requirement and 1190bf215546Sopenharmony_ci * dma_buf fd properties. Thus we override the requested memoryTypeIndex 1191bf215546Sopenharmony_ci * to an applicable one if existed. 1192bf215546Sopenharmony_ci */ 1193bf215546Sopenharmony_ci if (internal_ahb) { 1194bf215546Sopenharmony_ci if ((mem_type_bits & mem_req->memoryTypeBits) == 0) { 1195bf215546Sopenharmony_ci vn_log(dev->instance, "memoryTypeBits: img(0x%X) fd(0x%X)", 1196bf215546Sopenharmony_ci mem_req->memoryTypeBits, mem_type_bits); 1197bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1198bf215546Sopenharmony_ci } 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci mem_type_index = ffs(mem_type_bits & mem_req->memoryTypeBits) - 1; 1201bf215546Sopenharmony_ci } 1202bf215546Sopenharmony_ci 1203bf215546Sopenharmony_ci /* XXX Workaround before we use cross-domain backend in minigbm. The 1204bf215546Sopenharmony_ci * blob_mem allocated from virgl backend can have a queried guest 1205bf215546Sopenharmony_ci * mappable size smaller than the size returned from image memory 1206bf215546Sopenharmony_ci * requirement. 1207bf215546Sopenharmony_ci */ 1208bf215546Sopenharmony_ci force_unmappable = true; 1209bf215546Sopenharmony_ci } 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci if (dedicated_info && dedicated_info->buffer != VK_NULL_HANDLE) { 1212bf215546Sopenharmony_ci struct vn_buffer *buf = vn_buffer_from_handle(dedicated_info->buffer); 1213bf215546Sopenharmony_ci const VkMemoryRequirements *mem_req = 1214bf215546Sopenharmony_ci &buf->requirements.memory.memoryRequirements; 1215bf215546Sopenharmony_ci if (alloc_size < mem_req->size) { 1216bf215546Sopenharmony_ci vn_log(dev->instance, 1217bf215546Sopenharmony_ci "alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")", 1218bf215546Sopenharmony_ci alloc_size, mem_req->size); 1219bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1220bf215546Sopenharmony_ci } 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci alloc_size = mem_req->size; 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci assert((1 << mem_type_index) & mem_req->memoryTypeBits); 1225bf215546Sopenharmony_ci } 1226bf215546Sopenharmony_ci 1227bf215546Sopenharmony_ci assert((1 << mem_type_index) & mem_type_bits); 1228bf215546Sopenharmony_ci 1229bf215546Sopenharmony_ci errno = 0; 1230bf215546Sopenharmony_ci dup_fd = os_dupfd_cloexec(dma_buf_fd); 1231bf215546Sopenharmony_ci if (dup_fd < 0) 1232bf215546Sopenharmony_ci return (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS 1233bf215546Sopenharmony_ci : VK_ERROR_OUT_OF_HOST_MEMORY; 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci /* Spec requires AHB export info to be present, so we must strip it. In 1236bf215546Sopenharmony_ci * practice, the AHB import path here only needs the main allocation info 1237bf215546Sopenharmony_ci * and the dedicated_info. 1238bf215546Sopenharmony_ci */ 1239bf215546Sopenharmony_ci VkMemoryDedicatedAllocateInfo local_dedicated_info; 1240bf215546Sopenharmony_ci /* Override when dedicated_info exists and is not the tail struct. */ 1241bf215546Sopenharmony_ci if (dedicated_info && dedicated_info->pNext) { 1242bf215546Sopenharmony_ci local_dedicated_info = *dedicated_info; 1243bf215546Sopenharmony_ci local_dedicated_info.pNext = NULL; 1244bf215546Sopenharmony_ci dedicated_info = &local_dedicated_info; 1245bf215546Sopenharmony_ci } 1246bf215546Sopenharmony_ci const VkMemoryAllocateInfo local_alloc_info = { 1247bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 1248bf215546Sopenharmony_ci .pNext = dedicated_info, 1249bf215546Sopenharmony_ci .allocationSize = alloc_size, 1250bf215546Sopenharmony_ci .memoryTypeIndex = mem_type_index, 1251bf215546Sopenharmony_ci }; 1252bf215546Sopenharmony_ci result = vn_device_memory_import_dma_buf(dev, mem, &local_alloc_info, 1253bf215546Sopenharmony_ci force_unmappable, dup_fd); 1254bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1255bf215546Sopenharmony_ci close(dup_fd); 1256bf215546Sopenharmony_ci return result; 1257bf215546Sopenharmony_ci } 1258bf215546Sopenharmony_ci 1259bf215546Sopenharmony_ci AHardwareBuffer_acquire(ahb); 1260bf215546Sopenharmony_ci mem->ahb = ahb; 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci return VK_SUCCESS; 1263bf215546Sopenharmony_ci} 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ciVkResult 1266bf215546Sopenharmony_civn_android_device_allocate_ahb(struct vn_device *dev, 1267bf215546Sopenharmony_ci struct vn_device_memory *mem, 1268bf215546Sopenharmony_ci const VkMemoryAllocateInfo *alloc_info, 1269bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 1270bf215546Sopenharmony_ci{ 1271bf215546Sopenharmony_ci const VkMemoryDedicatedAllocateInfo *dedicated_info = 1272bf215546Sopenharmony_ci vk_find_struct_const(alloc_info->pNext, MEMORY_DEDICATED_ALLOCATE_INFO); 1273bf215546Sopenharmony_ci uint32_t width = 0; 1274bf215546Sopenharmony_ci uint32_t height = 1; 1275bf215546Sopenharmony_ci uint32_t layers = 1; 1276bf215546Sopenharmony_ci uint32_t format = 0; 1277bf215546Sopenharmony_ci uint64_t usage = 0; 1278bf215546Sopenharmony_ci struct AHardwareBuffer *ahb = NULL; 1279bf215546Sopenharmony_ci 1280bf215546Sopenharmony_ci if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) { 1281bf215546Sopenharmony_ci const VkImageCreateInfo *image_info = 1282bf215546Sopenharmony_ci &vn_image_from_handle(dedicated_info->image)->deferred_info->create; 1283bf215546Sopenharmony_ci assert(image_info); 1284bf215546Sopenharmony_ci width = image_info->extent.width; 1285bf215546Sopenharmony_ci height = image_info->extent.height; 1286bf215546Sopenharmony_ci layers = image_info->arrayLayers; 1287bf215546Sopenharmony_ci format = vn_android_ahb_format_from_vk_format(image_info->format); 1288bf215546Sopenharmony_ci usage = vn_android_get_ahb_usage(image_info->usage, image_info->flags); 1289bf215546Sopenharmony_ci } else { 1290bf215546Sopenharmony_ci const VkPhysicalDeviceMemoryProperties *mem_props = 1291bf215546Sopenharmony_ci &dev->physical_device->memory_properties.memoryProperties; 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci assert(alloc_info->memoryTypeIndex < mem_props->memoryTypeCount); 1294bf215546Sopenharmony_ci 1295bf215546Sopenharmony_ci width = alloc_info->allocationSize; 1296bf215546Sopenharmony_ci format = AHARDWAREBUFFER_FORMAT_BLOB; 1297bf215546Sopenharmony_ci usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER; 1298bf215546Sopenharmony_ci if (mem_props->memoryTypes[alloc_info->memoryTypeIndex].propertyFlags & 1299bf215546Sopenharmony_ci VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { 1300bf215546Sopenharmony_ci usage |= AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | 1301bf215546Sopenharmony_ci AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY; 1302bf215546Sopenharmony_ci } 1303bf215546Sopenharmony_ci } 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_ci ahb = vn_android_ahb_allocate(width, height, layers, format, usage); 1306bf215546Sopenharmony_ci if (!ahb) 1307bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci VkResult result = 1310bf215546Sopenharmony_ci vn_android_device_import_ahb(dev, mem, alloc_info, alloc, ahb, true); 1311bf215546Sopenharmony_ci 1312bf215546Sopenharmony_ci /* ahb alloc has already acquired a ref and import will acquire another, 1313bf215546Sopenharmony_ci * must release one here to avoid leak. 1314bf215546Sopenharmony_ci */ 1315bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1316bf215546Sopenharmony_ci 1317bf215546Sopenharmony_ci return result; 1318bf215546Sopenharmony_ci} 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_civoid 1321bf215546Sopenharmony_civn_android_release_ahb(struct AHardwareBuffer *ahb) 1322bf215546Sopenharmony_ci{ 1323bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1324bf215546Sopenharmony_ci} 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ciVkResult 1327bf215546Sopenharmony_civn_GetMemoryAndroidHardwareBufferANDROID( 1328bf215546Sopenharmony_ci VkDevice device, 1329bf215546Sopenharmony_ci const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo, 1330bf215546Sopenharmony_ci struct AHardwareBuffer **pBuffer) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci struct vn_device_memory *mem = vn_device_memory_from_handle(pInfo->memory); 1333bf215546Sopenharmony_ci 1334bf215546Sopenharmony_ci AHardwareBuffer_acquire(mem->ahb); 1335bf215546Sopenharmony_ci *pBuffer = mem->ahb; 1336bf215546Sopenharmony_ci 1337bf215546Sopenharmony_ci return VK_SUCCESS; 1338bf215546Sopenharmony_ci} 1339bf215546Sopenharmony_ci 1340bf215546Sopenharmony_cistruct vn_android_buffer_create_info { 1341bf215546Sopenharmony_ci VkBufferCreateInfo create; 1342bf215546Sopenharmony_ci VkExternalMemoryBufferCreateInfo external; 1343bf215546Sopenharmony_ci VkBufferOpaqueCaptureAddressCreateInfo address; 1344bf215546Sopenharmony_ci}; 1345bf215546Sopenharmony_ci 1346bf215546Sopenharmony_cistatic const VkBufferCreateInfo * 1347bf215546Sopenharmony_civn_android_fix_buffer_create_info( 1348bf215546Sopenharmony_ci const VkBufferCreateInfo *create_info, 1349bf215546Sopenharmony_ci struct vn_android_buffer_create_info *local_info) 1350bf215546Sopenharmony_ci{ 1351bf215546Sopenharmony_ci local_info->create = *create_info; 1352bf215546Sopenharmony_ci VkBaseOutStructure *dst = (void *)&local_info->create; 1353bf215546Sopenharmony_ci 1354bf215546Sopenharmony_ci vk_foreach_struct_const(src, create_info->pNext) { 1355bf215546Sopenharmony_ci void *pnext = NULL; 1356bf215546Sopenharmony_ci switch (src->sType) { 1357bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO: 1358bf215546Sopenharmony_ci memcpy(&local_info->external, src, sizeof(local_info->external)); 1359bf215546Sopenharmony_ci local_info->external.handleTypes = 1360bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 1361bf215546Sopenharmony_ci pnext = &local_info->external; 1362bf215546Sopenharmony_ci break; 1363bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO: 1364bf215546Sopenharmony_ci memcpy(&local_info->address, src, sizeof(local_info->address)); 1365bf215546Sopenharmony_ci pnext = &local_info->address; 1366bf215546Sopenharmony_ci break; 1367bf215546Sopenharmony_ci default: 1368bf215546Sopenharmony_ci break; 1369bf215546Sopenharmony_ci } 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci if (pnext) { 1372bf215546Sopenharmony_ci dst->pNext = pnext; 1373bf215546Sopenharmony_ci dst = pnext; 1374bf215546Sopenharmony_ci } 1375bf215546Sopenharmony_ci } 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci dst->pNext = NULL; 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci return &local_info->create; 1380bf215546Sopenharmony_ci} 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ciVkResult 1383bf215546Sopenharmony_civn_android_get_ahb_buffer_memory_type_bits(struct vn_device *dev, 1384bf215546Sopenharmony_ci uint32_t *out_mem_type_bits) 1385bf215546Sopenharmony_ci{ 1386bf215546Sopenharmony_ci const uint32_t format = AHARDWAREBUFFER_FORMAT_BLOB; 1387bf215546Sopenharmony_ci /* ensure dma_buf_memory_type_bits covers host visible usage */ 1388bf215546Sopenharmony_ci const uint64_t usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER | 1389bf215546Sopenharmony_ci AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | 1390bf215546Sopenharmony_ci AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY; 1391bf215546Sopenharmony_ci AHardwareBuffer *ahb = NULL; 1392bf215546Sopenharmony_ci int dma_buf_fd = -1; 1393bf215546Sopenharmony_ci uint64_t alloc_size = 0; 1394bf215546Sopenharmony_ci uint32_t mem_type_bits = 0; 1395bf215546Sopenharmony_ci VkResult result; 1396bf215546Sopenharmony_ci 1397bf215546Sopenharmony_ci ahb = vn_android_ahb_allocate(4096, 1, 1, format, usage); 1398bf215546Sopenharmony_ci if (!ahb) 1399bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci dma_buf_fd = 1402bf215546Sopenharmony_ci vn_android_gralloc_get_dma_buf_fd(AHardwareBuffer_getNativeHandle(ahb)); 1403bf215546Sopenharmony_ci if (dma_buf_fd < 0) { 1404bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1405bf215546Sopenharmony_ci return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1406bf215546Sopenharmony_ci } 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size, 1409bf215546Sopenharmony_ci &mem_type_bits); 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci AHardwareBuffer_release(ahb); 1412bf215546Sopenharmony_ci 1413bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1414bf215546Sopenharmony_ci return result; 1415bf215546Sopenharmony_ci 1416bf215546Sopenharmony_ci *out_mem_type_bits = mem_type_bits; 1417bf215546Sopenharmony_ci 1418bf215546Sopenharmony_ci return VK_SUCCESS; 1419bf215546Sopenharmony_ci} 1420bf215546Sopenharmony_ci 1421bf215546Sopenharmony_ciVkResult 1422bf215546Sopenharmony_civn_android_buffer_from_ahb(struct vn_device *dev, 1423bf215546Sopenharmony_ci const VkBufferCreateInfo *create_info, 1424bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 1425bf215546Sopenharmony_ci struct vn_buffer **out_buf) 1426bf215546Sopenharmony_ci{ 1427bf215546Sopenharmony_ci struct vn_android_buffer_create_info local_info; 1428bf215546Sopenharmony_ci VkResult result; 1429bf215546Sopenharmony_ci 1430bf215546Sopenharmony_ci create_info = vn_android_fix_buffer_create_info(create_info, &local_info); 1431bf215546Sopenharmony_ci result = vn_buffer_create(dev, create_info, alloc, out_buf); 1432bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1433bf215546Sopenharmony_ci return result; 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci /* AHB backed buffer layers on top of dma_buf, so here we must comine the 1436bf215546Sopenharmony_ci * queried type bits from both buffer memory requirement and dma_buf fd 1437bf215546Sopenharmony_ci * properties. 1438bf215546Sopenharmony_ci */ 1439bf215546Sopenharmony_ci (*out_buf)->requirements.memory.memoryRequirements.memoryTypeBits &= 1440bf215546Sopenharmony_ci dev->buffer_cache.ahb_mem_type_bits; 1441bf215546Sopenharmony_ci 1442bf215546Sopenharmony_ci assert((*out_buf)->requirements.memory.memoryRequirements.memoryTypeBits); 1443bf215546Sopenharmony_ci 1444bf215546Sopenharmony_ci return VK_SUCCESS; 1445bf215546Sopenharmony_ci} 1446