radv: Set handle types in Android semaphore/fence import.
[mesa.git] / src / amd / vulkan / radv_android.c
1 /*
2 * Copyright © 2017, Google Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifdef ANDROID
25 #include <hardware/gralloc.h>
26 #include <hardware/hardware.h>
27 #include <hardware/hwvulkan.h>
28 #include <vndk/hardware_buffer.h>
29 #include <vulkan/vk_android_native_buffer.h>
30 #include <vulkan/vk_icd.h>
31 #include <libsync.h>
32
33 #if ANDROID_API_LEVEL >= 26
34 #include <hardware/gralloc1.h>
35 #endif
36 #endif
37
38 #include "util/os_file.h"
39
40 #include "radv_private.h"
41 #include "vk_util.h"
42
43 #ifdef ANDROID
44
45 static int radv_hal_open(const struct hw_module_t* mod, const char* id, struct hw_device_t** dev);
46 static int radv_hal_close(struct hw_device_t *dev);
47
48 static void UNUSED
49 static_asserts(void)
50 {
51 STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC);
52 }
53
54 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
55 .common = {
56 .tag = HARDWARE_MODULE_TAG,
57 .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
58 .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
59 .id = HWVULKAN_HARDWARE_MODULE_ID,
60 .name = "AMD Vulkan HAL",
61 .author = "Google",
62 .methods = &(hw_module_methods_t) {
63 .open = radv_hal_open,
64 },
65 },
66 };
67
68 /* If any bits in test_mask are set, then unset them and return true. */
69 static inline bool
70 unmask32(uint32_t *inout_mask, uint32_t test_mask)
71 {
72 uint32_t orig_mask = *inout_mask;
73 *inout_mask &= ~test_mask;
74 return *inout_mask != orig_mask;
75 }
76
77 static int
78 radv_hal_open(const struct hw_module_t* mod, const char* id,
79 struct hw_device_t** dev)
80 {
81 assert(mod == &HAL_MODULE_INFO_SYM.common);
82 assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
83
84 hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
85 if (!hal_dev)
86 return -1;
87
88 *hal_dev = (hwvulkan_device_t) {
89 .common = {
90 .tag = HARDWARE_DEVICE_TAG,
91 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
92 .module = &HAL_MODULE_INFO_SYM.common,
93 .close = radv_hal_close,
94 },
95 .EnumerateInstanceExtensionProperties = radv_EnumerateInstanceExtensionProperties,
96 .CreateInstance = radv_CreateInstance,
97 .GetInstanceProcAddr = radv_GetInstanceProcAddr,
98 };
99
100 *dev = &hal_dev->common;
101 return 0;
102 }
103
104 static int
105 radv_hal_close(struct hw_device_t *dev)
106 {
107 /* hwvulkan.h claims that hw_device_t::close() is never called. */
108 return -1;
109 }
110
111 VkResult
112 radv_image_from_gralloc(VkDevice device_h,
113 const VkImageCreateInfo *base_info,
114 const VkNativeBufferANDROID *gralloc_info,
115 const VkAllocationCallbacks *alloc,
116 VkImage *out_image_h)
117
118 {
119 RADV_FROM_HANDLE(radv_device, device, device_h);
120 VkImage image_h = VK_NULL_HANDLE;
121 struct radv_image *image = NULL;
122 struct radv_bo *bo = NULL;
123 VkResult result;
124
125 if (gralloc_info->handle->numFds != 1) {
126 return vk_errorf(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE,
127 "VkNativeBufferANDROID::handle::numFds is %d, "
128 "expected 1", gralloc_info->handle->numFds);
129 }
130
131 /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
132 * must exceed that of the gralloc handle, and we do not own the gralloc
133 * handle.
134 */
135 int dma_buf = gralloc_info->handle->data[0];
136
137 VkDeviceMemory memory_h;
138
139 const VkImportMemoryFdInfoKHR import_info = {
140 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
141 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
142 .fd = os_dupfd_cloexec(dma_buf),
143 };
144
145 /* Find the first VRAM memory type, or GART for PRIME images. */
146 int memory_type_index = -1;
147 for (int i = 0; i < device->physical_device->memory_properties.memoryTypeCount; ++i) {
148 bool is_local = !!(device->physical_device->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
149 if (is_local) {
150 memory_type_index = i;
151 break;
152 }
153 }
154
155 /* fallback */
156 if (memory_type_index == -1)
157 memory_type_index = 0;
158
159 result = radv_AllocateMemory(device_h,
160 &(VkMemoryAllocateInfo) {
161 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
162 .pNext = &import_info,
163 /* Max buffer size, unused for imports */
164 .allocationSize = 0x7FFFFFFF,
165 .memoryTypeIndex = memory_type_index,
166 },
167 alloc,
168 &memory_h);
169 if (result != VK_SUCCESS)
170 return result;
171
172 struct radeon_bo_metadata md;
173 device->ws->buffer_get_metadata(radv_device_memory_from_handle(memory_h)->bo, &md);
174
175 VkImageCreateInfo updated_base_info = *base_info;
176
177 VkExternalMemoryImageCreateInfo external_memory_info = {
178 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
179 .pNext = updated_base_info.pNext,
180 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
181 };
182
183 updated_base_info.pNext = &external_memory_info;
184
185 result = radv_image_create(device_h,
186 &(struct radv_image_create_info) {
187 .vk_info = &updated_base_info,
188 .no_metadata_planes = true,
189 .bo_metadata = &md,
190 },
191 alloc,
192 &image_h);
193
194 if (result != VK_SUCCESS)
195 goto fail_create_image;
196
197 image = radv_image_from_handle(image_h);
198
199 radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
200
201 radv_BindImageMemory(device_h, image_h, memory_h, 0);
202
203 image->owned_memory = memory_h;
204 /* Don't clobber the out-parameter until success is certain. */
205 *out_image_h = image_h;
206
207 return VK_SUCCESS;
208
209 fail_create_image:
210 radv_FreeMemory(device_h, memory_h, alloc);
211 return result;
212 }
213
214 VkResult radv_GetSwapchainGrallocUsageANDROID(
215 VkDevice device_h,
216 VkFormat format,
217 VkImageUsageFlags imageUsage,
218 int* grallocUsage)
219 {
220 RADV_FROM_HANDLE(radv_device, device, device_h);
221 struct radv_physical_device *phys_dev = device->physical_device;
222 VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
223 VkResult result;
224
225 *grallocUsage = 0;
226
227 /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
228 * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
229 * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
230 *
231 * TODO(jessehall): I think these are right, but haven't thought hard
232 * about it. Do we need to query the driver for support of any of
233 * these?
234 *
235 * Any disagreement between this function and the hardcoded
236 * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
237 * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
238 */
239
240 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
241 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
242 .format = format,
243 .type = VK_IMAGE_TYPE_2D,
244 .tiling = VK_IMAGE_TILING_OPTIMAL,
245 .usage = imageUsage,
246 };
247
248 VkImageFormatProperties2 image_format_props = {
249 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
250 };
251
252 /* Check that requested format and usage are supported. */
253 result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h,
254 &image_format_info, &image_format_props);
255 if (result != VK_SUCCESS) {
256 return vk_errorf(device->instance, result,
257 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
258 "inside %s", __func__);
259 }
260
261 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT |
262 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
263 *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
264
265 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
266 VK_IMAGE_USAGE_SAMPLED_BIT |
267 VK_IMAGE_USAGE_STORAGE_BIT |
268 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
269 *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
270
271 /* All VkImageUsageFlags not explicitly checked here are unsupported for
272 * gralloc swapchains.
273 */
274 if (imageUsage != 0) {
275 return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
276 "unsupported VkImageUsageFlags(0x%x) for gralloc "
277 "swapchain", imageUsage);
278 }
279
280 /*
281 * FINISHME: Advertise all display-supported formats. Mostly
282 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
283 * what we need for 30-bit colors.
284 */
285 if (format == VK_FORMAT_B8G8R8A8_UNORM ||
286 format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
287 *grallocUsage |= GRALLOC_USAGE_HW_FB |
288 GRALLOC_USAGE_HW_COMPOSER |
289 GRALLOC_USAGE_EXTERNAL_DISP;
290 }
291
292 if (*grallocUsage == 0)
293 return VK_ERROR_FORMAT_NOT_SUPPORTED;
294
295 return VK_SUCCESS;
296 }
297
298 VkResult radv_GetSwapchainGrallocUsage2ANDROID(
299 VkDevice device_h,
300 VkFormat format,
301 VkImageUsageFlags imageUsage,
302 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
303 uint64_t* grallocConsumerUsage,
304 uint64_t* grallocProducerUsage)
305 {
306 /* Before level 26 (Android 8.0/Oreo) the loader uses
307 * vkGetSwapchainGrallocUsageANDROID. */
308 #if ANDROID_API_LEVEL >= 26
309 RADV_FROM_HANDLE(radv_device, device, device_h);
310 struct radv_physical_device *phys_dev = device->physical_device;
311 VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
312 VkResult result;
313
314 *grallocConsumerUsage = 0;
315 *grallocProducerUsage = 0;
316
317 if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
318 return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
319 "The Vulkan loader tried to query shared presentable image support");
320
321 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
322 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
323 .format = format,
324 .type = VK_IMAGE_TYPE_2D,
325 .tiling = VK_IMAGE_TILING_OPTIMAL,
326 .usage = imageUsage,
327 };
328
329 VkImageFormatProperties2 image_format_props = {
330 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
331 };
332
333 /* Check that requested format and usage are supported. */
334 result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h,
335 &image_format_info, &image_format_props);
336 if (result != VK_SUCCESS) {
337 return vk_errorf(device->instance, result,
338 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
339 "inside %s", __func__);
340 }
341
342 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT |
343 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
344 *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
345 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
346 }
347
348 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
349 VK_IMAGE_USAGE_SAMPLED_BIT |
350 VK_IMAGE_USAGE_STORAGE_BIT |
351 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
352 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
353 }
354
355 if (imageUsage != 0) {
356 return vk_errorf(device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
357 "unsupported VkImageUsageFlags(0x%x) for gralloc "
358 "swapchain", imageUsage);
359 }
360
361 /*
362 * FINISHME: Advertise all display-supported formats. Mostly
363 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
364 * what we need for 30-bit colors.
365 */
366 if (format == VK_FORMAT_B8G8R8A8_UNORM ||
367 format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
368 *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
369 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
370 }
371
372 if (!*grallocProducerUsage && !*grallocConsumerUsage)
373 return VK_ERROR_FORMAT_NOT_SUPPORTED;
374
375 return VK_SUCCESS;
376 #else
377 *grallocConsumerUsage = 0;
378 *grallocProducerUsage = 0;
379 return VK_ERROR_FORMAT_NOT_SUPPORTED;
380 #endif
381 }
382
383 VkResult
384 radv_AcquireImageANDROID(
385 VkDevice device,
386 VkImage image_h,
387 int nativeFenceFd,
388 VkSemaphore semaphore,
389 VkFence fence)
390 {
391 VkResult semaphore_result = VK_SUCCESS, fence_result = VK_SUCCESS;
392
393 if (semaphore != VK_NULL_HANDLE) {
394 int semaphore_fd = nativeFenceFd >= 0 ? os_dupfd_cloexec(nativeFenceFd) : nativeFenceFd;
395 semaphore_result = radv_ImportSemaphoreFdKHR(device,
396 &(VkImportSemaphoreFdInfoKHR) {
397 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
398 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
399 .fd = semaphore_fd,
400 .semaphore = semaphore,
401 .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
402 });
403 }
404
405 if (fence != VK_NULL_HANDLE) {
406 int fence_fd = nativeFenceFd >= 0 ? os_dupfd_cloexec(nativeFenceFd) : nativeFenceFd;
407 fence_result = radv_ImportFenceFdKHR(device,
408 &(VkImportFenceFdInfoKHR) {
409 .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
410 .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
411 .fd = fence_fd,
412 .fence = fence,
413 .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
414 });
415 }
416
417 close(nativeFenceFd);
418
419 if (semaphore_result != VK_SUCCESS)
420 return semaphore_result;
421 return fence_result;
422 }
423
424 VkResult
425 radv_QueueSignalReleaseImageANDROID(
426 VkQueue _queue,
427 uint32_t waitSemaphoreCount,
428 const VkSemaphore* pWaitSemaphores,
429 VkImage image,
430 int* pNativeFenceFd)
431 {
432 RADV_FROM_HANDLE(radv_queue, queue, _queue);
433 VkResult result = VK_SUCCESS;
434
435 if (waitSemaphoreCount == 0) {
436 if (pNativeFenceFd)
437 *pNativeFenceFd = -1;
438 return VK_SUCCESS;
439 }
440
441 int fd = -1;
442
443 for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
444 int tmp_fd;
445 result = radv_GetSemaphoreFdKHR(radv_device_to_handle(queue->device),
446 &(VkSemaphoreGetFdInfoKHR) {
447 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
448 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
449 .semaphore = pWaitSemaphores[i],
450 }, &tmp_fd);
451 if (result != VK_SUCCESS) {
452 if (fd >= 0)
453 close (fd);
454 return result;
455 }
456
457 if (fd < 0)
458 fd = tmp_fd;
459 else if (tmp_fd >= 0) {
460 sync_accumulate("radv", &fd, tmp_fd);
461 close(tmp_fd);
462 }
463 }
464
465 if (pNativeFenceFd) {
466 *pNativeFenceFd = fd;
467 } else if (fd >= 0) {
468 close(fd);
469 /* We still need to do the exports, to reset the semaphores, but
470 * otherwise we don't wait on them. */
471 }
472 return VK_SUCCESS;
473 }
474 #endif
475
476 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
477
478 enum {
479 /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
480 AHARDWAREBUFFER_USAGE_CAMERA_MASK = 0x00060000U,
481 };
482
483 static inline VkFormat
484 vk_format_from_android(unsigned android_format, unsigned android_usage)
485 {
486 switch (android_format) {
487 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
488 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
489 return VK_FORMAT_R8G8B8A8_UNORM;
490 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
491 return VK_FORMAT_R8G8B8_UNORM;
492 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
493 return VK_FORMAT_R5G6B5_UNORM_PACK16;
494 case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
495 return VK_FORMAT_R16G16B16A16_SFLOAT;
496 case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
497 return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
498 case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
499 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
500 case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
501 if (android_usage & AHARDWAREBUFFER_USAGE_CAMERA_MASK)
502 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
503 else
504 return VK_FORMAT_R8G8B8_UNORM;
505 case AHARDWAREBUFFER_FORMAT_BLOB:
506 default:
507 return VK_FORMAT_UNDEFINED;
508 }
509 }
510
511 static inline unsigned
512 android_format_from_vk(unsigned vk_format)
513 {
514 switch (vk_format) {
515 case VK_FORMAT_R8G8B8A8_UNORM:
516 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
517 case VK_FORMAT_R8G8B8_UNORM:
518 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
519 case VK_FORMAT_R5G6B5_UNORM_PACK16:
520 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
521 case VK_FORMAT_R16G16B16A16_SFLOAT:
522 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
523 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
524 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
525 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
526 return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
527 default:
528 return AHARDWAREBUFFER_FORMAT_BLOB;
529 }
530 }
531
532 uint64_t
533 radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create,
534 const VkImageUsageFlags vk_usage)
535 {
536 uint64_t ahb_usage = 0;
537 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
538 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
539
540 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
541 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
542
543 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
544 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
545
546 if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
547 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
548
549 if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
550 ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
551
552 /* No usage bits set - set at least one GPU usage. */
553 if (ahb_usage == 0)
554 ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
555 return ahb_usage;
556 }
557
558 static VkResult
559 get_ahb_buffer_format_properties(
560 VkDevice device_h,
561 const struct AHardwareBuffer *buffer,
562 VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
563 {
564 RADV_FROM_HANDLE(radv_device, device, device_h);
565
566 /* Get a description of buffer contents . */
567 AHardwareBuffer_Desc desc;
568 AHardwareBuffer_describe(buffer, &desc);
569
570 /* Verify description. */
571 const uint64_t gpu_usage =
572 AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
573 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
574 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
575
576 /* "Buffer must be a valid Android hardware buffer object with at least
577 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
578 */
579 if (!(desc.usage & (gpu_usage)))
580 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
581
582 /* Fill properties fields based on description. */
583 VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
584
585 p->format = vk_format_from_android(desc.format, desc.usage);
586 p->externalFormat = (uint64_t) (uintptr_t) p->format;
587
588 VkFormatProperties format_properties;
589 radv_GetPhysicalDeviceFormatProperties(
590 radv_physical_device_to_handle(device->physical_device),
591 p->format, &format_properties);
592
593 if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
594 p->formatFeatures = format_properties.linearTilingFeatures;
595 else
596 p->formatFeatures = format_properties.optimalTilingFeatures;
597
598 /* "Images can be created with an external format even if the Android hardware
599 * buffer has a format which has an equivalent Vulkan format to enable
600 * consistent handling of images from sources that might use either category
601 * of format. However, all images created with an external format are subject
602 * to the valid usage requirements associated with external formats, even if
603 * the Android hardware buffer’s format has a Vulkan equivalent."
604 *
605 * "The formatFeatures member *must* include
606 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
607 * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
608 * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
609 */
610 assert(p->formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
611
612 p->formatFeatures |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
613
614 /* "Implementations may not always be able to determine the color model,
615 * numerical range, or chroma offsets of the image contents, so the values
616 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
617 * Applications should treat these values as sensible defaults to use in
618 * the absence of more reliable information obtained through some other
619 * means."
620 */
621 p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
622 p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
623 p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
624 p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
625
626 p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
627 p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
628
629 p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
630 p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
631
632 return VK_SUCCESS;
633 }
634
635 VkResult
636 radv_GetAndroidHardwareBufferPropertiesANDROID(
637 VkDevice device_h,
638 const struct AHardwareBuffer *buffer,
639 VkAndroidHardwareBufferPropertiesANDROID *pProperties)
640 {
641 RADV_FROM_HANDLE(radv_device, dev, device_h);
642 struct radv_physical_device *pdevice = dev->physical_device;
643
644 VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
645 vk_find_struct(pProperties->pNext,
646 ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
647
648 /* Fill format properties of an Android hardware buffer. */
649 if (format_prop)
650 get_ahb_buffer_format_properties(device_h, buffer, format_prop);
651
652 /* NOTE - We support buffers with only one handle but do not error on
653 * multiple handle case. Reason is that we want to support YUV formats
654 * where we have many logical planes but they all point to the same
655 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
656 */
657 const native_handle_t *handle =
658 AHardwareBuffer_getNativeHandle(buffer);
659 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
660 if (dma_buf < 0)
661 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
662
663 /* All memory types. */
664 uint32_t memory_types = (1u << pdevice->memory_properties.memoryTypeCount) - 1;
665
666 pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
667 pProperties->memoryTypeBits = memory_types;
668
669 return VK_SUCCESS;
670 }
671
672 VkResult
673 radv_GetMemoryAndroidHardwareBufferANDROID(
674 VkDevice device_h,
675 const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
676 struct AHardwareBuffer **pBuffer)
677 {
678 RADV_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
679
680 /* This should always be set due to the export handle types being set on
681 * allocation. */
682 assert(mem->android_hardware_buffer);
683
684 /* Some quotes from Vulkan spec:
685 *
686 * "If the device memory was created by importing an Android hardware
687 * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
688 * Android hardware buffer object."
689 *
690 * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
691 * have been included in VkExportMemoryAllocateInfo::handleTypes when
692 * memory was created."
693 */
694 *pBuffer = mem->android_hardware_buffer;
695 /* Increase refcount. */
696 AHardwareBuffer_acquire(mem->android_hardware_buffer);
697 return VK_SUCCESS;
698 }
699
700 #endif
701
702 VkFormat
703 radv_select_android_external_format(const void *next, VkFormat default_format)
704 {
705 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
706 const VkExternalFormatANDROID *android_format =
707 vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
708
709 if (android_format && android_format->externalFormat) {
710 return (VkFormat)android_format->externalFormat;
711 }
712 #endif
713
714 return default_format;
715 }
716
717
718 VkResult
719 radv_import_ahb_memory(struct radv_device *device,
720 struct radv_device_memory *mem,
721 unsigned priority,
722 const VkImportAndroidHardwareBufferInfoANDROID *info)
723 {
724 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
725 /* Import from AHardwareBuffer to radv_device_memory. */
726 const native_handle_t *handle =
727 AHardwareBuffer_getNativeHandle(info->buffer);
728
729 /* NOTE - We support buffers with only one handle but do not error on
730 * multiple handle case. Reason is that we want to support YUV formats
731 * where we have many logical planes but they all point to the same
732 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
733 */
734 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
735 if (dma_buf < 0)
736 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
737
738 uint64_t alloc_size = 0;
739 mem->bo = device->ws->buffer_from_fd(device->ws, dma_buf,
740 priority, &alloc_size);
741 if (!mem->bo)
742 return VK_ERROR_OUT_OF_HOST_MEMORY;
743
744 if (mem->image) {
745 struct radeon_bo_metadata metadata;
746 device->ws->buffer_get_metadata(mem->bo, &metadata);
747
748 struct radv_image_create_info create_info = {
749 .no_metadata_planes = true,
750 .bo_metadata = &metadata
751 };
752
753 VkResult result = radv_image_create_layout(device, create_info, mem->image);
754 if (result != VK_SUCCESS) {
755 device->ws->buffer_destroy(mem->bo);
756 mem->bo = NULL;
757 return result;
758 }
759
760 if (alloc_size < mem->image->size) {
761 device->ws->buffer_destroy(mem->bo);
762 mem->bo = NULL;
763 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
764 }
765 } else if (mem->buffer) {
766 if (alloc_size < mem->buffer->size) {
767 device->ws->buffer_destroy(mem->bo);
768 mem->bo = NULL;
769 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
770 }
771 }
772
773 /* "If the vkAllocateMemory command succeeds, the implementation must
774 * acquire a reference to the imported hardware buffer, which it must
775 * release when the device memory object is freed. If the command fails,
776 * the implementation must not retain a reference."
777 */
778 AHardwareBuffer_acquire(info->buffer);
779 mem->android_hardware_buffer = info->buffer;
780
781 return VK_SUCCESS;
782 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
783 return VK_ERROR_EXTENSION_NOT_PRESENT;
784 #endif
785 }
786
787 VkResult
788 radv_create_ahb_memory(struct radv_device *device,
789 struct radv_device_memory *mem,
790 unsigned priority,
791 const VkMemoryAllocateInfo *pAllocateInfo)
792 {
793 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
794 const VkMemoryDedicatedAllocateInfo *dedicated_info =
795 vk_find_struct_const(pAllocateInfo->pNext,
796 MEMORY_DEDICATED_ALLOCATE_INFO);
797
798 uint32_t w = 0;
799 uint32_t h = 1;
800 uint32_t layers = 1;
801 uint32_t format = 0;
802 uint64_t usage = 0;
803
804 /* If caller passed dedicated information. */
805 if (dedicated_info && dedicated_info->image) {
806 RADV_FROM_HANDLE(radv_image, image, dedicated_info->image);
807 w = image->info.width;
808 h = image->info.height;
809 layers = image->info.array_size;
810 format = android_format_from_vk(image->vk_format);
811 usage = radv_ahb_usage_from_vk_usage(image->flags, image->usage);
812 } else if (dedicated_info && dedicated_info->buffer) {
813 RADV_FROM_HANDLE(radv_buffer, buffer, dedicated_info->buffer);
814 w = buffer->size;
815 format = AHARDWAREBUFFER_FORMAT_BLOB;
816 usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
817 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
818 } else {
819 w = pAllocateInfo->allocationSize;
820 format = AHARDWAREBUFFER_FORMAT_BLOB;
821 usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
822 AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
823 }
824
825 struct AHardwareBuffer *android_hardware_buffer = NULL;
826 struct AHardwareBuffer_Desc desc = {
827 .width = w,
828 .height = h,
829 .layers = layers,
830 .format = format,
831 .usage = usage,
832 };
833
834 if (AHardwareBuffer_allocate(&desc, &android_hardware_buffer) != 0)
835 return VK_ERROR_OUT_OF_HOST_MEMORY;
836
837 mem->android_hardware_buffer = android_hardware_buffer;
838
839 const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
840 .buffer = mem->android_hardware_buffer,
841 };
842
843 VkResult result = radv_import_ahb_memory(device, mem, priority, &import_info);
844 if (result != VK_SUCCESS)
845 AHardwareBuffer_release(mem->android_hardware_buffer);
846 return result;
847 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
848 return VK_ERROR_EXTENSION_NOT_PRESENT;
849 #endif
850 }
851
852 bool radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage) {
853 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
854 /* Ideally we check Gralloc for what it supports and then merge that with the radv
855 format support, but there is no easy gralloc query besides just creating an image.
856 That seems a bit on the expensive side, so just hardcode for now. */
857 /* TODO: Add multi-plane formats after confirming everything works between radeonsi
858 and radv. */
859 switch(format) {
860 case VK_FORMAT_R8G8B8A8_UNORM:
861 case VK_FORMAT_R5G6B5_UNORM_PACK16:
862 return true;
863 case VK_FORMAT_R8_UNORM:
864 case VK_FORMAT_R8G8_UNORM:
865 return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
866 default:
867 return false;
868 }
869 #else
870 (void)format;
871 (void)usage;
872 return false;
873 #endif
874 }