1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2019 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv and radv which are: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 8bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vn_image.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_image.h" 14bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_image_view.h" 15bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_sampler.h" 16bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h" 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#include "vn_android.h" 19bf215546Sopenharmony_ci#include "vn_device.h" 20bf215546Sopenharmony_ci#include "vn_device_memory.h" 21bf215546Sopenharmony_ci#include "vn_wsi.h" 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_cistatic void 24bf215546Sopenharmony_civn_image_init_memory_requirements(struct vn_image *img, 25bf215546Sopenharmony_ci struct vn_device *dev, 26bf215546Sopenharmony_ci const VkImageCreateInfo *create_info) 27bf215546Sopenharmony_ci{ 28bf215546Sopenharmony_ci uint32_t plane_count = 1; 29bf215546Sopenharmony_ci if (create_info->flags & VK_IMAGE_CREATE_DISJOINT_BIT) { 30bf215546Sopenharmony_ci /* TODO VkDrmFormatModifierPropertiesEXT::drmFormatModifierPlaneCount */ 31bf215546Sopenharmony_ci assert(create_info->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT); 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci switch (create_info->format) { 34bf215546Sopenharmony_ci case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 35bf215546Sopenharmony_ci case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 36bf215546Sopenharmony_ci case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 37bf215546Sopenharmony_ci case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 38bf215546Sopenharmony_ci case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 39bf215546Sopenharmony_ci case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 40bf215546Sopenharmony_ci case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 41bf215546Sopenharmony_ci case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 42bf215546Sopenharmony_ci plane_count = 2; 43bf215546Sopenharmony_ci break; 44bf215546Sopenharmony_ci case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 45bf215546Sopenharmony_ci case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 46bf215546Sopenharmony_ci case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 47bf215546Sopenharmony_ci case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 48bf215546Sopenharmony_ci case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 49bf215546Sopenharmony_ci case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 50bf215546Sopenharmony_ci case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 51bf215546Sopenharmony_ci case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 52bf215546Sopenharmony_ci case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 53bf215546Sopenharmony_ci case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 54bf215546Sopenharmony_ci case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 55bf215546Sopenharmony_ci case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 56bf215546Sopenharmony_ci plane_count = 3; 57bf215546Sopenharmony_ci break; 58bf215546Sopenharmony_ci default: 59bf215546Sopenharmony_ci plane_count = 1; 60bf215546Sopenharmony_ci break; 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci } 63bf215546Sopenharmony_ci assert(plane_count <= ARRAY_SIZE(img->requirements)); 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci /* TODO add a per-device cache for the requirements */ 66bf215546Sopenharmony_ci for (uint32_t i = 0; i < plane_count; i++) { 67bf215546Sopenharmony_ci img->requirements[i].memory.sType = 68bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; 69bf215546Sopenharmony_ci img->requirements[i].memory.pNext = &img->requirements[i].dedicated; 70bf215546Sopenharmony_ci img->requirements[i].dedicated.sType = 71bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; 72bf215546Sopenharmony_ci img->requirements[i].dedicated.pNext = NULL; 73bf215546Sopenharmony_ci } 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 76bf215546Sopenharmony_ci VkImage img_handle = vn_image_to_handle(img); 77bf215546Sopenharmony_ci if (plane_count == 1) { 78bf215546Sopenharmony_ci vn_call_vkGetImageMemoryRequirements2( 79bf215546Sopenharmony_ci dev->instance, dev_handle, 80bf215546Sopenharmony_ci &(VkImageMemoryRequirementsInfo2){ 81bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, 82bf215546Sopenharmony_ci .image = img_handle, 83bf215546Sopenharmony_ci }, 84bf215546Sopenharmony_ci &img->requirements[0].memory); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci /* AHB backed image requires dedicated allocation */ 87bf215546Sopenharmony_ci if (img->deferred_info) { 88bf215546Sopenharmony_ci img->requirements[0].dedicated.prefersDedicatedAllocation = VK_TRUE; 89bf215546Sopenharmony_ci img->requirements[0].dedicated.requiresDedicatedAllocation = VK_TRUE; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci } else { 92bf215546Sopenharmony_ci for (uint32_t i = 0; i < plane_count; i++) { 93bf215546Sopenharmony_ci vn_call_vkGetImageMemoryRequirements2( 94bf215546Sopenharmony_ci dev->instance, dev_handle, 95bf215546Sopenharmony_ci &(VkImageMemoryRequirementsInfo2){ 96bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, 97bf215546Sopenharmony_ci .pNext = 98bf215546Sopenharmony_ci &(VkImagePlaneMemoryRequirementsInfo){ 99bf215546Sopenharmony_ci .sType = 100bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, 101bf215546Sopenharmony_ci .planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT << i, 102bf215546Sopenharmony_ci }, 103bf215546Sopenharmony_ci .image = img_handle, 104bf215546Sopenharmony_ci }, 105bf215546Sopenharmony_ci &img->requirements[i].memory); 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci } 108bf215546Sopenharmony_ci} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_cistatic VkResult 111bf215546Sopenharmony_civn_image_deferred_info_init(struct vn_image *img, 112bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 113bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 114bf215546Sopenharmony_ci{ 115bf215546Sopenharmony_ci struct vn_image_create_deferred_info *info = NULL; 116bf215546Sopenharmony_ci VkBaseOutStructure *dst = NULL; 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci info = vk_zalloc(alloc, sizeof(*info), VN_DEFAULT_ALIGN, 119bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 120bf215546Sopenharmony_ci if (!info) 121bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci info->create = *create_info; 124bf215546Sopenharmony_ci dst = (void *)&info->create; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci vk_foreach_struct_const(src, create_info->pNext) { 127bf215546Sopenharmony_ci void *pnext = NULL; 128bf215546Sopenharmony_ci switch (src->sType) { 129bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: { 130bf215546Sopenharmony_ci /* 12.3. Images 131bf215546Sopenharmony_ci * 132bf215546Sopenharmony_ci * If viewFormatCount is zero, pViewFormats is ignored and the image 133bf215546Sopenharmony_ci * is created as if the VkImageFormatListCreateInfo structure were 134bf215546Sopenharmony_ci * not included in the pNext chain of VkImageCreateInfo. 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci if (!((const VkImageFormatListCreateInfo *)src)->viewFormatCount) 137bf215546Sopenharmony_ci break; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci memcpy(&info->list, src, sizeof(info->list)); 140bf215546Sopenharmony_ci pnext = &info->list; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci /* need a deep copy for view formats array */ 143bf215546Sopenharmony_ci const size_t size = sizeof(VkFormat) * info->list.viewFormatCount; 144bf215546Sopenharmony_ci VkFormat *view_formats = vk_zalloc( 145bf215546Sopenharmony_ci alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 146bf215546Sopenharmony_ci if (!view_formats) { 147bf215546Sopenharmony_ci vk_free(alloc, info); 148bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 149bf215546Sopenharmony_ci } 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci memcpy(view_formats, 152bf215546Sopenharmony_ci ((const VkImageFormatListCreateInfo *)src)->pViewFormats, 153bf215546Sopenharmony_ci size); 154bf215546Sopenharmony_ci info->list.pViewFormats = view_formats; 155bf215546Sopenharmony_ci } break; 156bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO: 157bf215546Sopenharmony_ci memcpy(&info->stencil, src, sizeof(info->stencil)); 158bf215546Sopenharmony_ci pnext = &info->stencil; 159bf215546Sopenharmony_ci break; 160bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID: 161bf215546Sopenharmony_ci /* we should have translated the external format */ 162bf215546Sopenharmony_ci assert(create_info->format != VK_FORMAT_UNDEFINED); 163bf215546Sopenharmony_ci info->from_external_format = 164bf215546Sopenharmony_ci ((const VkExternalFormatANDROID *)src)->externalFormat; 165bf215546Sopenharmony_ci break; 166bf215546Sopenharmony_ci default: 167bf215546Sopenharmony_ci break; 168bf215546Sopenharmony_ci } 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci if (pnext) { 171bf215546Sopenharmony_ci dst->pNext = pnext; 172bf215546Sopenharmony_ci dst = pnext; 173bf215546Sopenharmony_ci } 174bf215546Sopenharmony_ci } 175bf215546Sopenharmony_ci dst->pNext = NULL; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci img->deferred_info = info; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci return VK_SUCCESS; 180bf215546Sopenharmony_ci} 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_cistatic void 183bf215546Sopenharmony_civn_image_deferred_info_fini(struct vn_image *img, 184bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci if (!img->deferred_info) 187bf215546Sopenharmony_ci return; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci if (img->deferred_info->list.pViewFormats) 190bf215546Sopenharmony_ci vk_free(alloc, (void *)img->deferred_info->list.pViewFormats); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci vk_free(alloc, img->deferred_info); 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cistatic VkResult 196bf215546Sopenharmony_civn_image_init(struct vn_device *dev, 197bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 198bf215546Sopenharmony_ci struct vn_image *img) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci VkDevice device = vn_device_to_handle(dev); 201bf215546Sopenharmony_ci VkImage image = vn_image_to_handle(img); 202bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci img->sharing_mode = create_info->sharingMode; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci /* TODO async */ 207bf215546Sopenharmony_ci result = 208bf215546Sopenharmony_ci vn_call_vkCreateImage(dev->instance, device, create_info, NULL, &image); 209bf215546Sopenharmony_ci if (result != VK_SUCCESS) 210bf215546Sopenharmony_ci return result; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci vn_image_init_memory_requirements(img, dev, create_info); 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci return VK_SUCCESS; 215bf215546Sopenharmony_ci} 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ciVkResult 218bf215546Sopenharmony_civn_image_create(struct vn_device *dev, 219bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 220bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 221bf215546Sopenharmony_ci struct vn_image **out_img) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci struct vn_image *img = NULL; 224bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN, 227bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 228bf215546Sopenharmony_ci if (!img) 229bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base); 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci result = vn_image_init(dev, create_info, img); 234bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 235bf215546Sopenharmony_ci vn_object_base_fini(&img->base); 236bf215546Sopenharmony_ci vk_free(alloc, img); 237bf215546Sopenharmony_ci return result; 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci *out_img = img; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci return VK_SUCCESS; 243bf215546Sopenharmony_ci} 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ciVkResult 246bf215546Sopenharmony_civn_image_init_deferred(struct vn_device *dev, 247bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 248bf215546Sopenharmony_ci struct vn_image *img) 249bf215546Sopenharmony_ci{ 250bf215546Sopenharmony_ci VkResult result = vn_image_init(dev, create_info, img); 251bf215546Sopenharmony_ci img->deferred_info->initialized = result == VK_SUCCESS; 252bf215546Sopenharmony_ci return result; 253bf215546Sopenharmony_ci} 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ciVkResult 256bf215546Sopenharmony_civn_image_create_deferred(struct vn_device *dev, 257bf215546Sopenharmony_ci const VkImageCreateInfo *create_info, 258bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 259bf215546Sopenharmony_ci struct vn_image **out_img) 260bf215546Sopenharmony_ci{ 261bf215546Sopenharmony_ci struct vn_image *img = NULL; 262bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN, 265bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 266bf215546Sopenharmony_ci if (!img) 267bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 268bf215546Sopenharmony_ci 269bf215546Sopenharmony_ci vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base); 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci result = vn_image_deferred_info_init(img, create_info, alloc); 272bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 273bf215546Sopenharmony_ci vn_object_base_fini(&img->base); 274bf215546Sopenharmony_ci vk_free(alloc, img); 275bf215546Sopenharmony_ci return result; 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci *out_img = img; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci return VK_SUCCESS; 281bf215546Sopenharmony_ci} 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci/* image commands */ 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ciVkResult 286bf215546Sopenharmony_civn_CreateImage(VkDevice device, 287bf215546Sopenharmony_ci const VkImageCreateInfo *pCreateInfo, 288bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 289bf215546Sopenharmony_ci VkImage *pImage) 290bf215546Sopenharmony_ci{ 291bf215546Sopenharmony_ci VN_TRACE_FUNC(); 292bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 293bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 294bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 295bf215546Sopenharmony_ci struct vn_image *img; 296bf215546Sopenharmony_ci VkResult result; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci const struct wsi_image_create_info *wsi_info = 299bf215546Sopenharmony_ci vn_wsi_find_wsi_image_create_info(pCreateInfo); 300bf215546Sopenharmony_ci const VkNativeBufferANDROID *anb_info = 301bf215546Sopenharmony_ci vn_android_find_native_buffer(pCreateInfo); 302bf215546Sopenharmony_ci const VkExternalMemoryImageCreateInfo *external_info = 303bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, 304bf215546Sopenharmony_ci EXTERNAL_MEMORY_IMAGE_CREATE_INFO); 305bf215546Sopenharmony_ci const bool ahb_info = 306bf215546Sopenharmony_ci external_info && 307bf215546Sopenharmony_ci external_info->handleTypes == 308bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci#ifdef ANDROID 311bf215546Sopenharmony_ci /* VkImageSwapchainCreateInfoKHR is not useful at all */ 312bf215546Sopenharmony_ci const VkImageSwapchainCreateInfoKHR *swapchain_info = NULL; 313bf215546Sopenharmony_ci#else 314bf215546Sopenharmony_ci const VkImageSwapchainCreateInfoKHR *swapchain_info = vk_find_struct_const( 315bf215546Sopenharmony_ci pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); 316bf215546Sopenharmony_ci if (swapchain_info && !swapchain_info->swapchain) 317bf215546Sopenharmony_ci swapchain_info = NULL; 318bf215546Sopenharmony_ci#endif 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci if (wsi_info) { 321bf215546Sopenharmony_ci result = vn_wsi_create_image(dev, pCreateInfo, wsi_info, alloc, &img); 322bf215546Sopenharmony_ci } else if (anb_info) { 323bf215546Sopenharmony_ci result = 324bf215546Sopenharmony_ci vn_android_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img); 325bf215546Sopenharmony_ci } else if (ahb_info) { 326bf215546Sopenharmony_ci result = vn_android_image_from_ahb(dev, pCreateInfo, alloc, &img); 327bf215546Sopenharmony_ci } else if (swapchain_info) { 328bf215546Sopenharmony_ci result = vn_wsi_create_image_from_swapchain( 329bf215546Sopenharmony_ci dev, pCreateInfo, swapchain_info, alloc, &img); 330bf215546Sopenharmony_ci } else { 331bf215546Sopenharmony_ci result = vn_image_create(dev, pCreateInfo, alloc, &img); 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci if (result != VK_SUCCESS) 335bf215546Sopenharmony_ci return vn_error(dev->instance, result); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci *pImage = vn_image_to_handle(img); 338bf215546Sopenharmony_ci return VK_SUCCESS; 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_civoid 342bf215546Sopenharmony_civn_DestroyImage(VkDevice device, 343bf215546Sopenharmony_ci VkImage image, 344bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 345bf215546Sopenharmony_ci{ 346bf215546Sopenharmony_ci VN_TRACE_FUNC(); 347bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 348bf215546Sopenharmony_ci struct vn_image *img = vn_image_from_handle(image); 349bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 350bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci if (!img) 353bf215546Sopenharmony_ci return; 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ci if (img->wsi.memory && img->wsi.memory_owned) { 356bf215546Sopenharmony_ci VkDeviceMemory mem_handle = vn_device_memory_to_handle(img->wsi.memory); 357bf215546Sopenharmony_ci vn_FreeMemory(device, mem_handle, pAllocator); 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci /* must not ask renderer to destroy uninitialized deferred image */ 361bf215546Sopenharmony_ci if (!img->deferred_info || img->deferred_info->initialized) 362bf215546Sopenharmony_ci vn_async_vkDestroyImage(dev->instance, device, image, NULL); 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci vn_image_deferred_info_fini(img, alloc); 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci vn_object_base_fini(&img->base); 367bf215546Sopenharmony_ci vk_free(alloc, img); 368bf215546Sopenharmony_ci} 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_civoid 371bf215546Sopenharmony_civn_GetImageMemoryRequirements2(VkDevice device, 372bf215546Sopenharmony_ci const VkImageMemoryRequirementsInfo2 *pInfo, 373bf215546Sopenharmony_ci VkMemoryRequirements2 *pMemoryRequirements) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci const struct vn_image *img = vn_image_from_handle(pInfo->image); 376bf215546Sopenharmony_ci union { 377bf215546Sopenharmony_ci VkBaseOutStructure *pnext; 378bf215546Sopenharmony_ci VkMemoryRequirements2 *two; 379bf215546Sopenharmony_ci VkMemoryDedicatedRequirements *dedicated; 380bf215546Sopenharmony_ci } u = { .two = pMemoryRequirements }; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci uint32_t plane = 0; 383bf215546Sopenharmony_ci const VkImagePlaneMemoryRequirementsInfo *plane_info = 384bf215546Sopenharmony_ci vk_find_struct_const(pInfo->pNext, 385bf215546Sopenharmony_ci IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO); 386bf215546Sopenharmony_ci if (plane_info) { 387bf215546Sopenharmony_ci switch (plane_info->planeAspect) { 388bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_PLANE_1_BIT: 389bf215546Sopenharmony_ci plane = 1; 390bf215546Sopenharmony_ci break; 391bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_PLANE_2_BIT: 392bf215546Sopenharmony_ci plane = 2; 393bf215546Sopenharmony_ci break; 394bf215546Sopenharmony_ci default: 395bf215546Sopenharmony_ci plane = 0; 396bf215546Sopenharmony_ci break; 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci while (u.pnext) { 401bf215546Sopenharmony_ci switch (u.pnext->sType) { 402bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2: 403bf215546Sopenharmony_ci u.two->memoryRequirements = 404bf215546Sopenharmony_ci img->requirements[plane].memory.memoryRequirements; 405bf215546Sopenharmony_ci break; 406bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: 407bf215546Sopenharmony_ci u.dedicated->prefersDedicatedAllocation = 408bf215546Sopenharmony_ci img->requirements[plane].dedicated.prefersDedicatedAllocation; 409bf215546Sopenharmony_ci u.dedicated->requiresDedicatedAllocation = 410bf215546Sopenharmony_ci img->requirements[plane].dedicated.requiresDedicatedAllocation; 411bf215546Sopenharmony_ci break; 412bf215546Sopenharmony_ci default: 413bf215546Sopenharmony_ci break; 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci u.pnext = u.pnext->pNext; 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci} 418bf215546Sopenharmony_ci 419bf215546Sopenharmony_civoid 420bf215546Sopenharmony_civn_GetImageSparseMemoryRequirements2( 421bf215546Sopenharmony_ci VkDevice device, 422bf215546Sopenharmony_ci const VkImageSparseMemoryRequirementsInfo2 *pInfo, 423bf215546Sopenharmony_ci uint32_t *pSparseMemoryRequirementCount, 424bf215546Sopenharmony_ci VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 425bf215546Sopenharmony_ci{ 426bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci /* TODO per-device cache */ 429bf215546Sopenharmony_ci vn_call_vkGetImageSparseMemoryRequirements2(dev->instance, device, pInfo, 430bf215546Sopenharmony_ci pSparseMemoryRequirementCount, 431bf215546Sopenharmony_ci pSparseMemoryRequirements); 432bf215546Sopenharmony_ci} 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_cistatic void 435bf215546Sopenharmony_civn_image_bind_wsi_memory(struct vn_image *img, struct vn_device_memory *mem) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci assert(img->wsi.is_wsi && !img->wsi.memory); 438bf215546Sopenharmony_ci img->wsi.memory = mem; 439bf215546Sopenharmony_ci} 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ciVkResult 442bf215546Sopenharmony_civn_BindImageMemory2(VkDevice device, 443bf215546Sopenharmony_ci uint32_t bindInfoCount, 444bf215546Sopenharmony_ci const VkBindImageMemoryInfo *pBindInfos) 445bf215546Sopenharmony_ci{ 446bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 447bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci VkBindImageMemoryInfo *local_infos = NULL; 450bf215546Sopenharmony_ci for (uint32_t i = 0; i < bindInfoCount; i++) { 451bf215546Sopenharmony_ci const VkBindImageMemoryInfo *info = &pBindInfos[i]; 452bf215546Sopenharmony_ci struct vn_image *img = vn_image_from_handle(info->image); 453bf215546Sopenharmony_ci struct vn_device_memory *mem = 454bf215546Sopenharmony_ci vn_device_memory_from_handle(info->memory); 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci /* no bind info fixup needed */ 457bf215546Sopenharmony_ci if (mem && !mem->base_memory) { 458bf215546Sopenharmony_ci if (img->wsi.is_wsi) 459bf215546Sopenharmony_ci vn_image_bind_wsi_memory(img, mem); 460bf215546Sopenharmony_ci continue; 461bf215546Sopenharmony_ci } 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci if (!mem) { 464bf215546Sopenharmony_ci#ifdef ANDROID 465bf215546Sopenharmony_ci /* TODO handle VkNativeBufferANDROID when we bump up 466bf215546Sopenharmony_ci * VN_ANDROID_NATIVE_BUFFER_SPEC_VERSION 467bf215546Sopenharmony_ci */ 468bf215546Sopenharmony_ci unreachable("VkBindImageMemoryInfo with no memory"); 469bf215546Sopenharmony_ci#else 470bf215546Sopenharmony_ci const VkBindImageMemorySwapchainInfoKHR *swapchain_info = 471bf215546Sopenharmony_ci vk_find_struct_const(info->pNext, 472bf215546Sopenharmony_ci BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR); 473bf215546Sopenharmony_ci assert(img->wsi.is_wsi && swapchain_info); 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci struct vn_image *swapchain_img = 476bf215546Sopenharmony_ci vn_image_from_handle(wsi_common_get_image( 477bf215546Sopenharmony_ci swapchain_info->swapchain, swapchain_info->imageIndex)); 478bf215546Sopenharmony_ci mem = swapchain_img->wsi.memory; 479bf215546Sopenharmony_ci#endif 480bf215546Sopenharmony_ci } 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci if (img->wsi.is_wsi) 483bf215546Sopenharmony_ci vn_image_bind_wsi_memory(img, mem); 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ci if (!local_infos) { 486bf215546Sopenharmony_ci const size_t size = sizeof(*local_infos) * bindInfoCount; 487bf215546Sopenharmony_ci local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN, 488bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 489bf215546Sopenharmony_ci if (!local_infos) 490bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci memcpy(local_infos, pBindInfos, size); 493bf215546Sopenharmony_ci } 494bf215546Sopenharmony_ci 495bf215546Sopenharmony_ci /* If mem is suballocated, mem->base_memory is non-NULL and we must 496bf215546Sopenharmony_ci * patch it in. If VkBindImageMemorySwapchainInfoKHR is given, we've 497bf215546Sopenharmony_ci * looked mem up above and also need to patch it in. 498bf215546Sopenharmony_ci */ 499bf215546Sopenharmony_ci local_infos[i].memory = vn_device_memory_to_handle( 500bf215546Sopenharmony_ci mem->base_memory ? mem->base_memory : mem); 501bf215546Sopenharmony_ci local_infos[i].memoryOffset += mem->base_offset; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci if (local_infos) 504bf215546Sopenharmony_ci pBindInfos = local_infos; 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci vn_async_vkBindImageMemory2(dev->instance, device, bindInfoCount, 507bf215546Sopenharmony_ci pBindInfos); 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci vk_free(alloc, local_infos); 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci return VK_SUCCESS; 512bf215546Sopenharmony_ci} 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ciVkResult 515bf215546Sopenharmony_civn_GetImageDrmFormatModifierPropertiesEXT( 516bf215546Sopenharmony_ci VkDevice device, 517bf215546Sopenharmony_ci VkImage image, 518bf215546Sopenharmony_ci VkImageDrmFormatModifierPropertiesEXT *pProperties) 519bf215546Sopenharmony_ci{ 520bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci /* TODO local cache */ 523bf215546Sopenharmony_ci return vn_call_vkGetImageDrmFormatModifierPropertiesEXT( 524bf215546Sopenharmony_ci dev->instance, device, image, pProperties); 525bf215546Sopenharmony_ci} 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_civoid 528bf215546Sopenharmony_civn_GetImageSubresourceLayout(VkDevice device, 529bf215546Sopenharmony_ci VkImage image, 530bf215546Sopenharmony_ci const VkImageSubresource *pSubresource, 531bf215546Sopenharmony_ci VkSubresourceLayout *pLayout) 532bf215546Sopenharmony_ci{ 533bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 534bf215546Sopenharmony_ci struct vn_image *img = vn_image_from_handle(image); 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci /* override aspect mask for wsi/ahb images with tiling modifier */ 537bf215546Sopenharmony_ci VkImageSubresource local_subresource; 538bf215546Sopenharmony_ci if ((img->wsi.is_wsi && img->wsi.tiling_override == 539bf215546Sopenharmony_ci VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) || 540bf215546Sopenharmony_ci img->deferred_info) { 541bf215546Sopenharmony_ci VkImageAspectFlags aspect = pSubresource->aspectMask; 542bf215546Sopenharmony_ci switch (aspect) { 543bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_COLOR_BIT: 544bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_DEPTH_BIT: 545bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_STENCIL_BIT: 546bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_PLANE_0_BIT: 547bf215546Sopenharmony_ci aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT; 548bf215546Sopenharmony_ci break; 549bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_PLANE_1_BIT: 550bf215546Sopenharmony_ci aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT; 551bf215546Sopenharmony_ci break; 552bf215546Sopenharmony_ci case VK_IMAGE_ASPECT_PLANE_2_BIT: 553bf215546Sopenharmony_ci aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT; 554bf215546Sopenharmony_ci break; 555bf215546Sopenharmony_ci default: 556bf215546Sopenharmony_ci break; 557bf215546Sopenharmony_ci } 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci /* only handle supported aspect override */ 560bf215546Sopenharmony_ci if (aspect != pSubresource->aspectMask) { 561bf215546Sopenharmony_ci local_subresource = *pSubresource; 562bf215546Sopenharmony_ci local_subresource.aspectMask = aspect; 563bf215546Sopenharmony_ci pSubresource = &local_subresource; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci /* TODO local cache */ 568bf215546Sopenharmony_ci vn_call_vkGetImageSubresourceLayout(dev->instance, device, image, 569bf215546Sopenharmony_ci pSubresource, pLayout); 570bf215546Sopenharmony_ci} 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci/* image view commands */ 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ciVkResult 575bf215546Sopenharmony_civn_CreateImageView(VkDevice device, 576bf215546Sopenharmony_ci const VkImageViewCreateInfo *pCreateInfo, 577bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 578bf215546Sopenharmony_ci VkImageView *pView) 579bf215546Sopenharmony_ci{ 580bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 581bf215546Sopenharmony_ci struct vn_image *img = vn_image_from_handle(pCreateInfo->image); 582bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 583bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci VkImageViewCreateInfo local_info; 586bf215546Sopenharmony_ci if (img->deferred_info && img->deferred_info->from_external_format) { 587bf215546Sopenharmony_ci assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci local_info = *pCreateInfo; 590bf215546Sopenharmony_ci local_info.format = img->deferred_info->create.format; 591bf215546Sopenharmony_ci pCreateInfo = &local_info; 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci assert(pCreateInfo->format != VK_FORMAT_UNDEFINED); 594bf215546Sopenharmony_ci } 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci struct vn_image_view *view = 597bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN, 598bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 599bf215546Sopenharmony_ci if (!view) 600bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 601bf215546Sopenharmony_ci 602bf215546Sopenharmony_ci vn_object_base_init(&view->base, VK_OBJECT_TYPE_IMAGE_VIEW, &dev->base); 603bf215546Sopenharmony_ci view->image = img; 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci VkImageView view_handle = vn_image_view_to_handle(view); 606bf215546Sopenharmony_ci vn_async_vkCreateImageView(dev->instance, device, pCreateInfo, NULL, 607bf215546Sopenharmony_ci &view_handle); 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci *pView = view_handle; 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci return VK_SUCCESS; 612bf215546Sopenharmony_ci} 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_civoid 615bf215546Sopenharmony_civn_DestroyImageView(VkDevice device, 616bf215546Sopenharmony_ci VkImageView imageView, 617bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 618bf215546Sopenharmony_ci{ 619bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 620bf215546Sopenharmony_ci struct vn_image_view *view = vn_image_view_from_handle(imageView); 621bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 622bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci if (!view) 625bf215546Sopenharmony_ci return; 626bf215546Sopenharmony_ci 627bf215546Sopenharmony_ci vn_async_vkDestroyImageView(dev->instance, device, imageView, NULL); 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci vn_object_base_fini(&view->base); 630bf215546Sopenharmony_ci vk_free(alloc, view); 631bf215546Sopenharmony_ci} 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci/* sampler commands */ 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ciVkResult 636bf215546Sopenharmony_civn_CreateSampler(VkDevice device, 637bf215546Sopenharmony_ci const VkSamplerCreateInfo *pCreateInfo, 638bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 639bf215546Sopenharmony_ci VkSampler *pSampler) 640bf215546Sopenharmony_ci{ 641bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 642bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 643bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci struct vn_sampler *sampler = 646bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*sampler), VN_DEFAULT_ALIGN, 647bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 648bf215546Sopenharmony_ci if (!sampler) 649bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci vn_object_base_init(&sampler->base, VK_OBJECT_TYPE_SAMPLER, &dev->base); 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci VkSampler sampler_handle = vn_sampler_to_handle(sampler); 654bf215546Sopenharmony_ci vn_async_vkCreateSampler(dev->instance, device, pCreateInfo, NULL, 655bf215546Sopenharmony_ci &sampler_handle); 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci *pSampler = sampler_handle; 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci return VK_SUCCESS; 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_civoid 663bf215546Sopenharmony_civn_DestroySampler(VkDevice device, 664bf215546Sopenharmony_ci VkSampler _sampler, 665bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 666bf215546Sopenharmony_ci{ 667bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 668bf215546Sopenharmony_ci struct vn_sampler *sampler = vn_sampler_from_handle(_sampler); 669bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 670bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci if (!sampler) 673bf215546Sopenharmony_ci return; 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci vn_async_vkDestroySampler(dev->instance, device, _sampler, NULL); 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci vn_object_base_fini(&sampler->base); 678bf215546Sopenharmony_ci vk_free(alloc, sampler); 679bf215546Sopenharmony_ci} 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci/* sampler YCbCr conversion commands */ 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ciVkResult 684bf215546Sopenharmony_civn_CreateSamplerYcbcrConversion( 685bf215546Sopenharmony_ci VkDevice device, 686bf215546Sopenharmony_ci const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 687bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 688bf215546Sopenharmony_ci VkSamplerYcbcrConversion *pYcbcrConversion) 689bf215546Sopenharmony_ci{ 690bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 691bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 692bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 693bf215546Sopenharmony_ci const VkExternalFormatANDROID *ext_info = 694bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID); 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci VkSamplerYcbcrConversionCreateInfo local_info; 697bf215546Sopenharmony_ci if (ext_info && ext_info->externalFormat) { 698bf215546Sopenharmony_ci assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci local_info = *pCreateInfo; 701bf215546Sopenharmony_ci local_info.format = 702bf215546Sopenharmony_ci vn_android_drm_format_to_vk_format(ext_info->externalFormat); 703bf215546Sopenharmony_ci local_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 704bf215546Sopenharmony_ci local_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 705bf215546Sopenharmony_ci local_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 706bf215546Sopenharmony_ci local_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 707bf215546Sopenharmony_ci pCreateInfo = &local_info; 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci assert(pCreateInfo->format != VK_FORMAT_UNDEFINED); 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci struct vn_sampler_ycbcr_conversion *conv = 713bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*conv), VN_DEFAULT_ALIGN, 714bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 715bf215546Sopenharmony_ci if (!conv) 716bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 717bf215546Sopenharmony_ci 718bf215546Sopenharmony_ci vn_object_base_init(&conv->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, 719bf215546Sopenharmony_ci &dev->base); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci VkSamplerYcbcrConversion conv_handle = 722bf215546Sopenharmony_ci vn_sampler_ycbcr_conversion_to_handle(conv); 723bf215546Sopenharmony_ci vn_async_vkCreateSamplerYcbcrConversion(dev->instance, device, pCreateInfo, 724bf215546Sopenharmony_ci NULL, &conv_handle); 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci *pYcbcrConversion = conv_handle; 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci return VK_SUCCESS; 729bf215546Sopenharmony_ci} 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_civoid 732bf215546Sopenharmony_civn_DestroySamplerYcbcrConversion(VkDevice device, 733bf215546Sopenharmony_ci VkSamplerYcbcrConversion ycbcrConversion, 734bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 735bf215546Sopenharmony_ci{ 736bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 737bf215546Sopenharmony_ci struct vn_sampler_ycbcr_conversion *conv = 738bf215546Sopenharmony_ci vn_sampler_ycbcr_conversion_from_handle(ycbcrConversion); 739bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 740bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 741bf215546Sopenharmony_ci 742bf215546Sopenharmony_ci if (!conv) 743bf215546Sopenharmony_ci return; 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_ci vn_async_vkDestroySamplerYcbcrConversion(dev->instance, device, 746bf215546Sopenharmony_ci ycbcrConversion, NULL); 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci vn_object_base_fini(&conv->base); 749bf215546Sopenharmony_ci vk_free(alloc, conv); 750bf215546Sopenharmony_ci} 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_civoid 753bf215546Sopenharmony_civn_GetDeviceImageMemoryRequirements( 754bf215546Sopenharmony_ci VkDevice device, 755bf215546Sopenharmony_ci const VkDeviceImageMemoryRequirements *pInfo, 756bf215546Sopenharmony_ci VkMemoryRequirements2 *pMemoryRequirements) 757bf215546Sopenharmony_ci{ 758bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci /* TODO per-device cache */ 761bf215546Sopenharmony_ci vn_call_vkGetDeviceImageMemoryRequirements(dev->instance, device, pInfo, 762bf215546Sopenharmony_ci pMemoryRequirements); 763bf215546Sopenharmony_ci} 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_civoid 766bf215546Sopenharmony_civn_GetDeviceImageSparseMemoryRequirements( 767bf215546Sopenharmony_ci VkDevice device, 768bf215546Sopenharmony_ci const VkDeviceImageMemoryRequirements *pInfo, 769bf215546Sopenharmony_ci uint32_t *pSparseMemoryRequirementCount, 770bf215546Sopenharmony_ci VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 771bf215546Sopenharmony_ci{ 772bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_ci /* TODO per-device cache */ 775bf215546Sopenharmony_ci vn_call_vkGetDeviceImageSparseMemoryRequirements( 776bf215546Sopenharmony_ci dev->instance, device, pInfo, pSparseMemoryRequirementCount, 777bf215546Sopenharmony_ci pSparseMemoryRequirements); 778bf215546Sopenharmony_ci} 779