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