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