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