1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * based in part on anv and radv which are:
6*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat
8*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
9*61046927SAndroid Build Coastguard Worker */
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "vn_android.h"
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include <dlfcn.h>
14*61046927SAndroid Build Coastguard Worker #include <hardware/hwvulkan.h>
15*61046927SAndroid Build Coastguard Worker #include <vndk/hardware_buffer.h>
16*61046927SAndroid Build Coastguard Worker #include <vulkan/vk_icd.h>
17*61046927SAndroid Build Coastguard Worker
18*61046927SAndroid Build Coastguard Worker #include "util/os_file.h"
19*61046927SAndroid Build Coastguard Worker #include "util/u_gralloc/u_gralloc.h"
20*61046927SAndroid Build Coastguard Worker #include "vk_android.h"
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Worker #include "vn_buffer.h"
23*61046927SAndroid Build Coastguard Worker #include "vn_device.h"
24*61046927SAndroid Build Coastguard Worker #include "vn_device_memory.h"
25*61046927SAndroid Build Coastguard Worker #include "vn_image.h"
26*61046927SAndroid Build Coastguard Worker #include "vn_instance.h"
27*61046927SAndroid Build Coastguard Worker #include "vn_physical_device.h"
28*61046927SAndroid Build Coastguard Worker #include "vn_queue.h"
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc {
31*61046927SAndroid Build Coastguard Worker struct u_gralloc *gralloc;
32*61046927SAndroid Build Coastguard Worker uint64_t front_rendering_usage;
33*61046927SAndroid Build Coastguard Worker };
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker static struct vn_android_gralloc _vn_android_gralloc;
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker static int
vn_android_gralloc_init()38*61046927SAndroid Build Coastguard Worker vn_android_gralloc_init()
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker assert(!_vn_android_gralloc.gralloc);
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker struct u_gralloc *gralloc = u_gralloc_create(U_GRALLOC_TYPE_AUTO);
43*61046927SAndroid Build Coastguard Worker if (!gralloc) {
44*61046927SAndroid Build Coastguard Worker vn_log(NULL, "u_gralloc failed to create a gralloc module instance");
45*61046927SAndroid Build Coastguard Worker return -1;
46*61046927SAndroid Build Coastguard Worker }
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker const int gralloc_type = u_gralloc_get_type(gralloc);
49*61046927SAndroid Build Coastguard Worker if (gralloc_type != U_GRALLOC_TYPE_CROS &&
50*61046927SAndroid Build Coastguard Worker gralloc_type != U_GRALLOC_TYPE_GRALLOC4) {
51*61046927SAndroid Build Coastguard Worker u_gralloc_destroy(&gralloc);
52*61046927SAndroid Build Coastguard Worker vn_log(NULL, "only CrOS and IMapper v4 grallocs are supported for "
53*61046927SAndroid Build Coastguard Worker "Venus Vulkan HAL");
54*61046927SAndroid Build Coastguard Worker return -1;
55*61046927SAndroid Build Coastguard Worker }
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker _vn_android_gralloc.gralloc = gralloc;
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker return 0;
60*61046927SAndroid Build Coastguard Worker }
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker static inline void
vn_android_gralloc_fini()63*61046927SAndroid Build Coastguard Worker vn_android_gralloc_fini()
64*61046927SAndroid Build Coastguard Worker {
65*61046927SAndroid Build Coastguard Worker u_gralloc_destroy(&_vn_android_gralloc.gralloc);
66*61046927SAndroid Build Coastguard Worker }
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker static void
vn_android_gralloc_shared_present_usage_init_once()69*61046927SAndroid Build Coastguard Worker vn_android_gralloc_shared_present_usage_init_once()
70*61046927SAndroid Build Coastguard Worker {
71*61046927SAndroid Build Coastguard Worker assert(_vn_android_gralloc.gralloc);
72*61046927SAndroid Build Coastguard Worker
73*61046927SAndroid Build Coastguard Worker int ret = u_gralloc_get_front_rendering_usage(
74*61046927SAndroid Build Coastguard Worker _vn_android_gralloc.gralloc,
75*61046927SAndroid Build Coastguard Worker &_vn_android_gralloc.front_rendering_usage);
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker if (ret == 0)
78*61046927SAndroid Build Coastguard Worker assert(_vn_android_gralloc.front_rendering_usage);
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker uint64_t
vn_android_gralloc_get_shared_present_usage()82*61046927SAndroid Build Coastguard Worker vn_android_gralloc_get_shared_present_usage()
83*61046927SAndroid Build Coastguard Worker {
84*61046927SAndroid Build Coastguard Worker static once_flag once = ONCE_FLAG_INIT;
85*61046927SAndroid Build Coastguard Worker call_once(&once, vn_android_gralloc_shared_present_usage_init_once);
86*61046927SAndroid Build Coastguard Worker return _vn_android_gralloc.front_rendering_usage;
87*61046927SAndroid Build Coastguard Worker }
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc_buffer_properties {
90*61046927SAndroid Build Coastguard Worker uint32_t drm_fourcc;
91*61046927SAndroid Build Coastguard Worker uint32_t num_planes;
92*61046927SAndroid Build Coastguard Worker uint64_t modifier;
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker /* plane order matches VkImageDrmFormatModifierExplicitCreateInfoEXT */
95*61046927SAndroid Build Coastguard Worker uint32_t offset[4];
96*61046927SAndroid Build Coastguard Worker uint32_t stride[4];
97*61046927SAndroid Build Coastguard Worker };
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker static bool
vn_android_gralloc_get_buffer_properties(buffer_handle_t handle,struct vn_android_gralloc_buffer_properties * out_props)100*61046927SAndroid Build Coastguard Worker vn_android_gralloc_get_buffer_properties(
101*61046927SAndroid Build Coastguard Worker buffer_handle_t handle,
102*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc_buffer_properties *out_props)
103*61046927SAndroid Build Coastguard Worker {
104*61046927SAndroid Build Coastguard Worker struct u_gralloc *gralloc = _vn_android_gralloc.gralloc;
105*61046927SAndroid Build Coastguard Worker struct u_gralloc_buffer_basic_info info;
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker /*
108*61046927SAndroid Build Coastguard Worker * We only support (and care of) CrOS and IMapper v4 gralloc modules
109*61046927SAndroid Build Coastguard Worker * at this point. They don't need the pixel stride and HAL format
110*61046927SAndroid Build Coastguard Worker * to be provided externally to them. It allows integrating u_gralloc
111*61046927SAndroid Build Coastguard Worker * with minimal modifications at this point.
112*61046927SAndroid Build Coastguard Worker */
113*61046927SAndroid Build Coastguard Worker struct u_gralloc_buffer_handle ugb_handle = {
114*61046927SAndroid Build Coastguard Worker .handle = handle,
115*61046927SAndroid Build Coastguard Worker .pixel_stride = 0,
116*61046927SAndroid Build Coastguard Worker .hal_format = 0,
117*61046927SAndroid Build Coastguard Worker };
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker if (u_gralloc_get_buffer_basic_info(gralloc, &ugb_handle, &info) != 0) {
120*61046927SAndroid Build Coastguard Worker vn_log(NULL, "u_gralloc_get_buffer_basic_info failed");
121*61046927SAndroid Build Coastguard Worker return false;
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker if (info.modifier == DRM_FORMAT_MOD_INVALID) {
125*61046927SAndroid Build Coastguard Worker vn_log(NULL, "Unexpected DRM_FORMAT_MOD_INVALID");
126*61046927SAndroid Build Coastguard Worker return false;
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker assert(info.num_planes <= 4);
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker out_props->drm_fourcc = info.drm_fourcc;
132*61046927SAndroid Build Coastguard Worker out_props->num_planes = info.num_planes;
133*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info.num_planes; i++) {
134*61046927SAndroid Build Coastguard Worker if (!info.strides[i]) {
135*61046927SAndroid Build Coastguard Worker out_props->num_planes = i;
136*61046927SAndroid Build Coastguard Worker break;
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker out_props->stride[i] = info.strides[i];
139*61046927SAndroid Build Coastguard Worker out_props->offset[i] = info.offsets[i];
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker /* YVU420 has a chroma order of CrCb. So we must swap the planes for CrCb
143*61046927SAndroid Build Coastguard Worker * to align with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM. This is to serve
144*61046927SAndroid Build Coastguard Worker * VkImageDrmFormatModifierExplicitCreateInfoEXT explicit plane layouts.
145*61046927SAndroid Build Coastguard Worker */
146*61046927SAndroid Build Coastguard Worker if (info.drm_fourcc == DRM_FORMAT_YVU420) {
147*61046927SAndroid Build Coastguard Worker out_props->stride[1] = info.strides[2];
148*61046927SAndroid Build Coastguard Worker out_props->offset[1] = info.offsets[2];
149*61046927SAndroid Build Coastguard Worker out_props->stride[2] = info.strides[1];
150*61046927SAndroid Build Coastguard Worker out_props->offset[2] = info.offsets[1];
151*61046927SAndroid Build Coastguard Worker }
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker out_props->modifier = info.modifier;
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker return true;
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker static int
vn_android_gralloc_get_dma_buf_fd(const native_handle_t * handle)159*61046927SAndroid Build Coastguard Worker vn_android_gralloc_get_dma_buf_fd(const native_handle_t *handle)
160*61046927SAndroid Build Coastguard Worker {
161*61046927SAndroid Build Coastguard Worker /* There can be multiple fds wrapped inside a native_handle_t, but we
162*61046927SAndroid Build Coastguard Worker * expect the 1st one pointing to the dma_buf. For multi-planar format,
163*61046927SAndroid Build Coastguard Worker * there should only exist one undelying dma_buf. The other fd(s) could be
164*61046927SAndroid Build Coastguard Worker * dups to the same dma_buf or point to the shared memory used to store
165*61046927SAndroid Build Coastguard Worker * gralloc buffer metadata.
166*61046927SAndroid Build Coastguard Worker */
167*61046927SAndroid Build Coastguard Worker assert(handle);
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker if (handle->numFds < 1) {
170*61046927SAndroid Build Coastguard Worker vn_log(NULL, "handle->numFds is %d, expected >= 1", handle->numFds);
171*61046927SAndroid Build Coastguard Worker return -1;
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker if (handle->data[0] < 0) {
175*61046927SAndroid Build Coastguard Worker vn_log(NULL, "handle->data[0] < 0");
176*61046927SAndroid Build Coastguard Worker return -1;
177*61046927SAndroid Build Coastguard Worker }
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker return handle->data[0];
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker static int
183*61046927SAndroid Build Coastguard Worker vn_hal_open(const struct hw_module_t *mod,
184*61046927SAndroid Build Coastguard Worker const char *id,
185*61046927SAndroid Build Coastguard Worker struct hw_device_t **dev);
186*61046927SAndroid Build Coastguard Worker
187*61046927SAndroid Build Coastguard Worker static_assert(HWVULKAN_DISPATCH_MAGIC == ICD_LOADER_MAGIC, "");
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker PUBLIC struct hwvulkan_module_t HAL_MODULE_INFO_SYM = {
190*61046927SAndroid Build Coastguard Worker .common = {
191*61046927SAndroid Build Coastguard Worker .tag = HARDWARE_MODULE_TAG,
192*61046927SAndroid Build Coastguard Worker .module_api_version = HWVULKAN_MODULE_API_VERSION_0_1,
193*61046927SAndroid Build Coastguard Worker .hal_api_version = HARDWARE_HAL_API_VERSION,
194*61046927SAndroid Build Coastguard Worker .id = HWVULKAN_HARDWARE_MODULE_ID,
195*61046927SAndroid Build Coastguard Worker .name = "Venus Vulkan HAL",
196*61046927SAndroid Build Coastguard Worker .author = "Google LLC",
197*61046927SAndroid Build Coastguard Worker .methods = &(hw_module_methods_t) {
198*61046927SAndroid Build Coastguard Worker .open = vn_hal_open,
199*61046927SAndroid Build Coastguard Worker },
200*61046927SAndroid Build Coastguard Worker },
201*61046927SAndroid Build Coastguard Worker };
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker static int
vn_hal_close(UNUSED struct hw_device_t * dev)204*61046927SAndroid Build Coastguard Worker vn_hal_close(UNUSED struct hw_device_t *dev)
205*61046927SAndroid Build Coastguard Worker {
206*61046927SAndroid Build Coastguard Worker vn_android_gralloc_fini();
207*61046927SAndroid Build Coastguard Worker return 0;
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker static hwvulkan_device_t vn_hal_dev = {
211*61046927SAndroid Build Coastguard Worker .common = {
212*61046927SAndroid Build Coastguard Worker .tag = HARDWARE_DEVICE_TAG,
213*61046927SAndroid Build Coastguard Worker .version = HWVULKAN_DEVICE_API_VERSION_0_1,
214*61046927SAndroid Build Coastguard Worker .module = &HAL_MODULE_INFO_SYM.common,
215*61046927SAndroid Build Coastguard Worker .close = vn_hal_close,
216*61046927SAndroid Build Coastguard Worker },
217*61046927SAndroid Build Coastguard Worker .EnumerateInstanceExtensionProperties = vn_EnumerateInstanceExtensionProperties,
218*61046927SAndroid Build Coastguard Worker .CreateInstance = vn_CreateInstance,
219*61046927SAndroid Build Coastguard Worker .GetInstanceProcAddr = vn_GetInstanceProcAddr,
220*61046927SAndroid Build Coastguard Worker };
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker static int
vn_hal_open(const struct hw_module_t * mod,const char * id,struct hw_device_t ** dev)223*61046927SAndroid Build Coastguard Worker vn_hal_open(const struct hw_module_t *mod,
224*61046927SAndroid Build Coastguard Worker const char *id,
225*61046927SAndroid Build Coastguard Worker struct hw_device_t **dev)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker int ret;
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker assert(mod == &HAL_MODULE_INFO_SYM.common);
230*61046927SAndroid Build Coastguard Worker assert(strcmp(id, HWVULKAN_DEVICE_0) == 0);
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker ret = vn_android_gralloc_init();
233*61046927SAndroid Build Coastguard Worker if (ret)
234*61046927SAndroid Build Coastguard Worker return ret;
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker *dev = &vn_hal_dev.common;
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker return 0;
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker
241*61046927SAndroid Build Coastguard Worker const VkFormat *
vn_android_format_to_view_formats(VkFormat format,uint32_t * out_count)242*61046927SAndroid Build Coastguard Worker vn_android_format_to_view_formats(VkFormat format, uint32_t *out_count)
243*61046927SAndroid Build Coastguard Worker {
244*61046927SAndroid Build Coastguard Worker /* For AHB image prop query and creation, venus overrides the tiling to
245*61046927SAndroid Build Coastguard Worker * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, which requires to chain
246*61046927SAndroid Build Coastguard Worker * VkImageFormatListCreateInfo struct in the corresponding pNext when the
247*61046927SAndroid Build Coastguard Worker * VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT is set. Those AHB images are assumed
248*61046927SAndroid Build Coastguard Worker * to be mutable no more than sRGB-ness, and the implementations can fail
249*61046927SAndroid Build Coastguard Worker * whenever going beyond.
250*61046927SAndroid Build Coastguard Worker *
251*61046927SAndroid Build Coastguard Worker * This helper provides the view formats that have sRGB variants for the
252*61046927SAndroid Build Coastguard Worker * image format that venus supports.
253*61046927SAndroid Build Coastguard Worker */
254*61046927SAndroid Build Coastguard Worker static const VkFormat view_formats_r8g8b8a8[] = {
255*61046927SAndroid Build Coastguard Worker VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB
256*61046927SAndroid Build Coastguard Worker };
257*61046927SAndroid Build Coastguard Worker static const VkFormat view_formats_r8g8b8[] = { VK_FORMAT_R8G8B8_UNORM,
258*61046927SAndroid Build Coastguard Worker VK_FORMAT_R8G8B8_SRGB };
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker switch (format) {
261*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8G8B8A8_UNORM:
262*61046927SAndroid Build Coastguard Worker *out_count = ARRAY_SIZE(view_formats_r8g8b8a8);
263*61046927SAndroid Build Coastguard Worker return view_formats_r8g8b8a8;
264*61046927SAndroid Build Coastguard Worker break;
265*61046927SAndroid Build Coastguard Worker case VK_FORMAT_R8G8B8_UNORM:
266*61046927SAndroid Build Coastguard Worker *out_count = ARRAY_SIZE(view_formats_r8g8b8);
267*61046927SAndroid Build Coastguard Worker return view_formats_r8g8b8;
268*61046927SAndroid Build Coastguard Worker break;
269*61046927SAndroid Build Coastguard Worker default:
270*61046927SAndroid Build Coastguard Worker /* let the caller handle the fallback case */
271*61046927SAndroid Build Coastguard Worker *out_count = 0;
272*61046927SAndroid Build Coastguard Worker return NULL;
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker }
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker VkFormat
vn_android_drm_format_to_vk_format(uint32_t format)277*61046927SAndroid Build Coastguard Worker vn_android_drm_format_to_vk_format(uint32_t format)
278*61046927SAndroid Build Coastguard Worker {
279*61046927SAndroid Build Coastguard Worker switch (format) {
280*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR8888:
281*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_XBGR8888:
282*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8B8A8_UNORM;
283*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_BGR888:
284*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R8G8B8_UNORM;
285*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_RGB565:
286*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R5G6B5_UNORM_PACK16;
287*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR16161616F:
288*61046927SAndroid Build Coastguard Worker return VK_FORMAT_R16G16B16A16_SFLOAT;
289*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_ABGR2101010:
290*61046927SAndroid Build Coastguard Worker return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
291*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
292*61046927SAndroid Build Coastguard Worker return VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
293*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
294*61046927SAndroid Build Coastguard Worker return VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
295*61046927SAndroid Build Coastguard Worker default:
296*61046927SAndroid Build Coastguard Worker return VK_FORMAT_UNDEFINED;
297*61046927SAndroid Build Coastguard Worker }
298*61046927SAndroid Build Coastguard Worker }
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker static bool
vn_android_drm_format_is_yuv(uint32_t format)301*61046927SAndroid Build Coastguard Worker vn_android_drm_format_is_yuv(uint32_t format)
302*61046927SAndroid Build Coastguard Worker {
303*61046927SAndroid Build Coastguard Worker assert(vn_android_drm_format_to_vk_format(format) != VK_FORMAT_UNDEFINED);
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker switch (format) {
306*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_YVU420:
307*61046927SAndroid Build Coastguard Worker case DRM_FORMAT_NV12:
308*61046927SAndroid Build Coastguard Worker return true;
309*61046927SAndroid Build Coastguard Worker default:
310*61046927SAndroid Build Coastguard Worker return false;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker
314*61046927SAndroid Build Coastguard Worker VkResult
vn_GetSwapchainGrallocUsage2ANDROID(VkDevice device,VkFormat format,VkImageUsageFlags imageUsage,VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,uint64_t * grallocConsumerUsage,uint64_t * grallocProducerUsage)315*61046927SAndroid Build Coastguard Worker vn_GetSwapchainGrallocUsage2ANDROID(
316*61046927SAndroid Build Coastguard Worker VkDevice device,
317*61046927SAndroid Build Coastguard Worker VkFormat format,
318*61046927SAndroid Build Coastguard Worker VkImageUsageFlags imageUsage,
319*61046927SAndroid Build Coastguard Worker VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
320*61046927SAndroid Build Coastguard Worker uint64_t *grallocConsumerUsage,
321*61046927SAndroid Build Coastguard Worker uint64_t *grallocProducerUsage)
322*61046927SAndroid Build Coastguard Worker {
323*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker if (VN_DEBUG(WSI)) {
326*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
327*61046927SAndroid Build Coastguard Worker "format=%d, imageUsage=0x%x, swapchainImageUsage=0x%x", format,
328*61046927SAndroid Build Coastguard Worker imageUsage, swapchainImageUsage);
329*61046927SAndroid Build Coastguard Worker }
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker *grallocConsumerUsage = 0;
332*61046927SAndroid Build Coastguard Worker *grallocProducerUsage = 0;
333*61046927SAndroid Build Coastguard Worker if (imageUsage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT |
334*61046927SAndroid Build Coastguard Worker VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
335*61046927SAndroid Build Coastguard Worker *grallocProducerUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker if (imageUsage &
338*61046927SAndroid Build Coastguard Worker (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
339*61046927SAndroid Build Coastguard Worker VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))
340*61046927SAndroid Build Coastguard Worker *grallocProducerUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker if (swapchainImageUsage & VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID)
343*61046927SAndroid Build Coastguard Worker *grallocProducerUsage |= vn_android_gralloc_get_shared_present_usage();
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker vn_tls_set_async_pipeline_create();
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
348*61046927SAndroid Build Coastguard Worker }
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker static VkResult
vn_android_get_modifier_properties(struct vn_device * dev,VkFormat format,uint64_t modifier,VkDrmFormatModifierPropertiesEXT * out_props)351*61046927SAndroid Build Coastguard Worker vn_android_get_modifier_properties(struct vn_device *dev,
352*61046927SAndroid Build Coastguard Worker VkFormat format,
353*61046927SAndroid Build Coastguard Worker uint64_t modifier,
354*61046927SAndroid Build Coastguard Worker VkDrmFormatModifierPropertiesEXT *out_props)
355*61046927SAndroid Build Coastguard Worker {
356*61046927SAndroid Build Coastguard Worker VkPhysicalDevice physical_device =
357*61046927SAndroid Build Coastguard Worker vn_physical_device_to_handle(dev->physical_device);
358*61046927SAndroid Build Coastguard Worker VkDrmFormatModifierPropertiesListEXT mod_prop_list = {
359*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
360*61046927SAndroid Build Coastguard Worker };
361*61046927SAndroid Build Coastguard Worker VkFormatProperties2 format_prop = {
362*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
363*61046927SAndroid Build Coastguard Worker .pNext = &mod_prop_list,
364*61046927SAndroid Build Coastguard Worker };
365*61046927SAndroid Build Coastguard Worker
366*61046927SAndroid Build Coastguard Worker vn_GetPhysicalDeviceFormatProperties2(physical_device, format,
367*61046927SAndroid Build Coastguard Worker &format_prop);
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker if (!mod_prop_list.drmFormatModifierCount) {
370*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "No compatible modifier for VkFormat(%u)",
371*61046927SAndroid Build Coastguard Worker format);
372*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker STACK_ARRAY(VkDrmFormatModifierPropertiesEXT, mod_props,
376*61046927SAndroid Build Coastguard Worker mod_prop_list.drmFormatModifierCount);
377*61046927SAndroid Build Coastguard Worker
378*61046927SAndroid Build Coastguard Worker mod_prop_list.pDrmFormatModifierProperties = mod_props;
379*61046927SAndroid Build Coastguard Worker vn_GetPhysicalDeviceFormatProperties2(physical_device, format,
380*61046927SAndroid Build Coastguard Worker &format_prop);
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker bool modifier_found = false;
383*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < mod_prop_list.drmFormatModifierCount; i++) {
384*61046927SAndroid Build Coastguard Worker if (mod_props[i].drmFormatModifier == modifier) {
385*61046927SAndroid Build Coastguard Worker *out_props = mod_props[i];
386*61046927SAndroid Build Coastguard Worker modifier_found = true;
387*61046927SAndroid Build Coastguard Worker break;
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker STACK_ARRAY_FINISH(mod_props);
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker if (!modifier_found) {
394*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
395*61046927SAndroid Build Coastguard Worker "No matching modifier(%" PRIu64 ") properties for VkFormat(%u)",
396*61046927SAndroid Build Coastguard Worker modifier, format);
397*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
401*61046927SAndroid Build Coastguard Worker }
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker struct vn_android_image_builder {
404*61046927SAndroid Build Coastguard Worker VkImageCreateInfo create;
405*61046927SAndroid Build Coastguard Worker VkSubresourceLayout layouts[4];
406*61046927SAndroid Build Coastguard Worker VkImageDrmFormatModifierExplicitCreateInfoEXT modifier;
407*61046927SAndroid Build Coastguard Worker VkExternalMemoryImageCreateInfo external;
408*61046927SAndroid Build Coastguard Worker VkImageFormatListCreateInfo list;
409*61046927SAndroid Build Coastguard Worker };
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker static VkResult
vn_android_get_image_builder(struct vn_device * dev,const VkImageCreateInfo * create_info,const native_handle_t * handle,struct vn_android_image_builder * out_builder)412*61046927SAndroid Build Coastguard Worker vn_android_get_image_builder(struct vn_device *dev,
413*61046927SAndroid Build Coastguard Worker const VkImageCreateInfo *create_info,
414*61046927SAndroid Build Coastguard Worker const native_handle_t *handle,
415*61046927SAndroid Build Coastguard Worker struct vn_android_image_builder *out_builder)
416*61046927SAndroid Build Coastguard Worker {
417*61046927SAndroid Build Coastguard Worker /* Android image builder is only used by ANB or AHB. For ANB, Android
418*61046927SAndroid Build Coastguard Worker * Vulkan loader will never pass the below structs. For AHB, struct
419*61046927SAndroid Build Coastguard Worker * vn_image_create_deferred_info will never carry below either.
420*61046927SAndroid Build Coastguard Worker */
421*61046927SAndroid Build Coastguard Worker assert(!vk_find_struct_const(
422*61046927SAndroid Build Coastguard Worker create_info->pNext,
423*61046927SAndroid Build Coastguard Worker IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT));
424*61046927SAndroid Build Coastguard Worker assert(!vk_find_struct_const(create_info->pNext,
425*61046927SAndroid Build Coastguard Worker EXTERNAL_MEMORY_IMAGE_CREATE_INFO));
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc_buffer_properties buf_props;
428*61046927SAndroid Build Coastguard Worker if (!vn_android_gralloc_get_buffer_properties(handle, &buf_props))
429*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker /* fill VkImageCreateInfo */
432*61046927SAndroid Build Coastguard Worker memset(out_builder, 0, sizeof(*out_builder));
433*61046927SAndroid Build Coastguard Worker out_builder->create = *create_info;
434*61046927SAndroid Build Coastguard Worker out_builder->create.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker /* fill VkImageDrmFormatModifierExplicitCreateInfoEXT */
437*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < buf_props.num_planes; i++) {
438*61046927SAndroid Build Coastguard Worker out_builder->layouts[i].offset = buf_props.offset[i];
439*61046927SAndroid Build Coastguard Worker out_builder->layouts[i].rowPitch = buf_props.stride[i];
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker out_builder->modifier = (VkImageDrmFormatModifierExplicitCreateInfoEXT){
442*61046927SAndroid Build Coastguard Worker .sType =
443*61046927SAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT,
444*61046927SAndroid Build Coastguard Worker .pNext = out_builder->create.pNext,
445*61046927SAndroid Build Coastguard Worker .drmFormatModifier = buf_props.modifier,
446*61046927SAndroid Build Coastguard Worker .drmFormatModifierPlaneCount = buf_props.num_planes,
447*61046927SAndroid Build Coastguard Worker .pPlaneLayouts = out_builder->layouts,
448*61046927SAndroid Build Coastguard Worker };
449*61046927SAndroid Build Coastguard Worker out_builder->create.pNext = &out_builder->modifier;
450*61046927SAndroid Build Coastguard Worker
451*61046927SAndroid Build Coastguard Worker /* fill VkExternalMemoryImageCreateInfo */
452*61046927SAndroid Build Coastguard Worker out_builder->external = (VkExternalMemoryImageCreateInfo){
453*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
454*61046927SAndroid Build Coastguard Worker .pNext = out_builder->create.pNext,
455*61046927SAndroid Build Coastguard Worker .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
456*61046927SAndroid Build Coastguard Worker };
457*61046927SAndroid Build Coastguard Worker out_builder->create.pNext = &out_builder->external;
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker /* fill VkImageFormatListCreateInfo if needed
460*61046927SAndroid Build Coastguard Worker *
461*61046927SAndroid Build Coastguard Worker * vn_image::deferred_info only stores VkImageFormatListCreateInfo with a
462*61046927SAndroid Build Coastguard Worker * non-zero viewFormatCount, and that stored struct will be respected.
463*61046927SAndroid Build Coastguard Worker */
464*61046927SAndroid Build Coastguard Worker if ((create_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
465*61046927SAndroid Build Coastguard Worker !vk_find_struct_const(create_info->pNext,
466*61046927SAndroid Build Coastguard Worker IMAGE_FORMAT_LIST_CREATE_INFO)) {
467*61046927SAndroid Build Coastguard Worker /* 12.3. Images
468*61046927SAndroid Build Coastguard Worker *
469*61046927SAndroid Build Coastguard Worker * If tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT and flags
470*61046927SAndroid Build Coastguard Worker * contains VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, then the pNext chain
471*61046927SAndroid Build Coastguard Worker * must include a VkImageFormatListCreateInfo structure with non-zero
472*61046927SAndroid Build Coastguard Worker * viewFormatCount.
473*61046927SAndroid Build Coastguard Worker */
474*61046927SAndroid Build Coastguard Worker uint32_t vcount = 0;
475*61046927SAndroid Build Coastguard Worker const VkFormat *vformats =
476*61046927SAndroid Build Coastguard Worker vn_android_format_to_view_formats(create_info->format, &vcount);
477*61046927SAndroid Build Coastguard Worker if (!vformats) {
478*61046927SAndroid Build Coastguard Worker /* image builder struct persists through the image creation call */
479*61046927SAndroid Build Coastguard Worker vformats = &out_builder->create.format;
480*61046927SAndroid Build Coastguard Worker vcount = 1;
481*61046927SAndroid Build Coastguard Worker }
482*61046927SAndroid Build Coastguard Worker out_builder->list = (VkImageFormatListCreateInfo){
483*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
484*61046927SAndroid Build Coastguard Worker .pNext = out_builder->create.pNext,
485*61046927SAndroid Build Coastguard Worker .viewFormatCount = vcount,
486*61046927SAndroid Build Coastguard Worker .pViewFormats = vformats,
487*61046927SAndroid Build Coastguard Worker };
488*61046927SAndroid Build Coastguard Worker out_builder->create.pNext = &out_builder->list;
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker
491*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
492*61046927SAndroid Build Coastguard Worker }
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker static VkResult
vn_android_image_from_anb_internal(struct vn_device * dev,const VkImageCreateInfo * create_info,const VkNativeBufferANDROID * anb_info,const VkAllocationCallbacks * alloc,struct vn_image ** out_img)495*61046927SAndroid Build Coastguard Worker vn_android_image_from_anb_internal(struct vn_device *dev,
496*61046927SAndroid Build Coastguard Worker const VkImageCreateInfo *create_info,
497*61046927SAndroid Build Coastguard Worker const VkNativeBufferANDROID *anb_info,
498*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc,
499*61046927SAndroid Build Coastguard Worker struct vn_image **out_img)
500*61046927SAndroid Build Coastguard Worker {
501*61046927SAndroid Build Coastguard Worker /* If anb_info->handle points to a classic resouce created from
502*61046927SAndroid Build Coastguard Worker * virtio_gpu_cmd_resource_create_3d, anb_info->stride is the stride of the
503*61046927SAndroid Build Coastguard Worker * guest shadow storage other than the host gpu storage.
504*61046927SAndroid Build Coastguard Worker *
505*61046927SAndroid Build Coastguard Worker * We also need to pass the correct stride to vn_CreateImage, which will be
506*61046927SAndroid Build Coastguard Worker * done via VkImageDrmFormatModifierExplicitCreateInfoEXT and will require
507*61046927SAndroid Build Coastguard Worker * VK_EXT_image_drm_format_modifier support in the host driver. The struct
508*61046927SAndroid Build Coastguard Worker * needs host storage info which can be queried from cros gralloc.
509*61046927SAndroid Build Coastguard Worker */
510*61046927SAndroid Build Coastguard Worker struct vn_image *img = NULL;
511*61046927SAndroid Build Coastguard Worker VkResult result;
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker assert(!(create_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT));
514*61046927SAndroid Build Coastguard Worker assert(!vk_find_struct_const(create_info->pNext,
515*61046927SAndroid Build Coastguard Worker IMAGE_FORMAT_LIST_CREATE_INFO));
516*61046927SAndroid Build Coastguard Worker assert(!vk_find_struct_const(create_info->pNext,
517*61046927SAndroid Build Coastguard Worker IMAGE_STENCIL_USAGE_CREATE_INFO));
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker struct vn_android_image_builder builder;
520*61046927SAndroid Build Coastguard Worker result = vn_android_get_image_builder(dev, create_info, anb_info->handle,
521*61046927SAndroid Build Coastguard Worker &builder);
522*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
523*61046927SAndroid Build Coastguard Worker return result;
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker /* encoder will strip the Android specific pNext structs */
526*61046927SAndroid Build Coastguard Worker if (*out_img) {
527*61046927SAndroid Build Coastguard Worker /* driver side img obj has been created for deferred init like ahb */
528*61046927SAndroid Build Coastguard Worker img = *out_img;
529*61046927SAndroid Build Coastguard Worker result = vn_image_init_deferred(dev, &builder.create, img);
530*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
531*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "anb: vn_image_init_deferred failed");
532*61046927SAndroid Build Coastguard Worker return result;
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker } else {
535*61046927SAndroid Build Coastguard Worker result = vn_image_create(dev, &builder.create, alloc, &img);
536*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
537*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "anb: vn_image_create failed");
538*61046927SAndroid Build Coastguard Worker return result;
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker }
541*61046927SAndroid Build Coastguard Worker
542*61046927SAndroid Build Coastguard Worker img->wsi.is_wsi = true;
543*61046927SAndroid Build Coastguard Worker img->wsi.tiling_override = builder.create.tiling;
544*61046927SAndroid Build Coastguard Worker img->wsi.drm_format_modifier = builder.modifier.drmFormatModifier;
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker int dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(anb_info->handle);
547*61046927SAndroid Build Coastguard Worker if (dma_buf_fd < 0) {
548*61046927SAndroid Build Coastguard Worker result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
549*61046927SAndroid Build Coastguard Worker goto fail;
550*61046927SAndroid Build Coastguard Worker }
551*61046927SAndroid Build Coastguard Worker
552*61046927SAndroid Build Coastguard Worker uint64_t alloc_size = 0;
553*61046927SAndroid Build Coastguard Worker uint32_t mem_type_bits = 0;
554*61046927SAndroid Build Coastguard Worker result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size,
555*61046927SAndroid Build Coastguard Worker &mem_type_bits);
556*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
557*61046927SAndroid Build Coastguard Worker goto fail;
558*61046927SAndroid Build Coastguard Worker
559*61046927SAndroid Build Coastguard Worker const VkMemoryRequirements *mem_req =
560*61046927SAndroid Build Coastguard Worker &img->requirements[0].memory.memoryRequirements;
561*61046927SAndroid Build Coastguard Worker if (alloc_size < mem_req->size) {
562*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
563*61046927SAndroid Build Coastguard Worker "anb: alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")",
564*61046927SAndroid Build Coastguard Worker alloc_size, mem_req->size);
565*61046927SAndroid Build Coastguard Worker result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
566*61046927SAndroid Build Coastguard Worker goto fail;
567*61046927SAndroid Build Coastguard Worker }
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker mem_type_bits &= mem_req->memoryTypeBits;
570*61046927SAndroid Build Coastguard Worker if (!mem_type_bits) {
571*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "anb: no compatible mem type");
572*61046927SAndroid Build Coastguard Worker result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
573*61046927SAndroid Build Coastguard Worker goto fail;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker int dup_fd = os_dupfd_cloexec(dma_buf_fd);
577*61046927SAndroid Build Coastguard Worker if (dup_fd < 0) {
578*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "anb: os_dupfd_cloexec failed(%d)", errno);
579*61046927SAndroid Build Coastguard Worker result = (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS
580*61046927SAndroid Build Coastguard Worker : VK_ERROR_OUT_OF_HOST_MEMORY;
581*61046927SAndroid Build Coastguard Worker goto fail;
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker const VkImportMemoryFdInfoKHR import_fd_info = {
585*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
586*61046927SAndroid Build Coastguard Worker .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
587*61046927SAndroid Build Coastguard Worker .fd = dup_fd,
588*61046927SAndroid Build Coastguard Worker };
589*61046927SAndroid Build Coastguard Worker const VkMemoryAllocateInfo memory_info = {
590*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
591*61046927SAndroid Build Coastguard Worker .pNext = &import_fd_info,
592*61046927SAndroid Build Coastguard Worker .allocationSize = mem_req->size,
593*61046927SAndroid Build Coastguard Worker .memoryTypeIndex = ffs(mem_type_bits) - 1,
594*61046927SAndroid Build Coastguard Worker };
595*61046927SAndroid Build Coastguard Worker VkDeviceMemory mem_handle;
596*61046927SAndroid Build Coastguard Worker result = vn_AllocateMemory(vn_device_to_handle(dev), &memory_info, alloc,
597*61046927SAndroid Build Coastguard Worker &mem_handle);
598*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
599*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "anb: mem import failed");
600*61046927SAndroid Build Coastguard Worker /* only need to close the dup_fd on import failure */
601*61046927SAndroid Build Coastguard Worker close(dup_fd);
602*61046927SAndroid Build Coastguard Worker goto fail;
603*61046927SAndroid Build Coastguard Worker }
604*61046927SAndroid Build Coastguard Worker
605*61046927SAndroid Build Coastguard Worker /* Android WSI image owns the memory */
606*61046927SAndroid Build Coastguard Worker img->wsi.memory = vn_device_memory_from_handle(mem_handle);
607*61046927SAndroid Build Coastguard Worker img->wsi.memory_owned = true;
608*61046927SAndroid Build Coastguard Worker *out_img = img;
609*61046927SAndroid Build Coastguard Worker
610*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
611*61046927SAndroid Build Coastguard Worker
612*61046927SAndroid Build Coastguard Worker fail:
613*61046927SAndroid Build Coastguard Worker /* this handles mem free for owned import */
614*61046927SAndroid Build Coastguard Worker vn_DestroyImage(vn_device_to_handle(dev), vn_image_to_handle(img), alloc);
615*61046927SAndroid Build Coastguard Worker return result;
616*61046927SAndroid Build Coastguard Worker }
617*61046927SAndroid Build Coastguard Worker
618*61046927SAndroid Build Coastguard Worker VkResult
vn_android_image_from_anb(struct vn_device * dev,const VkImageCreateInfo * create_info,const VkNativeBufferANDROID * anb_info,const VkAllocationCallbacks * alloc,struct vn_image ** out_img)619*61046927SAndroid Build Coastguard Worker vn_android_image_from_anb(struct vn_device *dev,
620*61046927SAndroid Build Coastguard Worker const VkImageCreateInfo *create_info,
621*61046927SAndroid Build Coastguard Worker const VkNativeBufferANDROID *anb_info,
622*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc,
623*61046927SAndroid Build Coastguard Worker struct vn_image **out_img)
624*61046927SAndroid Build Coastguard Worker {
625*61046927SAndroid Build Coastguard Worker struct vn_image *img = NULL;
626*61046927SAndroid Build Coastguard Worker VkResult result = vn_android_image_from_anb_internal(
627*61046927SAndroid Build Coastguard Worker dev, create_info, anb_info, alloc, &img);
628*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
629*61046927SAndroid Build Coastguard Worker return result;
630*61046927SAndroid Build Coastguard Worker
631*61046927SAndroid Build Coastguard Worker const VkBindImageMemoryInfo bind_info = {
632*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
633*61046927SAndroid Build Coastguard Worker .image = vn_image_to_handle(img),
634*61046927SAndroid Build Coastguard Worker .memory = vn_device_memory_to_handle(img->wsi.memory),
635*61046927SAndroid Build Coastguard Worker };
636*61046927SAndroid Build Coastguard Worker result = vn_BindImageMemory2(vn_device_to_handle(dev), 1, &bind_info);
637*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
638*61046927SAndroid Build Coastguard Worker vn_DestroyImage(vn_device_to_handle(dev), vn_image_to_handle(img),
639*61046927SAndroid Build Coastguard Worker alloc);
640*61046927SAndroid Build Coastguard Worker return result;
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker *out_img = img;
644*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
645*61046927SAndroid Build Coastguard Worker }
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker struct vn_device_memory *
vn_android_get_wsi_memory_from_bind_info(struct vn_device * dev,const VkBindImageMemoryInfo * bind_info)648*61046927SAndroid Build Coastguard Worker vn_android_get_wsi_memory_from_bind_info(
649*61046927SAndroid Build Coastguard Worker struct vn_device *dev, const VkBindImageMemoryInfo *bind_info)
650*61046927SAndroid Build Coastguard Worker {
651*61046927SAndroid Build Coastguard Worker const VkNativeBufferANDROID *anb_info =
652*61046927SAndroid Build Coastguard Worker vk_find_struct_const(bind_info->pNext, NATIVE_BUFFER_ANDROID);
653*61046927SAndroid Build Coastguard Worker assert(anb_info && anb_info->handle);
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker struct vn_image *img = vn_image_from_handle(bind_info->image);
656*61046927SAndroid Build Coastguard Worker VkResult result = vn_android_image_from_anb_internal(
657*61046927SAndroid Build Coastguard Worker dev, &img->deferred_info->create, anb_info, &dev->base.base.alloc,
658*61046927SAndroid Build Coastguard Worker &img);
659*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
660*61046927SAndroid Build Coastguard Worker return NULL;
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker assert(img->wsi.memory_owned);
663*61046927SAndroid Build Coastguard Worker return img->wsi.memory;
664*61046927SAndroid Build Coastguard Worker }
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker static VkResult
vn_android_get_ahb_format_properties(struct vn_device * dev,const struct AHardwareBuffer * ahb,VkAndroidHardwareBufferFormatPropertiesANDROID * out_props)667*61046927SAndroid Build Coastguard Worker vn_android_get_ahb_format_properties(
668*61046927SAndroid Build Coastguard Worker struct vn_device *dev,
669*61046927SAndroid Build Coastguard Worker const struct AHardwareBuffer *ahb,
670*61046927SAndroid Build Coastguard Worker VkAndroidHardwareBufferFormatPropertiesANDROID *out_props)
671*61046927SAndroid Build Coastguard Worker {
672*61046927SAndroid Build Coastguard Worker AHardwareBuffer_Desc desc;
673*61046927SAndroid Build Coastguard Worker VkFormat format;
674*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc_buffer_properties buf_props;
675*61046927SAndroid Build Coastguard Worker VkDrmFormatModifierPropertiesEXT mod_props;
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker AHardwareBuffer_describe(ahb, &desc);
678*61046927SAndroid Build Coastguard Worker if (!(desc.usage & (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
679*61046927SAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
680*61046927SAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER))) {
681*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
682*61046927SAndroid Build Coastguard Worker "AHB usage(%" PRIu64 ") must include at least one GPU bit",
683*61046927SAndroid Build Coastguard Worker desc.usage);
684*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker /* Handle the special AHARDWAREBUFFER_FORMAT_BLOB for VkBuffer case. */
688*61046927SAndroid Build Coastguard Worker if (desc.format == AHARDWAREBUFFER_FORMAT_BLOB) {
689*61046927SAndroid Build Coastguard Worker out_props->format = VK_FORMAT_UNDEFINED;
690*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
691*61046927SAndroid Build Coastguard Worker }
692*61046927SAndroid Build Coastguard Worker
693*61046927SAndroid Build Coastguard Worker if (!vn_android_gralloc_get_buffer_properties(
694*61046927SAndroid Build Coastguard Worker AHardwareBuffer_getNativeHandle(ahb), &buf_props))
695*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker /* We implement AHB extension support with EXT_image_drm_format_modifier.
698*61046927SAndroid Build Coastguard Worker * It requires us to have a compatible VkFormat but not DRM formats. So if
699*61046927SAndroid Build Coastguard Worker * the ahb is not intended for backing a VkBuffer, error out early if the
700*61046927SAndroid Build Coastguard Worker * format is VK_FORMAT_UNDEFINED.
701*61046927SAndroid Build Coastguard Worker */
702*61046927SAndroid Build Coastguard Worker format = vn_android_drm_format_to_vk_format(buf_props.drm_fourcc);
703*61046927SAndroid Build Coastguard Worker if (format == VK_FORMAT_UNDEFINED) {
704*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "Unknown drm_fourcc(%u) from AHB format(0x%X)",
705*61046927SAndroid Build Coastguard Worker buf_props.drm_fourcc, desc.format);
706*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
707*61046927SAndroid Build Coastguard Worker }
708*61046927SAndroid Build Coastguard Worker
709*61046927SAndroid Build Coastguard Worker VkResult result = vn_android_get_modifier_properties(
710*61046927SAndroid Build Coastguard Worker dev, format, buf_props.modifier, &mod_props);
711*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
712*61046927SAndroid Build Coastguard Worker return result;
713*61046927SAndroid Build Coastguard Worker
714*61046927SAndroid Build Coastguard Worker if (mod_props.drmFormatModifierPlaneCount != buf_props.num_planes) {
715*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
716*61046927SAndroid Build Coastguard Worker "drmFormatModifierPlaneCount(%u) != buf_props.num_planes(%u) "
717*61046927SAndroid Build Coastguard Worker "for DRM format modifier(%" PRIu64 ")",
718*61046927SAndroid Build Coastguard Worker mod_props.drmFormatModifierPlaneCount, buf_props.num_planes,
719*61046927SAndroid Build Coastguard Worker buf_props.modifier);
720*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
721*61046927SAndroid Build Coastguard Worker }
722*61046927SAndroid Build Coastguard Worker
723*61046927SAndroid Build Coastguard Worker /* The spec requires that formatFeatures must include at least one of
724*61046927SAndroid Build Coastguard Worker * VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT or
725*61046927SAndroid Build Coastguard Worker * VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT.
726*61046927SAndroid Build Coastguard Worker */
727*61046927SAndroid Build Coastguard Worker const VkFormatFeatureFlags format_features =
728*61046927SAndroid Build Coastguard Worker mod_props.drmFormatModifierTilingFeatures |
729*61046927SAndroid Build Coastguard Worker VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker /* 11.2.7. Android Hardware Buffer External Memory
732*61046927SAndroid Build Coastguard Worker *
733*61046927SAndroid Build Coastguard Worker * Implementations may not always be able to determine the color model,
734*61046927SAndroid Build Coastguard Worker * numerical range, or chroma offsets of the image contents, so the values
735*61046927SAndroid Build Coastguard Worker * in VkAndroidHardwareBufferFormatPropertiesANDROID are only suggestions.
736*61046927SAndroid Build Coastguard Worker * Applications should treat these values as sensible defaults to use in the
737*61046927SAndroid Build Coastguard Worker * absence of more reliable information obtained through some other means.
738*61046927SAndroid Build Coastguard Worker */
739*61046927SAndroid Build Coastguard Worker const bool is_yuv = vn_android_drm_format_is_yuv(buf_props.drm_fourcc);
740*61046927SAndroid Build Coastguard Worker const VkSamplerYcbcrModelConversion model =
741*61046927SAndroid Build Coastguard Worker is_yuv ? VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601
742*61046927SAndroid Build Coastguard Worker : VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker /* ANGLE expects VK_FORMAT_UNDEFINED with externalFormat resolved from
745*61046927SAndroid Build Coastguard Worker * AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED and any supported planar
746*61046927SAndroid Build Coastguard Worker * AHB formats. Venus supports below explicit ones:
747*61046927SAndroid Build Coastguard Worker * - AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 (DRM_FORMAT_NV12)
748*61046927SAndroid Build Coastguard Worker * - AHARDWAREBUFFER_FORMAT_YV12 (DRM_FORMAT_YVU420)
749*61046927SAndroid Build Coastguard Worker */
750*61046927SAndroid Build Coastguard Worker if (desc.format == AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED || is_yuv)
751*61046927SAndroid Build Coastguard Worker format = VK_FORMAT_UNDEFINED;
752*61046927SAndroid Build Coastguard Worker
753*61046927SAndroid Build Coastguard Worker *out_props = (VkAndroidHardwareBufferFormatPropertiesANDROID) {
754*61046927SAndroid Build Coastguard Worker .sType = out_props->sType,
755*61046927SAndroid Build Coastguard Worker .pNext = out_props->pNext,
756*61046927SAndroid Build Coastguard Worker .format = format,
757*61046927SAndroid Build Coastguard Worker .externalFormat = buf_props.drm_fourcc,
758*61046927SAndroid Build Coastguard Worker .formatFeatures = format_features,
759*61046927SAndroid Build Coastguard Worker .samplerYcbcrConversionComponents = {
760*61046927SAndroid Build Coastguard Worker .r = VK_COMPONENT_SWIZZLE_IDENTITY,
761*61046927SAndroid Build Coastguard Worker .g = VK_COMPONENT_SWIZZLE_IDENTITY,
762*61046927SAndroid Build Coastguard Worker .b = VK_COMPONENT_SWIZZLE_IDENTITY,
763*61046927SAndroid Build Coastguard Worker .a = VK_COMPONENT_SWIZZLE_IDENTITY,
764*61046927SAndroid Build Coastguard Worker },
765*61046927SAndroid Build Coastguard Worker .suggestedYcbcrModel = model,
766*61046927SAndroid Build Coastguard Worker /* match EGL_YUV_NARROW_RANGE_EXT used in egl platform_android */
767*61046927SAndroid Build Coastguard Worker .suggestedYcbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW,
768*61046927SAndroid Build Coastguard Worker .suggestedXChromaOffset = VK_CHROMA_LOCATION_MIDPOINT,
769*61046927SAndroid Build Coastguard Worker .suggestedYChromaOffset = VK_CHROMA_LOCATION_MIDPOINT,
770*61046927SAndroid Build Coastguard Worker };
771*61046927SAndroid Build Coastguard Worker
772*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
773*61046927SAndroid Build Coastguard Worker }
774*61046927SAndroid Build Coastguard Worker
775*61046927SAndroid Build Coastguard Worker VkResult
vn_GetAndroidHardwareBufferPropertiesANDROID(VkDevice device,const struct AHardwareBuffer * buffer,VkAndroidHardwareBufferPropertiesANDROID * pProperties)776*61046927SAndroid Build Coastguard Worker vn_GetAndroidHardwareBufferPropertiesANDROID(
777*61046927SAndroid Build Coastguard Worker VkDevice device,
778*61046927SAndroid Build Coastguard Worker const struct AHardwareBuffer *buffer,
779*61046927SAndroid Build Coastguard Worker VkAndroidHardwareBufferPropertiesANDROID *pProperties)
780*61046927SAndroid Build Coastguard Worker {
781*61046927SAndroid Build Coastguard Worker VN_TRACE_FUNC();
782*61046927SAndroid Build Coastguard Worker struct vn_device *dev = vn_device_from_handle(device);
783*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
784*61046927SAndroid Build Coastguard Worker int dma_buf_fd = -1;
785*61046927SAndroid Build Coastguard Worker uint64_t alloc_size = 0;
786*61046927SAndroid Build Coastguard Worker uint32_t mem_type_bits = 0;
787*61046927SAndroid Build Coastguard Worker
788*61046927SAndroid Build Coastguard Worker VkAndroidHardwareBufferFormatProperties2ANDROID *format_props2 =
789*61046927SAndroid Build Coastguard Worker vk_find_struct(pProperties->pNext,
790*61046927SAndroid Build Coastguard Worker ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID);
791*61046927SAndroid Build Coastguard Worker VkAndroidHardwareBufferFormatPropertiesANDROID *format_props =
792*61046927SAndroid Build Coastguard Worker vk_find_struct(pProperties->pNext,
793*61046927SAndroid Build Coastguard Worker ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID);
794*61046927SAndroid Build Coastguard Worker if (format_props2 || format_props) {
795*61046927SAndroid Build Coastguard Worker VkAndroidHardwareBufferFormatPropertiesANDROID local_props = {
796*61046927SAndroid Build Coastguard Worker .sType =
797*61046927SAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
798*61046927SAndroid Build Coastguard Worker };
799*61046927SAndroid Build Coastguard Worker if (!format_props)
800*61046927SAndroid Build Coastguard Worker format_props = &local_props;
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker result =
803*61046927SAndroid Build Coastguard Worker vn_android_get_ahb_format_properties(dev, buffer, format_props);
804*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
805*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, result);
806*61046927SAndroid Build Coastguard Worker
807*61046927SAndroid Build Coastguard Worker if (format_props2) {
808*61046927SAndroid Build Coastguard Worker format_props2->format = format_props->format;
809*61046927SAndroid Build Coastguard Worker format_props2->externalFormat = format_props->externalFormat;
810*61046927SAndroid Build Coastguard Worker format_props2->formatFeatures =
811*61046927SAndroid Build Coastguard Worker (VkFormatFeatureFlags2)format_props->formatFeatures;
812*61046927SAndroid Build Coastguard Worker format_props2->samplerYcbcrConversionComponents =
813*61046927SAndroid Build Coastguard Worker format_props->samplerYcbcrConversionComponents;
814*61046927SAndroid Build Coastguard Worker format_props2->suggestedYcbcrModel =
815*61046927SAndroid Build Coastguard Worker format_props->suggestedYcbcrModel;
816*61046927SAndroid Build Coastguard Worker format_props2->suggestedYcbcrRange =
817*61046927SAndroid Build Coastguard Worker format_props->suggestedYcbcrRange;
818*61046927SAndroid Build Coastguard Worker format_props2->suggestedXChromaOffset =
819*61046927SAndroid Build Coastguard Worker format_props->suggestedXChromaOffset;
820*61046927SAndroid Build Coastguard Worker format_props2->suggestedYChromaOffset =
821*61046927SAndroid Build Coastguard Worker format_props->suggestedYChromaOffset;
822*61046927SAndroid Build Coastguard Worker }
823*61046927SAndroid Build Coastguard Worker }
824*61046927SAndroid Build Coastguard Worker
825*61046927SAndroid Build Coastguard Worker dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(
826*61046927SAndroid Build Coastguard Worker AHardwareBuffer_getNativeHandle(buffer));
827*61046927SAndroid Build Coastguard Worker if (dma_buf_fd < 0)
828*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
829*61046927SAndroid Build Coastguard Worker
830*61046927SAndroid Build Coastguard Worker result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size,
831*61046927SAndroid Build Coastguard Worker &mem_type_bits);
832*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
833*61046927SAndroid Build Coastguard Worker return vn_error(dev->instance, result);
834*61046927SAndroid Build Coastguard Worker
835*61046927SAndroid Build Coastguard Worker pProperties->allocationSize = alloc_size;
836*61046927SAndroid Build Coastguard Worker pProperties->memoryTypeBits = mem_type_bits;
837*61046927SAndroid Build Coastguard Worker
838*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
839*61046927SAndroid Build Coastguard Worker }
840*61046927SAndroid Build Coastguard Worker
841*61046927SAndroid Build Coastguard Worker static AHardwareBuffer *
vn_android_ahb_allocate(uint32_t width,uint32_t height,uint32_t layers,uint32_t format,uint64_t usage)842*61046927SAndroid Build Coastguard Worker vn_android_ahb_allocate(uint32_t width,
843*61046927SAndroid Build Coastguard Worker uint32_t height,
844*61046927SAndroid Build Coastguard Worker uint32_t layers,
845*61046927SAndroid Build Coastguard Worker uint32_t format,
846*61046927SAndroid Build Coastguard Worker uint64_t usage)
847*61046927SAndroid Build Coastguard Worker {
848*61046927SAndroid Build Coastguard Worker AHardwareBuffer *ahb = NULL;
849*61046927SAndroid Build Coastguard Worker AHardwareBuffer_Desc desc;
850*61046927SAndroid Build Coastguard Worker int ret = 0;
851*61046927SAndroid Build Coastguard Worker
852*61046927SAndroid Build Coastguard Worker memset(&desc, 0, sizeof(desc));
853*61046927SAndroid Build Coastguard Worker desc.width = width;
854*61046927SAndroid Build Coastguard Worker desc.height = height;
855*61046927SAndroid Build Coastguard Worker desc.layers = layers;
856*61046927SAndroid Build Coastguard Worker desc.format = format;
857*61046927SAndroid Build Coastguard Worker desc.usage = usage;
858*61046927SAndroid Build Coastguard Worker
859*61046927SAndroid Build Coastguard Worker ret = AHardwareBuffer_allocate(&desc, &ahb);
860*61046927SAndroid Build Coastguard Worker if (ret) {
861*61046927SAndroid Build Coastguard Worker /* We just log the error code here for now since the platform falsely
862*61046927SAndroid Build Coastguard Worker * maps all gralloc allocation failures to oom.
863*61046927SAndroid Build Coastguard Worker */
864*61046927SAndroid Build Coastguard Worker vn_log(NULL, "AHB alloc(w=%u,h=%u,l=%u,f=%u,u=%" PRIu64 ") failed(%d)",
865*61046927SAndroid Build Coastguard Worker width, height, layers, format, usage, ret);
866*61046927SAndroid Build Coastguard Worker return NULL;
867*61046927SAndroid Build Coastguard Worker }
868*61046927SAndroid Build Coastguard Worker
869*61046927SAndroid Build Coastguard Worker return ahb;
870*61046927SAndroid Build Coastguard Worker }
871*61046927SAndroid Build Coastguard Worker
872*61046927SAndroid Build Coastguard Worker bool
vn_android_get_drm_format_modifier_info(const VkPhysicalDeviceImageFormatInfo2 * format_info,VkPhysicalDeviceImageDrmFormatModifierInfoEXT * out_info)873*61046927SAndroid Build Coastguard Worker vn_android_get_drm_format_modifier_info(
874*61046927SAndroid Build Coastguard Worker const VkPhysicalDeviceImageFormatInfo2 *format_info,
875*61046927SAndroid Build Coastguard Worker VkPhysicalDeviceImageDrmFormatModifierInfoEXT *out_info)
876*61046927SAndroid Build Coastguard Worker {
877*61046927SAndroid Build Coastguard Worker /* To properly fill VkPhysicalDeviceImageDrmFormatModifierInfoEXT, we have
878*61046927SAndroid Build Coastguard Worker * to allocate an ahb to retrieve the drm format modifier. For the image
879*61046927SAndroid Build Coastguard Worker * sharing mode, we assume VK_SHARING_MODE_EXCLUSIVE for now.
880*61046927SAndroid Build Coastguard Worker */
881*61046927SAndroid Build Coastguard Worker AHardwareBuffer *ahb = NULL;
882*61046927SAndroid Build Coastguard Worker uint32_t format = 0;
883*61046927SAndroid Build Coastguard Worker uint64_t usage = 0;
884*61046927SAndroid Build Coastguard Worker struct vn_android_gralloc_buffer_properties buf_props;
885*61046927SAndroid Build Coastguard Worker
886*61046927SAndroid Build Coastguard Worker assert(format_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
887*61046927SAndroid Build Coastguard Worker
888*61046927SAndroid Build Coastguard Worker format = vk_image_format_to_ahb_format(format_info->format);
889*61046927SAndroid Build Coastguard Worker if (!format)
890*61046927SAndroid Build Coastguard Worker return false;
891*61046927SAndroid Build Coastguard Worker
892*61046927SAndroid Build Coastguard Worker usage =
893*61046927SAndroid Build Coastguard Worker vk_image_usage_to_ahb_usage(format_info->flags, format_info->usage);
894*61046927SAndroid Build Coastguard Worker ahb = vn_android_ahb_allocate(16, 16, 1, format, usage);
895*61046927SAndroid Build Coastguard Worker if (!ahb)
896*61046927SAndroid Build Coastguard Worker return false;
897*61046927SAndroid Build Coastguard Worker
898*61046927SAndroid Build Coastguard Worker if (!vn_android_gralloc_get_buffer_properties(
899*61046927SAndroid Build Coastguard Worker AHardwareBuffer_getNativeHandle(ahb), &buf_props)) {
900*61046927SAndroid Build Coastguard Worker AHardwareBuffer_release(ahb);
901*61046927SAndroid Build Coastguard Worker return false;
902*61046927SAndroid Build Coastguard Worker }
903*61046927SAndroid Build Coastguard Worker
904*61046927SAndroid Build Coastguard Worker *out_info = (VkPhysicalDeviceImageDrmFormatModifierInfoEXT){
905*61046927SAndroid Build Coastguard Worker .sType =
906*61046927SAndroid Build Coastguard Worker VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
907*61046927SAndroid Build Coastguard Worker .pNext = NULL,
908*61046927SAndroid Build Coastguard Worker .drmFormatModifier = buf_props.modifier,
909*61046927SAndroid Build Coastguard Worker .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
910*61046927SAndroid Build Coastguard Worker .queueFamilyIndexCount = 0,
911*61046927SAndroid Build Coastguard Worker .pQueueFamilyIndices = NULL,
912*61046927SAndroid Build Coastguard Worker };
913*61046927SAndroid Build Coastguard Worker
914*61046927SAndroid Build Coastguard Worker AHardwareBuffer_release(ahb);
915*61046927SAndroid Build Coastguard Worker return true;
916*61046927SAndroid Build Coastguard Worker }
917*61046927SAndroid Build Coastguard Worker
918*61046927SAndroid Build Coastguard Worker VkResult
vn_android_device_import_ahb(struct vn_device * dev,struct vn_device_memory * mem,const struct VkMemoryDedicatedAllocateInfo * dedicated_info)919*61046927SAndroid Build Coastguard Worker vn_android_device_import_ahb(
920*61046927SAndroid Build Coastguard Worker struct vn_device *dev,
921*61046927SAndroid Build Coastguard Worker struct vn_device_memory *mem,
922*61046927SAndroid Build Coastguard Worker const struct VkMemoryDedicatedAllocateInfo *dedicated_info)
923*61046927SAndroid Build Coastguard Worker {
924*61046927SAndroid Build Coastguard Worker const struct vk_device_memory *mem_vk = &mem->base.base;
925*61046927SAndroid Build Coastguard Worker const native_handle_t *handle = NULL;
926*61046927SAndroid Build Coastguard Worker int dma_buf_fd = -1;
927*61046927SAndroid Build Coastguard Worker int dup_fd = -1;
928*61046927SAndroid Build Coastguard Worker uint64_t alloc_size = 0;
929*61046927SAndroid Build Coastguard Worker uint32_t mem_type_bits = 0;
930*61046927SAndroid Build Coastguard Worker uint32_t mem_type_index = mem_vk->memory_type_index;
931*61046927SAndroid Build Coastguard Worker bool force_unmappable = false;
932*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
933*61046927SAndroid Build Coastguard Worker
934*61046927SAndroid Build Coastguard Worker handle = AHardwareBuffer_getNativeHandle(mem_vk->ahardware_buffer);
935*61046927SAndroid Build Coastguard Worker dma_buf_fd = vn_android_gralloc_get_dma_buf_fd(handle);
936*61046927SAndroid Build Coastguard Worker if (dma_buf_fd < 0)
937*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
938*61046927SAndroid Build Coastguard Worker
939*61046927SAndroid Build Coastguard Worker result = vn_get_memory_dma_buf_properties(dev, dma_buf_fd, &alloc_size,
940*61046927SAndroid Build Coastguard Worker &mem_type_bits);
941*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
942*61046927SAndroid Build Coastguard Worker return result;
943*61046927SAndroid Build Coastguard Worker
944*61046927SAndroid Build Coastguard Worker /* If ahb is for an image, finish the deferred image creation first */
945*61046927SAndroid Build Coastguard Worker if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
946*61046927SAndroid Build Coastguard Worker struct vn_image *img = vn_image_from_handle(dedicated_info->image);
947*61046927SAndroid Build Coastguard Worker struct vn_android_image_builder builder;
948*61046927SAndroid Build Coastguard Worker
949*61046927SAndroid Build Coastguard Worker result = vn_android_get_image_builder(dev, &img->deferred_info->create,
950*61046927SAndroid Build Coastguard Worker handle, &builder);
951*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
952*61046927SAndroid Build Coastguard Worker return result;
953*61046927SAndroid Build Coastguard Worker
954*61046927SAndroid Build Coastguard Worker result = vn_image_init_deferred(dev, &builder.create, img);
955*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
956*61046927SAndroid Build Coastguard Worker return result;
957*61046927SAndroid Build Coastguard Worker
958*61046927SAndroid Build Coastguard Worker const VkMemoryRequirements *mem_req =
959*61046927SAndroid Build Coastguard Worker &img->requirements[0].memory.memoryRequirements;
960*61046927SAndroid Build Coastguard Worker if (alloc_size < mem_req->size) {
961*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
962*61046927SAndroid Build Coastguard Worker "alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")",
963*61046927SAndroid Build Coastguard Worker alloc_size, mem_req->size);
964*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
965*61046927SAndroid Build Coastguard Worker }
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker alloc_size = mem_req->size;
968*61046927SAndroid Build Coastguard Worker
969*61046927SAndroid Build Coastguard Worker /* Per spec 11.2.3. Device Memory Allocation
970*61046927SAndroid Build Coastguard Worker *
971*61046927SAndroid Build Coastguard Worker * If the parameters define an export operation and the external handle
972*61046927SAndroid Build Coastguard Worker * type is
973*61046927SAndroid Build Coastguard Worker * VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
974*61046927SAndroid Build Coastguard Worker * implementations should not strictly follow memoryTypeIndex. Instead,
975*61046927SAndroid Build Coastguard Worker * they should modify the allocation internally to use the required
976*61046927SAndroid Build Coastguard Worker * memory type for the application’s given usage. This is because for an
977*61046927SAndroid Build Coastguard Worker * export operation, there is currently no way for the client to know
978*61046927SAndroid Build Coastguard Worker * the memory type index before allocating.
979*61046927SAndroid Build Coastguard Worker */
980*61046927SAndroid Build Coastguard Worker if (!(mem_vk->import_handle_type &
981*61046927SAndroid Build Coastguard Worker VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
982*61046927SAndroid Build Coastguard Worker if ((mem_type_bits & mem_req->memoryTypeBits) == 0) {
983*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "memoryTypeBits: img(0x%X) fd(0x%X)",
984*61046927SAndroid Build Coastguard Worker mem_req->memoryTypeBits, mem_type_bits);
985*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
986*61046927SAndroid Build Coastguard Worker }
987*61046927SAndroid Build Coastguard Worker
988*61046927SAndroid Build Coastguard Worker mem_type_index = ffs(mem_type_bits & mem_req->memoryTypeBits) - 1;
989*61046927SAndroid Build Coastguard Worker }
990*61046927SAndroid Build Coastguard Worker
991*61046927SAndroid Build Coastguard Worker /* XXX Workaround before we use cross-domain backend in minigbm. The
992*61046927SAndroid Build Coastguard Worker * blob_mem allocated from virgl backend can have a queried guest
993*61046927SAndroid Build Coastguard Worker * mappable size smaller than the size returned from image memory
994*61046927SAndroid Build Coastguard Worker * requirement.
995*61046927SAndroid Build Coastguard Worker */
996*61046927SAndroid Build Coastguard Worker force_unmappable = true;
997*61046927SAndroid Build Coastguard Worker }
998*61046927SAndroid Build Coastguard Worker
999*61046927SAndroid Build Coastguard Worker if (dedicated_info && dedicated_info->buffer != VK_NULL_HANDLE) {
1000*61046927SAndroid Build Coastguard Worker struct vn_buffer *buf = vn_buffer_from_handle(dedicated_info->buffer);
1001*61046927SAndroid Build Coastguard Worker const VkMemoryRequirements *mem_req =
1002*61046927SAndroid Build Coastguard Worker &buf->requirements.memory.memoryRequirements;
1003*61046927SAndroid Build Coastguard Worker if (alloc_size < mem_req->size) {
1004*61046927SAndroid Build Coastguard Worker vn_log(dev->instance,
1005*61046927SAndroid Build Coastguard Worker "alloc_size(%" PRIu64 ") mem_req->size(%" PRIu64 ")",
1006*61046927SAndroid Build Coastguard Worker alloc_size, mem_req->size);
1007*61046927SAndroid Build Coastguard Worker return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1008*61046927SAndroid Build Coastguard Worker }
1009*61046927SAndroid Build Coastguard Worker
1010*61046927SAndroid Build Coastguard Worker alloc_size = mem_req->size;
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker assert((1 << mem_type_index) & mem_req->memoryTypeBits);
1013*61046927SAndroid Build Coastguard Worker }
1014*61046927SAndroid Build Coastguard Worker
1015*61046927SAndroid Build Coastguard Worker assert((1 << mem_type_index) & mem_type_bits);
1016*61046927SAndroid Build Coastguard Worker
1017*61046927SAndroid Build Coastguard Worker errno = 0;
1018*61046927SAndroid Build Coastguard Worker dup_fd = os_dupfd_cloexec(dma_buf_fd);
1019*61046927SAndroid Build Coastguard Worker if (dup_fd < 0)
1020*61046927SAndroid Build Coastguard Worker return (errno == EMFILE) ? VK_ERROR_TOO_MANY_OBJECTS
1021*61046927SAndroid Build Coastguard Worker : VK_ERROR_OUT_OF_HOST_MEMORY;
1022*61046927SAndroid Build Coastguard Worker
1023*61046927SAndroid Build Coastguard Worker /* Spec requires AHB export info to be present, so we must strip it. In
1024*61046927SAndroid Build Coastguard Worker * practice, the AHB import path here only needs the main allocation info
1025*61046927SAndroid Build Coastguard Worker * and the dedicated_info.
1026*61046927SAndroid Build Coastguard Worker */
1027*61046927SAndroid Build Coastguard Worker VkMemoryDedicatedAllocateInfo local_dedicated_info;
1028*61046927SAndroid Build Coastguard Worker /* Override when dedicated_info exists and is not the tail struct. */
1029*61046927SAndroid Build Coastguard Worker if (dedicated_info && dedicated_info->pNext) {
1030*61046927SAndroid Build Coastguard Worker local_dedicated_info = *dedicated_info;
1031*61046927SAndroid Build Coastguard Worker local_dedicated_info.pNext = NULL;
1032*61046927SAndroid Build Coastguard Worker dedicated_info = &local_dedicated_info;
1033*61046927SAndroid Build Coastguard Worker }
1034*61046927SAndroid Build Coastguard Worker const VkMemoryAllocateInfo local_alloc_info = {
1035*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1036*61046927SAndroid Build Coastguard Worker .pNext = dedicated_info,
1037*61046927SAndroid Build Coastguard Worker .allocationSize = alloc_size,
1038*61046927SAndroid Build Coastguard Worker .memoryTypeIndex = mem_type_index,
1039*61046927SAndroid Build Coastguard Worker };
1040*61046927SAndroid Build Coastguard Worker result = vn_device_memory_import_dma_buf(dev, mem, &local_alloc_info,
1041*61046927SAndroid Build Coastguard Worker force_unmappable, dup_fd);
1042*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
1043*61046927SAndroid Build Coastguard Worker close(dup_fd);
1044*61046927SAndroid Build Coastguard Worker return result;
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker
1047*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1048*61046927SAndroid Build Coastguard Worker }
1049*61046927SAndroid Build Coastguard Worker
1050*61046927SAndroid Build Coastguard Worker uint32_t
vn_android_get_ahb_buffer_memory_type_bits(struct vn_device * dev)1051*61046927SAndroid Build Coastguard Worker vn_android_get_ahb_buffer_memory_type_bits(struct vn_device *dev)
1052*61046927SAndroid Build Coastguard Worker {
1053*61046927SAndroid Build Coastguard Worker static const uint32_t format = AHARDWAREBUFFER_FORMAT_BLOB;
1054*61046927SAndroid Build Coastguard Worker /* ensure dma_buf_memory_type_bits covers host visible usage */
1055*61046927SAndroid Build Coastguard Worker static const uint64_t usage = AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER |
1056*61046927SAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_CPU_READ_RARELY |
1057*61046927SAndroid Build Coastguard Worker AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
1058*61046927SAndroid Build Coastguard Worker AHardwareBuffer *ahb = vn_android_ahb_allocate(4096, 1, 1, format, usage);
1059*61046927SAndroid Build Coastguard Worker if (!ahb)
1060*61046927SAndroid Build Coastguard Worker return 0;
1061*61046927SAndroid Build Coastguard Worker
1062*61046927SAndroid Build Coastguard Worker int dma_buf_fd =
1063*61046927SAndroid Build Coastguard Worker vn_android_gralloc_get_dma_buf_fd(AHardwareBuffer_getNativeHandle(ahb));
1064*61046927SAndroid Build Coastguard Worker if (dma_buf_fd < 0) {
1065*61046927SAndroid Build Coastguard Worker AHardwareBuffer_release(ahb);
1066*61046927SAndroid Build Coastguard Worker return 0;
1067*61046927SAndroid Build Coastguard Worker }
1068*61046927SAndroid Build Coastguard Worker
1069*61046927SAndroid Build Coastguard Worker uint64_t alloc_size = 0;
1070*61046927SAndroid Build Coastguard Worker uint32_t mem_type_bits = 0;
1071*61046927SAndroid Build Coastguard Worker VkResult ret = vn_get_memory_dma_buf_properties(
1072*61046927SAndroid Build Coastguard Worker dev, dma_buf_fd, &alloc_size, &mem_type_bits);
1073*61046927SAndroid Build Coastguard Worker /* release ahb first as below no longer needs it */
1074*61046927SAndroid Build Coastguard Worker AHardwareBuffer_release(ahb);
1075*61046927SAndroid Build Coastguard Worker
1076*61046927SAndroid Build Coastguard Worker if (ret != VK_SUCCESS) {
1077*61046927SAndroid Build Coastguard Worker vn_log(dev->instance, "AHB buffer mem type bits query failed %d", ret);
1078*61046927SAndroid Build Coastguard Worker return 0;
1079*61046927SAndroid Build Coastguard Worker }
1080*61046927SAndroid Build Coastguard Worker
1081*61046927SAndroid Build Coastguard Worker return mem_type_bits;
1082*61046927SAndroid Build Coastguard Worker }
1083