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