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