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