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 <libsync.h>
26 #include <hardware/gralloc.h>
27 #include <hardware/hardware.h>
28 #include <hardware/hwvulkan.h>
29 #include <vulkan/vk_android_native_buffer.h>
30 #include <vulkan/vk_icd.h>
31
32 #if ANDROID_API_LEVEL >= 26
33 #include <hardware/gralloc1.h>
34 #endif
35 #endif
36
37 #include "util/os_file.h"
38
39 #include "radv_private.h"
40 #include "vk_util.h"
41
42 #ifdef ANDROID
43
44 static int radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev);
45 static int radv_hal_close(struct hw_device_t *dev);
46
47 static void UNUSED
static_asserts(void)48 static_asserts(void)
49 {
50 STATIC_ASSERT(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC);
51 }
52
53 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
54 .common =
55 {
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 =
63 &(hw_module_methods_t){
64 .open = radv_hal_open,
65 },
66 },
67 };
68
69 /* If any bits in test_mask are set, then unset them and return true. */
70 static inline bool
unmask32(uint32_t * inout_mask,uint32_t test_mask)71 unmask32(uint32_t *inout_mask, uint32_t test_mask)
72 {
73 uint32_t orig_mask = *inout_mask;
74 *inout_mask &= ~test_mask;
75 return *inout_mask != orig_mask;
76 }
77
78 static int
radv_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)79 radv_hal_open(const struct hw_module_t *mod, const char *id, 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 {
91 .tag = HARDWARE_DEVICE_TAG,
92 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
93 .module = &HAL_MODULE_INFO_SYM.common,
94 .close = radv_hal_close,
95 },
96 .EnumerateInstanceExtensionProperties = radv_EnumerateInstanceExtensionProperties,
97 .CreateInstance = radv_CreateInstance,
98 .GetInstanceProcAddr = radv_GetInstanceProcAddr,
99 };
100
101 *dev = &hal_dev->common;
102 return 0;
103 }
104
105 static int
radv_hal_close(struct hw_device_t * dev)106 radv_hal_close(struct hw_device_t *dev)
107 {
108 /* hwvulkan.h claims that hw_device_t::close() is never called. */
109 return -1;
110 }
111
112 VkResult
radv_image_from_gralloc(VkDevice device_h,const VkImageCreateInfo * base_info,const VkNativeBufferANDROID * gralloc_info,const VkAllocationCallbacks * alloc,VkImage * out_image_h)113 radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
114 const VkNativeBufferANDROID *gralloc_info,
115 const VkAllocationCallbacks *alloc, VkImage *out_image_h)
116
117 {
118 RADV_FROM_HANDLE(radv_device, device, device_h);
119 VkImage image_h = VK_NULL_HANDLE;
120 struct radv_image *image = NULL;
121 VkResult result;
122
123 if (gralloc_info->handle->numFds != 1) {
124 return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
125 "VkNativeBufferANDROID::handle::numFds is %d, "
126 "expected 1",
127 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 &
148 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, &memory_h);
168 if (result != VK_SUCCESS)
169 return result;
170
171 struct radeon_bo_metadata md;
172 device->ws->buffer_get_metadata(device->ws, 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, &image_h);
191
192 if (result != VK_SUCCESS)
193 goto fail_create_image;
194
195 image = radv_image_from_handle(image_h);
196
197 radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
198
199 VkBindImageMemoryInfo bind_info = {
200 .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
201 .image = image_h,
202 .memory = memory_h,
203 .memoryOffset = 0
204 };
205 radv_BindImageMemory2(device_h, 1, &bind_info);
206
207 image->owned_memory = memory_h;
208 /* Don't clobber the out-parameter until success is certain. */
209 *out_image_h = image_h;
210
211 return VK_SUCCESS;
212
213 fail_create_image:
214 radv_FreeMemory(device_h, memory_h, alloc);
215 return result;
216 }
217
218 VkResult
radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)219 radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format,
220 VkImageUsageFlags imageUsage, int *grallocUsage)
221 {
222 RADV_FROM_HANDLE(radv_device, device, device_h);
223 struct radv_physical_device *phys_dev = device->physical_device;
224 VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
225 VkResult result;
226
227 *grallocUsage = 0;
228
229 /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
230 * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
231 * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
232 *
233 * TODO(jessehall): I think these are right, but haven't thought hard
234 * about it. Do we need to query the driver for support of any of
235 * these?
236 *
237 * Any disagreement between this function and the hardcoded
238 * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
239 * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
240 */
241
242 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
243 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
244 .format = format,
245 .type = VK_IMAGE_TYPE_2D,
246 .tiling = VK_IMAGE_TILING_OPTIMAL,
247 .usage = imageUsage,
248 };
249
250 VkImageFormatProperties2 image_format_props = {
251 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
252 };
253
254 /* Check that requested format and usage are supported. */
255 result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
256 &image_format_props);
257 if (result != VK_SUCCESS) {
258 return vk_errorf(device, result,
259 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
260 "inside %s",
261 __func__);
262 }
263
264 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
265 *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
266
267 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
268 VK_IMAGE_USAGE_STORAGE_BIT | 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, VK_ERROR_FORMAT_NOT_SUPPORTED,
276 "unsupported VkImageUsageFlags(0x%x) for gralloc "
277 "swapchain",
278 imageUsage);
279 }
280
281 /*
282 * FINISHME: Advertise all display-supported formats. Mostly
283 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
284 * what we need for 30-bit colors.
285 */
286 if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
287 *grallocUsage |=
288 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
289 }
290
291 if (*grallocUsage == 0)
292 return VK_ERROR_FORMAT_NOT_SUPPORTED;
293
294 return VK_SUCCESS;
295 }
296
297 VkResult
radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)298 radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format,
299 VkImageUsageFlags imageUsage,
300 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
301 uint64_t *grallocConsumerUsage,
302 uint64_t *grallocProducerUsage)
303 {
304 /* Before level 26 (Android 8.0/Oreo) the loader uses
305 * vkGetSwapchainGrallocUsageANDROID. */
306 #if ANDROID_API_LEVEL >= 26
307 RADV_FROM_HANDLE(radv_device, device, device_h);
308 struct radv_physical_device *phys_dev = device->physical_device;
309 VkPhysicalDevice phys_dev_h = radv_physical_device_to_handle(phys_dev);
310 VkResult result;
311
312 *grallocConsumerUsage = 0;
313 *grallocProducerUsage = 0;
314
315 if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
316 return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
317 "The Vulkan loader tried to query shared presentable image support");
318
319 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
320 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
321 .format = format,
322 .type = VK_IMAGE_TYPE_2D,
323 .tiling = VK_IMAGE_TILING_OPTIMAL,
324 .usage = imageUsage,
325 };
326
327 VkImageFormatProperties2 image_format_props = {
328 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
329 };
330
331 /* Check that requested format and usage are supported. */
332 result = radv_GetPhysicalDeviceImageFormatProperties2(phys_dev_h, &image_format_info,
333 &image_format_props);
334 if (result != VK_SUCCESS) {
335 return vk_errorf(device, result,
336 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
337 "inside %s",
338 __func__);
339 }
340
341 if (unmask32(&imageUsage,
342 VK_IMAGE_USAGE_TRANSFER_DST_BIT | 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 | VK_IMAGE_USAGE_SAMPLED_BIT |
348 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
349 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
350 }
351
352 if (imageUsage != 0) {
353 return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
354 "unsupported VkImageUsageFlags(0x%x) for gralloc "
355 "swapchain",
356 imageUsage);
357 }
358
359 /*
360 * FINISHME: Advertise all display-supported formats. Mostly
361 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
362 * what we need for 30-bit colors.
363 */
364 if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
365 *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
366 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
367 }
368
369 if (!*grallocProducerUsage && !*grallocConsumerUsage)
370 return VK_ERROR_FORMAT_NOT_SUPPORTED;
371
372 return VK_SUCCESS;
373 #else
374 *grallocConsumerUsage = 0;
375 *grallocProducerUsage = 0;
376 return VK_ERROR_FORMAT_NOT_SUPPORTED;
377 #endif
378 }
379
380 VkResult
radv_AcquireImageANDROID(VkDevice device_h,VkImage image_h,int nativeFenceFd,VkSemaphore semaphore,VkFence fence)381 radv_AcquireImageANDROID(VkDevice device_h, VkImage image_h, int nativeFenceFd, VkSemaphore semaphore,
382 VkFence fence)
383 {
384 RADV_FROM_HANDLE(radv_device, device, device_h);
385 VkResult result = VK_SUCCESS;
386
387 /* From https://source.android.com/devices/graphics/implement-vulkan :
388 *
389 * "The driver takes ownership of the fence file descriptor and closes
390 * the fence file descriptor when no longer needed. The driver must do
391 * so even if neither a semaphore or fence object is provided, or even
392 * if vkAcquireImageANDROID fails and returns an error."
393 *
394 * The Vulkan spec for VkImportFence/SemaphoreFdKHR(), however, requires
395 * the file descriptor to be left alone on failure.
396 */
397 int semaphore_fd = -1, fence_fd = -1;
398 if (nativeFenceFd >= 0) {
399 if (semaphore != VK_NULL_HANDLE && fence != VK_NULL_HANDLE) {
400 /* We have both so we have to import the sync file twice. One of
401 * them needs to be a dup.
402 */
403 semaphore_fd = nativeFenceFd;
404 fence_fd = dup(nativeFenceFd);
405 if (fence_fd < 0) {
406 VkResult err = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS :
407 VK_ERROR_OUT_OF_HOST_MEMORY;
408 close(nativeFenceFd);
409 return vk_error(device, err);
410 }
411 } else if (semaphore != VK_NULL_HANDLE) {
412 semaphore_fd = nativeFenceFd;
413 } else if (fence != VK_NULL_HANDLE) {
414 fence_fd = nativeFenceFd;
415 } else {
416 /* Nothing to import into so we have to close the file */
417 close(nativeFenceFd);
418 }
419 }
420
421 if (semaphore != VK_NULL_HANDLE) {
422 const VkImportSemaphoreFdInfoKHR info = {
423 .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
424 .semaphore = semaphore,
425 .flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
426 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
427 .fd = semaphore_fd,
428 };
429 result = radv_ImportSemaphoreFdKHR(device_h, &info);
430 if (result == VK_SUCCESS)
431 semaphore_fd = -1; /* RADV took ownership */
432 }
433
434 if (result == VK_SUCCESS && fence != VK_NULL_HANDLE) {
435 const VkImportFenceFdInfoKHR info = {
436 .sType = VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
437 .fence = fence,
438 .flags = VK_FENCE_IMPORT_TEMPORARY_BIT,
439 .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
440 .fd = fence_fd,
441 };
442 result = radv_ImportFenceFdKHR(device_h, &info);
443 if (result == VK_SUCCESS)
444 fence_fd = -1; /* RADV took ownership */
445 }
446
447 if (semaphore_fd >= 0)
448 close(semaphore_fd);
449 if (fence_fd >= 0)
450 close(fence_fd);
451
452 return result;
453 }
454
455 VkResult
radv_QueueSignalReleaseImageANDROID(VkQueue _queue,uint32_t waitSemaphoreCount,const VkSemaphore * pWaitSemaphores,VkImage image,int * pNativeFenceFd)456 radv_QueueSignalReleaseImageANDROID(VkQueue _queue, uint32_t waitSemaphoreCount,
457 const VkSemaphore *pWaitSemaphores, VkImage image,
458 int *pNativeFenceFd)
459 {
460 RADV_FROM_HANDLE(radv_queue, queue, _queue);
461 VkResult result = VK_SUCCESS;
462
463 if (waitSemaphoreCount == 0) {
464 if (pNativeFenceFd)
465 *pNativeFenceFd = -1;
466 return VK_SUCCESS;
467 }
468
469 int fd = -1;
470
471 for (uint32_t i = 0; i < waitSemaphoreCount; ++i) {
472 int tmp_fd;
473 result =
474 radv_GetSemaphoreFdKHR(radv_device_to_handle(queue->device),
475 &(VkSemaphoreGetFdInfoKHR){
476 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
477 .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
478 .semaphore = pWaitSemaphores[i],
479 },
480 &tmp_fd);
481 if (result != VK_SUCCESS) {
482 if (fd >= 0)
483 close(fd);
484 return result;
485 }
486
487 if (fd < 0)
488 fd = tmp_fd;
489 else if (tmp_fd >= 0) {
490 sync_accumulate("radv", &fd, tmp_fd);
491 close(tmp_fd);
492 }
493 }
494
495 if (pNativeFenceFd) {
496 *pNativeFenceFd = fd;
497 } else if (fd >= 0) {
498 close(fd);
499 /* We still need to do the exports, to reset the semaphores, but
500 * otherwise we don't wait on them. */
501 }
502 return VK_SUCCESS;
503 }
504 #endif
505
506 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
507
508 enum {
509 /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
510 BUFFER_USAGE_CAMERA_MASK = 0x00060000U,
511 };
512
513 static inline VkFormat
vk_format_from_android(unsigned android_format,unsigned android_usage)514 vk_format_from_android(unsigned android_format, unsigned android_usage)
515 {
516 switch (android_format) {
517 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
518 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
519 return VK_FORMAT_R8G8B8A8_UNORM;
520 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
521 return VK_FORMAT_R8G8B8_UNORM;
522 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
523 return VK_FORMAT_R5G6B5_UNORM_PACK16;
524 case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
525 return VK_FORMAT_R16G16B16A16_SFLOAT;
526 case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
527 return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
528 case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
529 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
530 case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
531 if (android_usage & BUFFER_USAGE_CAMERA_MASK)
532 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
533 else
534 return VK_FORMAT_R8G8B8_UNORM;
535 case AHARDWAREBUFFER_FORMAT_BLOB:
536 default:
537 return VK_FORMAT_UNDEFINED;
538 }
539 }
540
541 static inline unsigned
android_format_from_vk(unsigned vk_format)542 android_format_from_vk(unsigned vk_format)
543 {
544 switch (vk_format) {
545 case VK_FORMAT_R8G8B8A8_UNORM:
546 return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
547 case VK_FORMAT_R8G8B8_UNORM:
548 return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
549 case VK_FORMAT_R5G6B5_UNORM_PACK16:
550 return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
551 case VK_FORMAT_R16G16B16A16_SFLOAT:
552 return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
553 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
554 return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
555 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
556 return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
557 default:
558 return AHARDWAREBUFFER_FORMAT_BLOB;
559 }
560 }
561
562 uint64_t
radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create,const VkImageUsageFlags vk_usage)563 radv_ahb_usage_from_vk_usage(const VkImageCreateFlags vk_create, const VkImageUsageFlags vk_usage)
564 {
565 uint64_t ahb_usage = 0;
566 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
567 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
568
569 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
570 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
571
572 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
573 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
574
575 if (vk_create & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
576 ahb_usage |= AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
577
578 if (vk_create & VK_IMAGE_CREATE_PROTECTED_BIT)
579 ahb_usage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
580
581 /* No usage bits set - set at least one GPU usage. */
582 if (ahb_usage == 0)
583 ahb_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
584 return ahb_usage;
585 }
586
587 static VkResult
get_ahb_buffer_format_properties(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatPropertiesANDROID * pProperties)588 get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer *buffer,
589 VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
590 {
591 RADV_FROM_HANDLE(radv_device, device, device_h);
592
593 /* Get a description of buffer contents . */
594 AHardwareBuffer_Desc desc;
595 AHardwareBuffer_describe(buffer, &desc);
596
597 /* Verify description. */
598 const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
599 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
600 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
601
602 /* "Buffer must be a valid Android hardware buffer object with at least
603 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
604 */
605 if (!(desc.usage & (gpu_usage)))
606 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
607
608 /* Fill properties fields based on description. */
609 VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
610
611 p->format = vk_format_from_android(desc.format, desc.usage);
612 p->externalFormat = (uint64_t)(uintptr_t)p->format;
613
614 VkFormatProperties2 format_properties = {
615 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
616 };
617
618 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
619 p->format, &format_properties);
620
621 if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
622 p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
623 else
624 p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
625
626 /* "Images can be created with an external format even if the Android hardware
627 * buffer has a format which has an equivalent Vulkan format to enable
628 * consistent handling of images from sources that might use either category
629 * of format. However, all images created with an external format are subject
630 * to the valid usage requirements associated with external formats, even if
631 * the Android hardware buffer’s format has a Vulkan equivalent."
632 *
633 * "The formatFeatures member *must* include
634 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
635 * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
636 * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
637 */
638 assert(p->formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
639
640 p->formatFeatures |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
641
642 /* "Implementations may not always be able to determine the color model,
643 * numerical range, or chroma offsets of the image contents, so the values
644 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
645 * Applications should treat these values as sensible defaults to use in
646 * the absence of more reliable information obtained through some other
647 * means."
648 */
649 p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
650 p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
651 p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
652 p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
653
654 p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
655 p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
656
657 p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
658 p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
659
660 return VK_SUCCESS;
661 }
662
663 static VkResult
get_ahb_buffer_format_properties2(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatProperties2ANDROID * pProperties)664 get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
665 VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
666 {
667 RADV_FROM_HANDLE(radv_device, device, device_h);
668
669 /* Get a description of buffer contents . */
670 AHardwareBuffer_Desc desc;
671 AHardwareBuffer_describe(buffer, &desc);
672
673 /* Verify description. */
674 const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
675 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
676 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
677
678 /* "Buffer must be a valid Android hardware buffer object with at least
679 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
680 */
681 if (!(desc.usage & (gpu_usage)))
682 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
683
684 /* Fill properties fields based on description. */
685 VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
686
687 p->format = vk_format_from_android(desc.format, desc.usage);
688 p->externalFormat = (uint64_t)(uintptr_t)p->format;
689
690 VkFormatProperties2 format_properties = {
691 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2
692 };
693
694 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(device->physical_device),
695 p->format, &format_properties);
696
697 if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
698 p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
699 else
700 p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
701
702 /* "Images can be created with an external format even if the Android hardware
703 * buffer has a format which has an equivalent Vulkan format to enable
704 * consistent handling of images from sources that might use either category
705 * of format. However, all images created with an external format are subject
706 * to the valid usage requirements associated with external formats, even if
707 * the Android hardware buffer’s format has a Vulkan equivalent."
708 *
709 * "The formatFeatures member *must* include
710 * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR and at least one of
711 * VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR or
712 * VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR"
713 */
714 assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR);
715
716 p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
717
718 /* "Implementations may not always be able to determine the color model,
719 * numerical range, or chroma offsets of the image contents, so the values
720 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
721 * Applications should treat these values as sensible defaults to use in
722 * the absence of more reliable information obtained through some other
723 * means."
724 */
725 p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
726 p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
727 p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
728 p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
729
730 p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
731 p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
732
733 p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
734 p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
735
736 return VK_SUCCESS;
737 }
738
739 VkResult
radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)740 radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,
741 const struct AHardwareBuffer *buffer,
742 VkAndroidHardwareBufferPropertiesANDROID *pProperties)
743 {
744 RADV_FROM_HANDLE(radv_device, dev, device_h);
745 struct radv_physical_device *pdevice = dev->physical_device;
746
747 VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
748 vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
749
750 /* Fill format properties of an Android hardware buffer. */
751 if (format_prop)
752 get_ahb_buffer_format_properties(device_h, buffer, format_prop);
753
754 VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
755 vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
756 if (format_prop2)
757 get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
758
759 /* NOTE - We support buffers with only one handle but do not error on
760 * multiple handle case. Reason is that we want to support YUV formats
761 * where we have many logical planes but they all point to the same
762 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
763 */
764 const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
765 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
766 if (dma_buf < 0)
767 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
768
769 /* All memory types. */
770 uint32_t memory_types = (1u << pdevice->memory_properties.memoryTypeCount) - 1;
771
772 pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
773 pProperties->memoryTypeBits = memory_types;
774
775 return VK_SUCCESS;
776 }
777
778 VkResult
radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,const VkMemoryGetAndroidHardwareBufferInfoANDROID * pInfo,struct AHardwareBuffer ** pBuffer)779 radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,
780 const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
781 struct AHardwareBuffer **pBuffer)
782 {
783 RADV_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
784
785 /* This should always be set due to the export handle types being set on
786 * allocation. */
787 assert(mem->android_hardware_buffer);
788
789 /* Some quotes from Vulkan spec:
790 *
791 * "If the device memory was created by importing an Android hardware
792 * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
793 * Android hardware buffer object."
794 *
795 * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
796 * have been included in VkExportMemoryAllocateInfo::handleTypes when
797 * memory was created."
798 */
799 *pBuffer = mem->android_hardware_buffer;
800 /* Increase refcount. */
801 AHardwareBuffer_acquire(mem->android_hardware_buffer);
802 return VK_SUCCESS;
803 }
804
805 #endif
806
807 VkFormat
radv_select_android_external_format(const void * next,VkFormat default_format)808 radv_select_android_external_format(const void *next, VkFormat default_format)
809 {
810 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
811 const VkExternalFormatANDROID *android_format =
812 vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
813
814 if (android_format && android_format->externalFormat) {
815 return (VkFormat)android_format->externalFormat;
816 }
817 #endif
818
819 return default_format;
820 }
821
822 VkResult
radv_import_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkImportAndroidHardwareBufferInfoANDROID * info)823 radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
824 unsigned priority, const VkImportAndroidHardwareBufferInfoANDROID *info)
825 {
826 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
827 /* Import from AHardwareBuffer to radv_device_memory. */
828 const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
829
830 /* NOTE - We support buffers with only one handle but do not error on
831 * multiple handle case. Reason is that we want to support YUV formats
832 * where we have many logical planes but they all point to the same
833 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
834 */
835 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
836 if (dma_buf < 0)
837 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
838
839 uint64_t alloc_size = 0;
840 VkResult result =
841 device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
842 if (result != VK_SUCCESS)
843 return result;
844
845 if (mem->image) {
846 struct radeon_bo_metadata metadata;
847 device->ws->buffer_get_metadata(device->ws, mem->bo, &metadata);
848
849 struct radv_image_create_info create_info = {.no_metadata_planes = true,
850 .bo_metadata = &metadata};
851
852 VkResult result = radv_image_create_layout(device, create_info, NULL, mem->image);
853 if (result != VK_SUCCESS) {
854 device->ws->buffer_destroy(device->ws, mem->bo);
855 mem->bo = NULL;
856 return result;
857 }
858
859 if (alloc_size < mem->image->size) {
860 device->ws->buffer_destroy(device->ws, mem->bo);
861 mem->bo = NULL;
862 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
863 }
864 } else if (mem->buffer) {
865 if (alloc_size < mem->buffer->size) {
866 device->ws->buffer_destroy(device->ws, mem->bo);
867 mem->bo = NULL;
868 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
869 }
870 }
871
872 /* "If the vkAllocateMemory command succeeds, the implementation must
873 * acquire a reference to the imported hardware buffer, which it must
874 * release when the device memory object is freed. If the command fails,
875 * the implementation must not retain a reference."
876 */
877 AHardwareBuffer_acquire(info->buffer);
878 mem->android_hardware_buffer = info->buffer;
879
880 return VK_SUCCESS;
881 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
882 return VK_ERROR_EXTENSION_NOT_PRESENT;
883 #endif
884 }
885
886 VkResult
radv_create_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkMemoryAllocateInfo * pAllocateInfo)887 radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem,
888 unsigned priority, const VkMemoryAllocateInfo *pAllocateInfo)
889 {
890 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
891 const VkMemoryDedicatedAllocateInfo *dedicated_info =
892 vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
893
894 uint32_t w = 0;
895 uint32_t h = 1;
896 uint32_t layers = 1;
897 uint32_t format = 0;
898 uint64_t usage = 0;
899
900 /* If caller passed dedicated information. */
901 if (dedicated_info && dedicated_info->image) {
902 RADV_FROM_HANDLE(radv_image, image, dedicated_info->image);
903 w = image->info.width;
904 h = image->info.height;
905 layers = image->info.array_size;
906 format = android_format_from_vk(image->vk_format);
907 usage = radv_ahb_usage_from_vk_usage(image->flags, image->usage);
908 } else if (dedicated_info && dedicated_info->buffer) {
909 RADV_FROM_HANDLE(radv_buffer, buffer, dedicated_info->buffer);
910 w = buffer->size;
911 format = AHARDWAREBUFFER_FORMAT_BLOB;
912 usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
913 } else {
914 w = pAllocateInfo->allocationSize;
915 format = AHARDWAREBUFFER_FORMAT_BLOB;
916 usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
917 }
918
919 struct AHardwareBuffer *android_hardware_buffer = NULL;
920 struct AHardwareBuffer_Desc desc = {
921 .width = w,
922 .height = h,
923 .layers = layers,
924 .format = format,
925 .usage = usage,
926 };
927
928 if (AHardwareBuffer_allocate(&desc, &android_hardware_buffer) != 0)
929 return VK_ERROR_OUT_OF_HOST_MEMORY;
930
931 mem->android_hardware_buffer = android_hardware_buffer;
932
933 const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
934 .buffer = mem->android_hardware_buffer,
935 };
936
937 VkResult result = radv_import_ahb_memory(device, mem, priority, &import_info);
938
939 /* Release a reference to avoid leak for AHB allocation. */
940 AHardwareBuffer_release(mem->android_hardware_buffer);
941
942 return result;
943 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
944 return VK_ERROR_EXTENSION_NOT_PRESENT;
945 #endif
946 }
947
948 bool
radv_android_gralloc_supports_format(VkFormat format,VkImageUsageFlagBits usage)949 radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage)
950 {
951 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
952 /* Ideally we check Gralloc for what it supports and then merge that with the radv
953 format support, but there is no easy gralloc query besides just creating an image.
954 That seems a bit on the expensive side, so just hardcode for now. */
955 /* TODO: Add multi-plane formats after confirming everything works between radeonsi
956 and radv. */
957 switch (format) {
958 case VK_FORMAT_R8G8B8A8_UNORM:
959 case VK_FORMAT_R5G6B5_UNORM_PACK16:
960 return true;
961 case VK_FORMAT_R8_UNORM:
962 case VK_FORMAT_R8G8_UNORM:
963 return !(usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
964 default:
965 return false;
966 }
967 #else
968 (void)format;
969 (void)usage;
970 return false;
971 #endif
972 }
973