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