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