• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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