1 /*
2 * Copyright © 2017, Google Inc.
3 *
4 * SPDX-License-Identifier: MIT
5 */
6
7 #include "radv_android.h"
8 #include "radv_buffer.h"
9 #include "radv_device.h"
10 #include "radv_device_memory.h"
11 #include "radv_entrypoints.h"
12 #include "radv_image.h"
13 #include "radv_physical_device.h"
14
15 #if DETECT_OS_ANDROID
16 #include <libsync.h>
17 #include <hardware/gralloc.h>
18 #include <hardware/hardware.h>
19 #include <hardware/hwvulkan.h>
20 #include <vulkan/vk_android_native_buffer.h>
21 #include <vulkan/vk_icd.h>
22
23 #if ANDROID_API_LEVEL >= 26
24 #include <hardware/gralloc1.h>
25 #endif
26 #endif /* DETECT_OS_ANDROID */
27
28 #include "util/os_file.h"
29
30 #include "vk_android.h"
31 #include "vk_log.h"
32 #include "vk_util.h"
33
34 #if DETECT_OS_ANDROID
35
36 static int radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev);
37 static int radv_hal_close(struct hw_device_t *dev);
38
39 static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
40
41 PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
42 .common =
43 {
44 .tag = HARDWARE_MODULE_TAG,
45 .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
46 .hal_api_version = HARDWARE_MAKE_API_VERSION(1, 0),
47 .id = HWVULKAN_HARDWARE_MODULE_ID,
48 .name = "AMD Vulkan HAL",
49 .author = "Google",
50 .methods =
51 &(hw_module_methods_t){
52 .open = radv_hal_open,
53 },
54 },
55 };
56
57 /* If any bits in test_mask are set, then unset them and return true. */
58 static inline bool
unmask32(uint32_t * inout_mask,uint32_t test_mask)59 unmask32(uint32_t *inout_mask, uint32_t test_mask)
60 {
61 uint32_t orig_mask = *inout_mask;
62 *inout_mask &= ~test_mask;
63 return *inout_mask != orig_mask;
64 }
65
66 static int
radv_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)67 radv_hal_open(const struct hw_module_t *mod, const char *id, struct hw_device_t **dev)
68 {
69 assert(mod == &HAL_MODULE_INFO_SYM.common);
70 assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
71
72 hwvulkan_device_t *hal_dev = malloc(sizeof(*hal_dev));
73 if (!hal_dev)
74 return -1;
75
76 *hal_dev = (hwvulkan_device_t){
77 .common =
78 {
79 .tag = HARDWARE_DEVICE_TAG,
80 .version = HWVULKAN_DEVICE_API_VERSION_0_1,
81 .module = &HAL_MODULE_INFO_SYM.common,
82 .close = radv_hal_close,
83 },
84 .EnumerateInstanceExtensionProperties = radv_EnumerateInstanceExtensionProperties,
85 .CreateInstance = radv_CreateInstance,
86 .GetInstanceProcAddr = radv_GetInstanceProcAddr,
87 };
88
89 *dev = &hal_dev->common;
90 return 0;
91 }
92
93 static int
radv_hal_close(struct hw_device_t * dev)94 radv_hal_close(struct hw_device_t *dev)
95 {
96 /* hwvulkan.h claims that hw_device_t::close() is never called. */
97 return -1;
98 }
99
100 VkResult
radv_image_from_gralloc(VkDevice device_h,const VkImageCreateInfo * base_info,const VkNativeBufferANDROID * gralloc_info,const VkAllocationCallbacks * alloc,VkImage * out_image_h)101 radv_image_from_gralloc(VkDevice device_h, const VkImageCreateInfo *base_info,
102 const VkNativeBufferANDROID *gralloc_info, const VkAllocationCallbacks *alloc,
103 VkImage *out_image_h)
104
105 {
106 VK_FROM_HANDLE(radv_device, device, device_h);
107 const struct radv_physical_device *pdev = radv_device_physical(device);
108 VkImage image_h = VK_NULL_HANDLE;
109 struct radv_image *image = NULL;
110 VkResult result;
111
112 if (gralloc_info->handle->numFds != 1) {
113 return vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
114 "VkNativeBufferANDROID::handle::numFds is %d, "
115 "expected 1",
116 gralloc_info->handle->numFds);
117 }
118
119 /* Do not close the gralloc handle's dma_buf. The lifetime of the dma_buf
120 * must exceed that of the gralloc handle, and we do not own the gralloc
121 * handle.
122 */
123 int dma_buf = gralloc_info->handle->data[0];
124
125 VkDeviceMemory memory_h;
126
127 const VkImportMemoryFdInfoKHR import_info = {
128 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
129 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT,
130 .fd = os_dupfd_cloexec(dma_buf),
131 };
132
133 /* Find the first VRAM memory type, or GART for PRIME images. */
134 int memory_type_index = -1;
135 for (int i = 0; i < pdev->memory_properties.memoryTypeCount; ++i) {
136 bool is_local = !!(pdev->memory_properties.memoryTypes[i].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
137 bool is_32bit = !!(pdev->memory_types_32bit & (1u << i));
138 if (is_local && !is_32bit) {
139 memory_type_index = i;
140 break;
141 }
142 }
143
144 /* fallback */
145 if (memory_type_index == -1)
146 memory_type_index = 0;
147
148 result = radv_AllocateMemory(device_h,
149 &(VkMemoryAllocateInfo){
150 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
151 .pNext = &import_info,
152 /* Max buffer size, unused for imports */
153 .allocationSize = 0x7FFFFFFF,
154 .memoryTypeIndex = memory_type_index,
155 },
156 alloc, &memory_h);
157 if (result != VK_SUCCESS)
158 return result;
159
160 struct radeon_bo_metadata md;
161 device->ws->buffer_get_metadata(device->ws, radv_device_memory_from_handle(memory_h)->bo, &md);
162
163 VkImageCreateInfo updated_base_info = *base_info;
164
165 VkExternalMemoryImageCreateInfo external_memory_info = {
166 .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
167 .pNext = updated_base_info.pNext,
168 .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
169 };
170
171 updated_base_info.pNext = &external_memory_info;
172
173 result = radv_image_create(device_h,
174 &(struct radv_image_create_info){
175 .vk_info = &updated_base_info,
176 .no_metadata_planes = true,
177 .bo_metadata = &md,
178 },
179 alloc, &image_h, false);
180
181 if (result != VK_SUCCESS)
182 goto fail_create_image;
183
184 image = radv_image_from_handle(image_h);
185
186 radv_image_override_offset_stride(device, image, 0, gralloc_info->stride);
187
188 VkBindImageMemoryInfo bind_info = {.sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
189 .image = image_h,
190 .memory = memory_h,
191 .memoryOffset = 0};
192 radv_BindImageMemory2(device_h, 1, &bind_info);
193
194 image->owned_memory = memory_h;
195 /* Don't clobber the out-parameter until success is certain. */
196 *out_image_h = image_h;
197
198 return VK_SUCCESS;
199
200 fail_create_image:
201 radv_FreeMemory(device_h, memory_h, alloc);
202 return result;
203 }
204
205 VkResult
radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,int * grallocUsage)206 radv_GetSwapchainGrallocUsageANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
207 int *grallocUsage)
208 {
209 VK_FROM_HANDLE(radv_device, device, device_h);
210 struct radv_physical_device *pdev = radv_device_physical(device);
211 VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
212 VkResult result;
213
214 *grallocUsage = 0;
215
216 /* WARNING: Android Nougat's libvulkan.so hardcodes the VkImageUsageFlags
217 * returned to applications via VkSurfaceCapabilitiesKHR::supportedUsageFlags.
218 * The relevant code in libvulkan/swapchain.cpp contains this fun comment:
219 *
220 * TODO(jessehall): I think these are right, but haven't thought hard
221 * about it. Do we need to query the driver for support of any of
222 * these?
223 *
224 * Any disagreement between this function and the hardcoded
225 * VkSurfaceCapabilitiesKHR:supportedUsageFlags causes tests
226 * dEQP-VK.wsi.android.swapchain.*.image_usage to fail.
227 */
228
229 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
230 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
231 .format = format,
232 .type = VK_IMAGE_TYPE_2D,
233 .tiling = VK_IMAGE_TILING_OPTIMAL,
234 .usage = imageUsage,
235 };
236
237 VkImageFormatProperties2 image_format_props = {
238 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
239 };
240
241 /* Check that requested format and usage are supported. */
242 result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
243 if (result != VK_SUCCESS) {
244 return vk_errorf(device, result,
245 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
246 "inside %s",
247 __func__);
248 }
249
250 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
251 *grallocUsage |= GRALLOC_USAGE_HW_RENDER;
252
253 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
254 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
255 *grallocUsage |= GRALLOC_USAGE_HW_TEXTURE;
256
257 /* All VkImageUsageFlags not explicitly checked here are unsupported for
258 * gralloc swapchains.
259 */
260 if (imageUsage != 0) {
261 return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
262 "unsupported VkImageUsageFlags(0x%x) for gralloc "
263 "swapchain",
264 imageUsage);
265 }
266
267 /*
268 * FINISHME: Advertise all display-supported formats. Mostly
269 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
270 * what we need for 30-bit colors.
271 */
272 if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
273 *grallocUsage |= GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP;
274 }
275
276 if (*grallocUsage == 0)
277 return VK_ERROR_FORMAT_NOT_SUPPORTED;
278
279 return VK_SUCCESS;
280 }
281
282 VkResult
radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)283 radv_GetSwapchainGrallocUsage2ANDROID(VkDevice device_h, VkFormat format, VkImageUsageFlags imageUsage,
284 VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
285 uint64_t *grallocConsumerUsage, uint64_t *grallocProducerUsage)
286 {
287 /* Before level 26 (Android 8.0/Oreo) the loader uses
288 * vkGetSwapchainGrallocUsageANDROID. */
289 #if ANDROID_API_LEVEL >= 26
290 VK_FROM_HANDLE(radv_device, device, device_h);
291 struct radv_physical_device *pdev = radv_device_physical(device);
292 VkPhysicalDevice pdev_h = radv_physical_device_to_handle(pdev);
293 VkResult result;
294
295 *grallocConsumerUsage = 0;
296 *grallocProducerUsage = 0;
297
298 if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
299 return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
300 "The Vulkan loader tried to query shared presentable image support");
301
302 const VkPhysicalDeviceImageFormatInfo2 image_format_info = {
303 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
304 .format = format,
305 .type = VK_IMAGE_TYPE_2D,
306 .tiling = VK_IMAGE_TILING_OPTIMAL,
307 .usage = imageUsage,
308 };
309
310 VkImageFormatProperties2 image_format_props = {
311 .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
312 };
313
314 /* Check that requested format and usage are supported. */
315 result = radv_GetPhysicalDeviceImageFormatProperties2(pdev_h, &image_format_info, &image_format_props);
316 if (result != VK_SUCCESS) {
317 return vk_errorf(device, result,
318 "radv_GetPhysicalDeviceImageFormatProperties2 failed "
319 "inside %s",
320 __func__);
321 }
322
323 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) {
324 *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
325 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET;
326 }
327
328 if (unmask32(&imageUsage, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
329 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
330 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
331 }
332
333 if (imageUsage != 0) {
334 return vk_errorf(device, VK_ERROR_FORMAT_NOT_SUPPORTED,
335 "unsupported VkImageUsageFlags(0x%x) for gralloc "
336 "swapchain",
337 imageUsage);
338 }
339
340 /*
341 * FINISHME: Advertise all display-supported formats. Mostly
342 * DRM_FORMAT_ARGB2101010 and DRM_FORMAT_ABGR2101010, but need to check
343 * what we need for 30-bit colors.
344 */
345 if (format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B5G6R5_UNORM_PACK16) {
346 *grallocProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
347 *grallocConsumerUsage |= GRALLOC1_CONSUMER_USAGE_HWCOMPOSER;
348 }
349
350 if (!*grallocProducerUsage && !*grallocConsumerUsage)
351 return VK_ERROR_FORMAT_NOT_SUPPORTED;
352
353 return VK_SUCCESS;
354 #else
355 *grallocConsumerUsage = 0;
356 *grallocProducerUsage = 0;
357 return VK_ERROR_FORMAT_NOT_SUPPORTED;
358 #endif
359 }
360 #endif /* DETECT_OS_ANDROID */
361
362 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
363
364 enum {
365 /* Usage bit equal to GRALLOC_USAGE_HW_CAMERA_MASK */
366 BUFFER_USAGE_CAMERA_MASK = 0x00060000U,
367 };
368
369 static inline VkFormat
vk_format_from_android(unsigned android_format,unsigned android_usage)370 vk_format_from_android(unsigned android_format, unsigned android_usage)
371 {
372 switch (android_format) {
373 case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
374 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
375 case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
376 if (android_usage & BUFFER_USAGE_CAMERA_MASK)
377 return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
378 else
379 return VK_FORMAT_R8G8B8_UNORM;
380 default:
381 return vk_ahb_format_to_image_format(android_format);
382 }
383 }
384
385 unsigned
radv_ahb_format_for_vk_format(VkFormat vk_format)386 radv_ahb_format_for_vk_format(VkFormat vk_format)
387 {
388 switch (vk_format) {
389 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
390 return AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420;
391 default:
392 return vk_image_format_to_ahb_format(vk_format);
393 }
394 }
395
396 static VkResult
get_ahb_buffer_format_properties(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatPropertiesANDROID * pProperties)397 get_ahb_buffer_format_properties(VkDevice device_h, const struct AHardwareBuffer *buffer,
398 VkAndroidHardwareBufferFormatPropertiesANDROID *pProperties)
399 {
400 VK_FROM_HANDLE(radv_device, device, device_h);
401 struct radv_physical_device *pdev = radv_device_physical(device);
402
403 /* Get a description of buffer contents . */
404 AHardwareBuffer_Desc desc;
405 AHardwareBuffer_describe(buffer, &desc);
406
407 /* Verify description. */
408 const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
409 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
410
411 /* "Buffer must be a valid Android hardware buffer object with at least
412 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
413 */
414 if (!(desc.usage & (gpu_usage)))
415 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
416
417 /* Fill properties fields based on description. */
418 VkAndroidHardwareBufferFormatPropertiesANDROID *p = pProperties;
419
420 p->format = vk_format_from_android(desc.format, desc.usage);
421 p->externalFormat = (uint64_t)(uintptr_t)p->format;
422
423 VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
424
425 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
426
427 if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
428 p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
429 else
430 p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
431
432 /* "Images can be created with an external format even if the Android hardware
433 * buffer has a format which has an equivalent Vulkan format to enable
434 * consistent handling of images from sources that might use either category
435 * of format. However, all images created with an external format are subject
436 * to the valid usage requirements associated with external formats, even if
437 * the Android hardware buffer’s format has a Vulkan equivalent."
438 *
439 * "The formatFeatures member *must* include
440 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT and at least one of
441 * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
442 * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT"
443 */
444 assert(p->formatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
445
446 p->formatFeatures |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
447
448 /* "Implementations may not always be able to determine the color model,
449 * numerical range, or chroma offsets of the image contents, so the values
450 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
451 * Applications should treat these values as sensible defaults to use in
452 * the absence of more reliable information obtained through some other
453 * means."
454 */
455 p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
456 p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
457 p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
458 p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
459
460 p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
461 p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
462
463 p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
464 p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
465
466 return VK_SUCCESS;
467 }
468
469 static VkResult
get_ahb_buffer_format_properties2(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferFormatProperties2ANDROID * pProperties)470 get_ahb_buffer_format_properties2(VkDevice device_h, const struct AHardwareBuffer *buffer,
471 VkAndroidHardwareBufferFormatProperties2ANDROID *pProperties)
472 {
473 VK_FROM_HANDLE(radv_device, device, device_h);
474 struct radv_physical_device *pdev = radv_device_physical(device);
475
476 /* Get a description of buffer contents . */
477 AHardwareBuffer_Desc desc;
478 AHardwareBuffer_describe(buffer, &desc);
479
480 /* Verify description. */
481 const uint64_t gpu_usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
482 AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER;
483
484 /* "Buffer must be a valid Android hardware buffer object with at least
485 * one of the AHARDWAREBUFFER_USAGE_GPU_* usage flags."
486 */
487 if (!(desc.usage & (gpu_usage)))
488 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
489
490 /* Fill properties fields based on description. */
491 VkAndroidHardwareBufferFormatProperties2ANDROID *p = pProperties;
492
493 p->format = vk_format_from_android(desc.format, desc.usage);
494 p->externalFormat = (uint64_t)(uintptr_t)p->format;
495
496 VkFormatProperties2 format_properties = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2};
497
498 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(pdev), p->format, &format_properties);
499
500 if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
501 p->formatFeatures = format_properties.formatProperties.linearTilingFeatures;
502 else
503 p->formatFeatures = format_properties.formatProperties.optimalTilingFeatures;
504
505 /* "Images can be created with an external format even if the Android hardware
506 * buffer has a format which has an equivalent Vulkan format to enable
507 * consistent handling of images from sources that might use either category
508 * of format. However, all images created with an external format are subject
509 * to the valid usage requirements associated with external formats, even if
510 * the Android hardware buffer’s format has a Vulkan equivalent."
511 *
512 * "The formatFeatures member *must* include
513 * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT and at least one of
514 * VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT or
515 * VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT"
516 */
517 assert(p->formatFeatures & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT);
518
519 p->formatFeatures |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
520
521 /* "Implementations may not always be able to determine the color model,
522 * numerical range, or chroma offsets of the image contents, so the values
523 * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
524 * Applications should treat these values as sensible defaults to use in
525 * the absence of more reliable information obtained through some other
526 * means."
527 */
528 p->samplerYcbcrConversionComponents.r = VK_COMPONENT_SWIZZLE_IDENTITY;
529 p->samplerYcbcrConversionComponents.g = VK_COMPONENT_SWIZZLE_IDENTITY;
530 p->samplerYcbcrConversionComponents.b = VK_COMPONENT_SWIZZLE_IDENTITY;
531 p->samplerYcbcrConversionComponents.a = VK_COMPONENT_SWIZZLE_IDENTITY;
532
533 p->suggestedYcbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601;
534 p->suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
535
536 p->suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
537 p->suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT;
538
539 return VK_SUCCESS;
540 }
541
542 VkResult
radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)543 radv_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device_h, const struct AHardwareBuffer *buffer,
544 VkAndroidHardwareBufferPropertiesANDROID *pProperties)
545 {
546 VK_FROM_HANDLE(radv_device, dev, device_h);
547 struct radv_physical_device *pdev = radv_device_physical(dev);
548
549 VkAndroidHardwareBufferFormatPropertiesANDROID *format_prop =
550 vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
551
552 /* Fill format properties of an Android hardware buffer. */
553 if (format_prop)
554 get_ahb_buffer_format_properties(device_h, buffer, format_prop);
555
556 VkAndroidHardwareBufferFormatProperties2ANDROID *format_prop2 =
557 vk_find_struct(pProperties->pNext, ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
558 if (format_prop2)
559 get_ahb_buffer_format_properties2(device_h, buffer, format_prop2);
560
561 /* NOTE - We support buffers with only one handle but do not error on
562 * multiple handle case. Reason is that we want to support YUV formats
563 * where we have many logical planes but they all point to the same
564 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
565 */
566 const native_handle_t *handle = AHardwareBuffer_getNativeHandle(buffer);
567 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
568 if (dma_buf < 0)
569 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
570
571 /* All memory types. */
572 uint32_t memory_types = (1u << pdev->memory_properties.memoryTypeCount) - 1;
573
574 pProperties->allocationSize = lseek(dma_buf, 0, SEEK_END);
575 pProperties->memoryTypeBits = memory_types & ~pdev->memory_types_32bit;
576
577 return VK_SUCCESS;
578 }
579
580 VkResult
radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h,const VkMemoryGetAndroidHardwareBufferInfoANDROID * pInfo,struct AHardwareBuffer ** pBuffer)581 radv_GetMemoryAndroidHardwareBufferANDROID(VkDevice device_h, const VkMemoryGetAndroidHardwareBufferInfoANDROID *pInfo,
582 struct AHardwareBuffer **pBuffer)
583 {
584 VK_FROM_HANDLE(radv_device_memory, mem, pInfo->memory);
585
586 /* This should always be set due to the export handle types being set on
587 * allocation. */
588 assert(mem->android_hardware_buffer);
589
590 /* Some quotes from Vulkan spec:
591 *
592 * "If the device memory was created by importing an Android hardware
593 * buffer, vkGetMemoryAndroidHardwareBufferANDROID must return that same
594 * Android hardware buffer object."
595 *
596 * "VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID must
597 * have been included in VkExportMemoryAllocateInfo::handleTypes when
598 * memory was created."
599 */
600 *pBuffer = mem->android_hardware_buffer;
601 /* Increase refcount. */
602 AHardwareBuffer_acquire(mem->android_hardware_buffer);
603 return VK_SUCCESS;
604 }
605
606 #endif
607
608 VkFormat
radv_select_android_external_format(const void * next,VkFormat default_format)609 radv_select_android_external_format(const void *next, VkFormat default_format)
610 {
611 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
612 const VkExternalFormatANDROID *android_format = vk_find_struct_const(next, EXTERNAL_FORMAT_ANDROID);
613
614 if (android_format && android_format->externalFormat) {
615 return (VkFormat)android_format->externalFormat;
616 }
617 #endif
618
619 return default_format;
620 }
621
622 VkResult
radv_import_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkImportAndroidHardwareBufferInfoANDROID * info)623 radv_import_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
624 const VkImportAndroidHardwareBufferInfoANDROID *info)
625 {
626 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
627 /* Import from AHardwareBuffer to radv_device_memory. */
628 const native_handle_t *handle = AHardwareBuffer_getNativeHandle(info->buffer);
629
630 /* NOTE - We support buffers with only one handle but do not error on
631 * multiple handle case. Reason is that we want to support YUV formats
632 * where we have many logical planes but they all point to the same
633 * buffer, like is the case with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.
634 */
635 int dma_buf = (handle && handle->numFds) ? handle->data[0] : -1;
636 if (dma_buf < 0)
637 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
638
639 uint64_t alloc_size = 0;
640 VkResult result = device->ws->buffer_from_fd(device->ws, dma_buf, priority, &mem->bo, &alloc_size);
641 if (result != VK_SUCCESS)
642 return result;
643
644 if (mem->image) {
645 struct radeon_bo_metadata metadata;
646 device->ws->buffer_get_metadata(device->ws, mem->bo, &metadata);
647
648 struct radv_image_create_info create_info = {.no_metadata_planes = true, .bo_metadata = &metadata};
649
650 result = radv_image_create_layout(device, create_info, NULL, NULL, mem->image);
651 if (result != VK_SUCCESS) {
652 radv_bo_destroy(device, NULL, mem->bo);
653 mem->bo = NULL;
654 return result;
655 }
656
657 if (alloc_size < mem->image->size) {
658 radv_bo_destroy(device, NULL, mem->bo);
659 mem->bo = NULL;
660 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
661 }
662 } else if (mem->buffer) {
663 if (alloc_size < mem->buffer->vk.size) {
664 radv_bo_destroy(device, NULL, mem->bo);
665 mem->bo = NULL;
666 return VK_ERROR_INVALID_EXTERNAL_HANDLE;
667 }
668 }
669
670 /* "If the vkAllocateMemory command succeeds, the implementation must
671 * acquire a reference to the imported hardware buffer, which it must
672 * release when the device memory object is freed. If the command fails,
673 * the implementation must not retain a reference."
674 */
675 AHardwareBuffer_acquire(info->buffer);
676 mem->android_hardware_buffer = info->buffer;
677
678 return VK_SUCCESS;
679 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
680 return VK_ERROR_EXTENSION_NOT_PRESENT;
681 #endif
682 }
683
684 VkResult
radv_create_ahb_memory(struct radv_device * device,struct radv_device_memory * mem,unsigned priority,const VkMemoryAllocateInfo * pAllocateInfo)685 radv_create_ahb_memory(struct radv_device *device, struct radv_device_memory *mem, unsigned priority,
686 const VkMemoryAllocateInfo *pAllocateInfo)
687 {
688 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
689 mem->android_hardware_buffer = vk_alloc_ahardware_buffer(pAllocateInfo);
690 if (mem->android_hardware_buffer == NULL)
691 return VK_ERROR_OUT_OF_HOST_MEMORY;
692
693 const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
694 .buffer = mem->android_hardware_buffer,
695 };
696
697 VkResult result = radv_import_ahb_memory(device, mem, priority, &import_info);
698
699 /* Release a reference to avoid leak for AHB allocation. */
700 AHardwareBuffer_release(mem->android_hardware_buffer);
701
702 return result;
703 #else /* RADV_SUPPORT_ANDROID_HARDWARE_BUFFER */
704 return VK_ERROR_EXTENSION_NOT_PRESENT;
705 #endif
706 }
707
708 bool
radv_android_gralloc_supports_format(VkFormat format,VkImageUsageFlagBits usage)709 radv_android_gralloc_supports_format(VkFormat format, VkImageUsageFlagBits usage)
710 {
711 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
712 /* Ideally we check AHardwareBuffer_isSupported. But that test-allocates on most platforms and
713 * seems a bit on the expensive side. Return true as long as it is a format we understand.
714 */
715 (void)usage;
716 return radv_ahb_format_for_vk_format(format);
717 #else
718 (void)format;
719 (void)usage;
720 return false;
721 #endif
722 }
723