17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2019 Google LLC 37ec681f3Smrg * SPDX-License-Identifier: MIT 47ec681f3Smrg * 57ec681f3Smrg * based in part on anv and radv which are: 67ec681f3Smrg * Copyright © 2015 Intel Corporation 77ec681f3Smrg * Copyright © 2016 Red Hat. 87ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen 97ec681f3Smrg */ 107ec681f3Smrg 117ec681f3Smrg#include "vn_image.h" 127ec681f3Smrg 137ec681f3Smrg#include "venus-protocol/vn_protocol_driver_image.h" 147ec681f3Smrg#include "venus-protocol/vn_protocol_driver_image_view.h" 157ec681f3Smrg#include "venus-protocol/vn_protocol_driver_sampler.h" 167ec681f3Smrg#include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h" 177ec681f3Smrg 187ec681f3Smrg#include "vn_android.h" 197ec681f3Smrg#include "vn_device.h" 207ec681f3Smrg#include "vn_device_memory.h" 217ec681f3Smrg#include "vn_wsi.h" 227ec681f3Smrg 237ec681f3Smrgstatic void 247ec681f3Smrgvn_image_init_memory_requirements(struct vn_image *img, 257ec681f3Smrg struct vn_device *dev, 267ec681f3Smrg const VkImageCreateInfo *create_info) 277ec681f3Smrg{ 287ec681f3Smrg uint32_t plane_count = 1; 297ec681f3Smrg if (create_info->flags & VK_IMAGE_CREATE_DISJOINT_BIT) { 307ec681f3Smrg /* TODO VkDrmFormatModifierPropertiesEXT::drmFormatModifierPlaneCount */ 317ec681f3Smrg assert(create_info->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT); 327ec681f3Smrg 337ec681f3Smrg switch (create_info->format) { 347ec681f3Smrg case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 357ec681f3Smrg case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 367ec681f3Smrg case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 377ec681f3Smrg case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 387ec681f3Smrg case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 397ec681f3Smrg case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 407ec681f3Smrg case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 417ec681f3Smrg case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 427ec681f3Smrg plane_count = 2; 437ec681f3Smrg break; 447ec681f3Smrg case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 457ec681f3Smrg case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 467ec681f3Smrg case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 477ec681f3Smrg case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 487ec681f3Smrg case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 497ec681f3Smrg case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 507ec681f3Smrg case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 517ec681f3Smrg case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 527ec681f3Smrg case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 537ec681f3Smrg case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 547ec681f3Smrg case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 557ec681f3Smrg case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 567ec681f3Smrg plane_count = 3; 577ec681f3Smrg break; 587ec681f3Smrg default: 597ec681f3Smrg plane_count = 1; 607ec681f3Smrg break; 617ec681f3Smrg } 627ec681f3Smrg } 637ec681f3Smrg assert(plane_count <= ARRAY_SIZE(img->memory_requirements)); 647ec681f3Smrg 657ec681f3Smrg /* TODO add a per-device cache for the requirements */ 667ec681f3Smrg for (uint32_t i = 0; i < plane_count; i++) { 677ec681f3Smrg img->memory_requirements[i].sType = 687ec681f3Smrg VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; 697ec681f3Smrg img->memory_requirements[i].pNext = &img->dedicated_requirements[i]; 707ec681f3Smrg img->dedicated_requirements[i].sType = 717ec681f3Smrg VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; 727ec681f3Smrg img->dedicated_requirements[i].pNext = NULL; 737ec681f3Smrg } 747ec681f3Smrg 757ec681f3Smrg VkDevice dev_handle = vn_device_to_handle(dev); 767ec681f3Smrg VkImage img_handle = vn_image_to_handle(img); 777ec681f3Smrg if (plane_count == 1) { 787ec681f3Smrg vn_call_vkGetImageMemoryRequirements2( 797ec681f3Smrg dev->instance, dev_handle, 807ec681f3Smrg &(VkImageMemoryRequirementsInfo2){ 817ec681f3Smrg .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, 827ec681f3Smrg .image = img_handle, 837ec681f3Smrg }, 847ec681f3Smrg &img->memory_requirements[0]); 857ec681f3Smrg 867ec681f3Smrg /* AHB backed image requires dedicated allocation */ 877ec681f3Smrg if (img->deferred_info) { 887ec681f3Smrg img->dedicated_requirements[0].prefersDedicatedAllocation = VK_TRUE; 897ec681f3Smrg img->dedicated_requirements[0].requiresDedicatedAllocation = VK_TRUE; 907ec681f3Smrg } 917ec681f3Smrg } else { 927ec681f3Smrg for (uint32_t i = 0; i < plane_count; i++) { 937ec681f3Smrg vn_call_vkGetImageMemoryRequirements2( 947ec681f3Smrg dev->instance, dev_handle, 957ec681f3Smrg &(VkImageMemoryRequirementsInfo2){ 967ec681f3Smrg .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, 977ec681f3Smrg .pNext = 987ec681f3Smrg &(VkImagePlaneMemoryRequirementsInfo){ 997ec681f3Smrg .sType = 1007ec681f3Smrg VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, 1017ec681f3Smrg .planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT << i, 1027ec681f3Smrg }, 1037ec681f3Smrg .image = img_handle, 1047ec681f3Smrg }, 1057ec681f3Smrg &img->memory_requirements[i]); 1067ec681f3Smrg } 1077ec681f3Smrg } 1087ec681f3Smrg} 1097ec681f3Smrg 1107ec681f3Smrgstatic VkResult 1117ec681f3Smrgvn_image_store_deferred_create_info( 1127ec681f3Smrg const VkImageCreateInfo *create_info, 1137ec681f3Smrg const VkAllocationCallbacks *alloc, 1147ec681f3Smrg struct vn_image_create_deferred_info **out_info) 1157ec681f3Smrg{ 1167ec681f3Smrg struct vn_image_create_deferred_info *info = NULL; 1177ec681f3Smrg VkBaseOutStructure *dst = NULL; 1187ec681f3Smrg 1197ec681f3Smrg info = vk_zalloc(alloc, sizeof(*info), VN_DEFAULT_ALIGN, 1207ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1217ec681f3Smrg if (!info) 1227ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 1237ec681f3Smrg 1247ec681f3Smrg info->create = *create_info; 1257ec681f3Smrg dst = (void *)&info->create; 1267ec681f3Smrg 1277ec681f3Smrg vk_foreach_struct_const(src, create_info->pNext) { 1287ec681f3Smrg void *pnext = NULL; 1297ec681f3Smrg switch (src->sType) { 1307ec681f3Smrg case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: 1317ec681f3Smrg memcpy(&info->list, src, sizeof(info->list)); 1327ec681f3Smrg pnext = &info->list; 1337ec681f3Smrg break; 1347ec681f3Smrg case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO: 1357ec681f3Smrg memcpy(&info->stencil, src, sizeof(info->stencil)); 1367ec681f3Smrg pnext = &info->stencil; 1377ec681f3Smrg break; 1387ec681f3Smrg default: 1397ec681f3Smrg break; 1407ec681f3Smrg } 1417ec681f3Smrg 1427ec681f3Smrg if (pnext) { 1437ec681f3Smrg dst->pNext = pnext; 1447ec681f3Smrg dst = pnext; 1457ec681f3Smrg } 1467ec681f3Smrg } 1477ec681f3Smrg dst->pNext = NULL; 1487ec681f3Smrg 1497ec681f3Smrg *out_info = info; 1507ec681f3Smrg 1517ec681f3Smrg return VK_SUCCESS; 1527ec681f3Smrg} 1537ec681f3Smrg 1547ec681f3Smrgstatic VkResult 1557ec681f3Smrgvn_image_init(struct vn_device *dev, 1567ec681f3Smrg const VkImageCreateInfo *create_info, 1577ec681f3Smrg struct vn_image *img) 1587ec681f3Smrg{ 1597ec681f3Smrg VkDevice device = vn_device_to_handle(dev); 1607ec681f3Smrg VkImage image = vn_image_to_handle(img); 1617ec681f3Smrg VkResult result = VK_SUCCESS; 1627ec681f3Smrg 1637ec681f3Smrg img->sharing_mode = create_info->sharingMode; 1647ec681f3Smrg 1657ec681f3Smrg /* TODO async */ 1667ec681f3Smrg result = 1677ec681f3Smrg vn_call_vkCreateImage(dev->instance, device, create_info, NULL, &image); 1687ec681f3Smrg if (result != VK_SUCCESS) 1697ec681f3Smrg return result; 1707ec681f3Smrg 1717ec681f3Smrg vn_image_init_memory_requirements(img, dev, create_info); 1727ec681f3Smrg 1737ec681f3Smrg return VK_SUCCESS; 1747ec681f3Smrg} 1757ec681f3Smrg 1767ec681f3SmrgVkResult 1777ec681f3Smrgvn_image_create(struct vn_device *dev, 1787ec681f3Smrg const VkImageCreateInfo *create_info, 1797ec681f3Smrg const VkAllocationCallbacks *alloc, 1807ec681f3Smrg struct vn_image **out_img) 1817ec681f3Smrg{ 1827ec681f3Smrg struct vn_image *img = NULL; 1837ec681f3Smrg VkResult result = VK_SUCCESS; 1847ec681f3Smrg 1857ec681f3Smrg img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN, 1867ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1877ec681f3Smrg if (!img) 1887ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 1897ec681f3Smrg 1907ec681f3Smrg vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base); 1917ec681f3Smrg 1927ec681f3Smrg result = vn_image_init(dev, create_info, img); 1937ec681f3Smrg if (result != VK_SUCCESS) { 1947ec681f3Smrg vn_object_base_fini(&img->base); 1957ec681f3Smrg vk_free(alloc, img); 1967ec681f3Smrg return result; 1977ec681f3Smrg } 1987ec681f3Smrg 1997ec681f3Smrg *out_img = img; 2007ec681f3Smrg 2017ec681f3Smrg return VK_SUCCESS; 2027ec681f3Smrg} 2037ec681f3Smrg 2047ec681f3SmrgVkResult 2057ec681f3Smrgvn_image_init_deferred(struct vn_device *dev, 2067ec681f3Smrg const VkImageCreateInfo *create_info, 2077ec681f3Smrg struct vn_image *img) 2087ec681f3Smrg{ 2097ec681f3Smrg VkResult result = vn_image_init(dev, create_info, img); 2107ec681f3Smrg img->deferred_info->initialized = result == VK_SUCCESS; 2117ec681f3Smrg return result; 2127ec681f3Smrg} 2137ec681f3Smrg 2147ec681f3SmrgVkResult 2157ec681f3Smrgvn_image_create_deferred(struct vn_device *dev, 2167ec681f3Smrg const VkImageCreateInfo *create_info, 2177ec681f3Smrg const VkAllocationCallbacks *alloc, 2187ec681f3Smrg struct vn_image **out_img) 2197ec681f3Smrg{ 2207ec681f3Smrg struct vn_image *img = NULL; 2217ec681f3Smrg VkResult result = VK_SUCCESS; 2227ec681f3Smrg 2237ec681f3Smrg img = vk_zalloc(alloc, sizeof(*img), VN_DEFAULT_ALIGN, 2247ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2257ec681f3Smrg if (!img) 2267ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 2277ec681f3Smrg 2287ec681f3Smrg vn_object_base_init(&img->base, VK_OBJECT_TYPE_IMAGE, &dev->base); 2297ec681f3Smrg 2307ec681f3Smrg result = vn_image_store_deferred_create_info(create_info, alloc, 2317ec681f3Smrg &img->deferred_info); 2327ec681f3Smrg if (result != VK_SUCCESS) { 2337ec681f3Smrg vn_object_base_fini(&img->base); 2347ec681f3Smrg vk_free(alloc, img); 2357ec681f3Smrg return result; 2367ec681f3Smrg } 2377ec681f3Smrg 2387ec681f3Smrg *out_img = img; 2397ec681f3Smrg 2407ec681f3Smrg return VK_SUCCESS; 2417ec681f3Smrg} 2427ec681f3Smrg 2437ec681f3Smrg/* image commands */ 2447ec681f3Smrg 2457ec681f3SmrgVkResult 2467ec681f3Smrgvn_CreateImage(VkDevice device, 2477ec681f3Smrg const VkImageCreateInfo *pCreateInfo, 2487ec681f3Smrg const VkAllocationCallbacks *pAllocator, 2497ec681f3Smrg VkImage *pImage) 2507ec681f3Smrg{ 2517ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 2527ec681f3Smrg const VkAllocationCallbacks *alloc = 2537ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 2547ec681f3Smrg struct vn_image *img; 2557ec681f3Smrg VkResult result; 2567ec681f3Smrg 2577ec681f3Smrg const struct wsi_image_create_info *wsi_info = 2587ec681f3Smrg vn_wsi_find_wsi_image_create_info(pCreateInfo); 2597ec681f3Smrg const VkNativeBufferANDROID *anb_info = 2607ec681f3Smrg vn_android_find_native_buffer(pCreateInfo); 2617ec681f3Smrg const VkExternalMemoryImageCreateInfo *external_info = 2627ec681f3Smrg vk_find_struct_const(pCreateInfo->pNext, 2637ec681f3Smrg EXTERNAL_MEMORY_IMAGE_CREATE_INFO); 2647ec681f3Smrg const bool ahb_info = 2657ec681f3Smrg external_info && 2667ec681f3Smrg external_info->handleTypes == 2677ec681f3Smrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 2687ec681f3Smrg 2697ec681f3Smrg if (wsi_info) { 2707ec681f3Smrg result = vn_wsi_create_image(dev, pCreateInfo, wsi_info, alloc, &img); 2717ec681f3Smrg } else if (anb_info) { 2727ec681f3Smrg result = 2737ec681f3Smrg vn_android_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img); 2747ec681f3Smrg } else if (ahb_info) { 2757ec681f3Smrg result = vn_android_image_from_ahb(dev, pCreateInfo, alloc, &img); 2767ec681f3Smrg } else { 2777ec681f3Smrg result = vn_image_create(dev, pCreateInfo, alloc, &img); 2787ec681f3Smrg } 2797ec681f3Smrg 2807ec681f3Smrg if (result != VK_SUCCESS) 2817ec681f3Smrg return vn_error(dev->instance, result); 2827ec681f3Smrg 2837ec681f3Smrg *pImage = vn_image_to_handle(img); 2847ec681f3Smrg return VK_SUCCESS; 2857ec681f3Smrg} 2867ec681f3Smrg 2877ec681f3Smrgvoid 2887ec681f3Smrgvn_DestroyImage(VkDevice device, 2897ec681f3Smrg VkImage image, 2907ec681f3Smrg const VkAllocationCallbacks *pAllocator) 2917ec681f3Smrg{ 2927ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 2937ec681f3Smrg struct vn_image *img = vn_image_from_handle(image); 2947ec681f3Smrg const VkAllocationCallbacks *alloc = 2957ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 2967ec681f3Smrg 2977ec681f3Smrg if (!img) 2987ec681f3Smrg return; 2997ec681f3Smrg 3007ec681f3Smrg if (img->private_memory != VK_NULL_HANDLE) 3017ec681f3Smrg vn_FreeMemory(device, img->private_memory, pAllocator); 3027ec681f3Smrg 3037ec681f3Smrg /* must not ask renderer to destroy uninitialized deferred image */ 3047ec681f3Smrg if (!img->deferred_info || img->deferred_info->initialized) 3057ec681f3Smrg vn_async_vkDestroyImage(dev->instance, device, image, NULL); 3067ec681f3Smrg 3077ec681f3Smrg if (img->deferred_info) 3087ec681f3Smrg vk_free(alloc, img->deferred_info); 3097ec681f3Smrg 3107ec681f3Smrg vn_object_base_fini(&img->base); 3117ec681f3Smrg vk_free(alloc, img); 3127ec681f3Smrg} 3137ec681f3Smrg 3147ec681f3Smrgvoid 3157ec681f3Smrgvn_GetImageMemoryRequirements(VkDevice device, 3167ec681f3Smrg VkImage image, 3177ec681f3Smrg VkMemoryRequirements *pMemoryRequirements) 3187ec681f3Smrg{ 3197ec681f3Smrg const struct vn_image *img = vn_image_from_handle(image); 3207ec681f3Smrg 3217ec681f3Smrg *pMemoryRequirements = img->memory_requirements[0].memoryRequirements; 3227ec681f3Smrg} 3237ec681f3Smrg 3247ec681f3Smrgvoid 3257ec681f3Smrgvn_GetImageSparseMemoryRequirements( 3267ec681f3Smrg VkDevice device, 3277ec681f3Smrg VkImage image, 3287ec681f3Smrg uint32_t *pSparseMemoryRequirementCount, 3297ec681f3Smrg VkSparseImageMemoryRequirements *pSparseMemoryRequirements) 3307ec681f3Smrg{ 3317ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 3327ec681f3Smrg 3337ec681f3Smrg /* TODO per-device cache */ 3347ec681f3Smrg vn_call_vkGetImageSparseMemoryRequirements(dev->instance, device, image, 3357ec681f3Smrg pSparseMemoryRequirementCount, 3367ec681f3Smrg pSparseMemoryRequirements); 3377ec681f3Smrg} 3387ec681f3Smrg 3397ec681f3Smrgvoid 3407ec681f3Smrgvn_GetImageMemoryRequirements2(VkDevice device, 3417ec681f3Smrg const VkImageMemoryRequirementsInfo2 *pInfo, 3427ec681f3Smrg VkMemoryRequirements2 *pMemoryRequirements) 3437ec681f3Smrg{ 3447ec681f3Smrg const struct vn_image *img = vn_image_from_handle(pInfo->image); 3457ec681f3Smrg union { 3467ec681f3Smrg VkBaseOutStructure *pnext; 3477ec681f3Smrg VkMemoryRequirements2 *two; 3487ec681f3Smrg VkMemoryDedicatedRequirements *dedicated; 3497ec681f3Smrg } u = { .two = pMemoryRequirements }; 3507ec681f3Smrg 3517ec681f3Smrg uint32_t plane = 0; 3527ec681f3Smrg const VkImagePlaneMemoryRequirementsInfo *plane_info = 3537ec681f3Smrg vk_find_struct_const(pInfo->pNext, 3547ec681f3Smrg IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO); 3557ec681f3Smrg if (plane_info) { 3567ec681f3Smrg switch (plane_info->planeAspect) { 3577ec681f3Smrg case VK_IMAGE_ASPECT_PLANE_1_BIT: 3587ec681f3Smrg plane = 1; 3597ec681f3Smrg break; 3607ec681f3Smrg case VK_IMAGE_ASPECT_PLANE_2_BIT: 3617ec681f3Smrg plane = 2; 3627ec681f3Smrg break; 3637ec681f3Smrg default: 3647ec681f3Smrg plane = 0; 3657ec681f3Smrg break; 3667ec681f3Smrg } 3677ec681f3Smrg } 3687ec681f3Smrg 3697ec681f3Smrg while (u.pnext) { 3707ec681f3Smrg switch (u.pnext->sType) { 3717ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2: 3727ec681f3Smrg u.two->memoryRequirements = 3737ec681f3Smrg img->memory_requirements[plane].memoryRequirements; 3747ec681f3Smrg break; 3757ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: 3767ec681f3Smrg u.dedicated->prefersDedicatedAllocation = 3777ec681f3Smrg img->dedicated_requirements[plane].prefersDedicatedAllocation; 3787ec681f3Smrg u.dedicated->requiresDedicatedAllocation = 3797ec681f3Smrg img->dedicated_requirements[plane].requiresDedicatedAllocation; 3807ec681f3Smrg break; 3817ec681f3Smrg default: 3827ec681f3Smrg break; 3837ec681f3Smrg } 3847ec681f3Smrg u.pnext = u.pnext->pNext; 3857ec681f3Smrg } 3867ec681f3Smrg} 3877ec681f3Smrg 3887ec681f3Smrgvoid 3897ec681f3Smrgvn_GetImageSparseMemoryRequirements2( 3907ec681f3Smrg VkDevice device, 3917ec681f3Smrg const VkImageSparseMemoryRequirementsInfo2 *pInfo, 3927ec681f3Smrg uint32_t *pSparseMemoryRequirementCount, 3937ec681f3Smrg VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 3947ec681f3Smrg{ 3957ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 3967ec681f3Smrg 3977ec681f3Smrg /* TODO per-device cache */ 3987ec681f3Smrg vn_call_vkGetImageSparseMemoryRequirements2(dev->instance, device, pInfo, 3997ec681f3Smrg pSparseMemoryRequirementCount, 4007ec681f3Smrg pSparseMemoryRequirements); 4017ec681f3Smrg} 4027ec681f3Smrg 4037ec681f3SmrgVkResult 4047ec681f3Smrgvn_BindImageMemory(VkDevice device, 4057ec681f3Smrg VkImage image, 4067ec681f3Smrg VkDeviceMemory memory, 4077ec681f3Smrg VkDeviceSize memoryOffset) 4087ec681f3Smrg{ 4097ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 4107ec681f3Smrg struct vn_device_memory *mem = vn_device_memory_from_handle(memory); 4117ec681f3Smrg 4127ec681f3Smrg if (mem->base_memory) { 4137ec681f3Smrg memory = vn_device_memory_to_handle(mem->base_memory); 4147ec681f3Smrg memoryOffset += mem->base_offset; 4157ec681f3Smrg } 4167ec681f3Smrg 4177ec681f3Smrg vn_async_vkBindImageMemory(dev->instance, device, image, memory, 4187ec681f3Smrg memoryOffset); 4197ec681f3Smrg 4207ec681f3Smrg return VK_SUCCESS; 4217ec681f3Smrg} 4227ec681f3Smrg 4237ec681f3SmrgVkResult 4247ec681f3Smrgvn_BindImageMemory2(VkDevice device, 4257ec681f3Smrg uint32_t bindInfoCount, 4267ec681f3Smrg const VkBindImageMemoryInfo *pBindInfos) 4277ec681f3Smrg{ 4287ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 4297ec681f3Smrg const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 4307ec681f3Smrg 4317ec681f3Smrg VkBindImageMemoryInfo *local_infos = NULL; 4327ec681f3Smrg for (uint32_t i = 0; i < bindInfoCount; i++) { 4337ec681f3Smrg const VkBindImageMemoryInfo *info = &pBindInfos[i]; 4347ec681f3Smrg struct vn_device_memory *mem = 4357ec681f3Smrg vn_device_memory_from_handle(info->memory); 4367ec681f3Smrg /* TODO handle VkBindImageMemorySwapchainInfoKHR */ 4377ec681f3Smrg if (!mem || !mem->base_memory) 4387ec681f3Smrg continue; 4397ec681f3Smrg 4407ec681f3Smrg if (!local_infos) { 4417ec681f3Smrg const size_t size = sizeof(*local_infos) * bindInfoCount; 4427ec681f3Smrg local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN, 4437ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 4447ec681f3Smrg if (!local_infos) 4457ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 4467ec681f3Smrg 4477ec681f3Smrg memcpy(local_infos, pBindInfos, size); 4487ec681f3Smrg } 4497ec681f3Smrg 4507ec681f3Smrg local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory); 4517ec681f3Smrg local_infos[i].memoryOffset += mem->base_offset; 4527ec681f3Smrg } 4537ec681f3Smrg if (local_infos) 4547ec681f3Smrg pBindInfos = local_infos; 4557ec681f3Smrg 4567ec681f3Smrg vn_async_vkBindImageMemory2(dev->instance, device, bindInfoCount, 4577ec681f3Smrg pBindInfos); 4587ec681f3Smrg 4597ec681f3Smrg vk_free(alloc, local_infos); 4607ec681f3Smrg 4617ec681f3Smrg return VK_SUCCESS; 4627ec681f3Smrg} 4637ec681f3Smrg 4647ec681f3SmrgVkResult 4657ec681f3Smrgvn_GetImageDrmFormatModifierPropertiesEXT( 4667ec681f3Smrg VkDevice device, 4677ec681f3Smrg VkImage image, 4687ec681f3Smrg VkImageDrmFormatModifierPropertiesEXT *pProperties) 4697ec681f3Smrg{ 4707ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 4717ec681f3Smrg 4727ec681f3Smrg /* TODO local cache */ 4737ec681f3Smrg return vn_call_vkGetImageDrmFormatModifierPropertiesEXT( 4747ec681f3Smrg dev->instance, device, image, pProperties); 4757ec681f3Smrg} 4767ec681f3Smrg 4777ec681f3Smrgvoid 4787ec681f3Smrgvn_GetImageSubresourceLayout(VkDevice device, 4797ec681f3Smrg VkImage image, 4807ec681f3Smrg const VkImageSubresource *pSubresource, 4817ec681f3Smrg VkSubresourceLayout *pLayout) 4827ec681f3Smrg{ 4837ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 4847ec681f3Smrg 4857ec681f3Smrg /* TODO local cache */ 4867ec681f3Smrg vn_call_vkGetImageSubresourceLayout(dev->instance, device, image, 4877ec681f3Smrg pSubresource, pLayout); 4887ec681f3Smrg} 4897ec681f3Smrg 4907ec681f3Smrg/* image view commands */ 4917ec681f3Smrg 4927ec681f3SmrgVkResult 4937ec681f3Smrgvn_CreateImageView(VkDevice device, 4947ec681f3Smrg const VkImageViewCreateInfo *pCreateInfo, 4957ec681f3Smrg const VkAllocationCallbacks *pAllocator, 4967ec681f3Smrg VkImageView *pView) 4977ec681f3Smrg{ 4987ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 4997ec681f3Smrg const VkAllocationCallbacks *alloc = 5007ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 5017ec681f3Smrg 5027ec681f3Smrg struct vn_image_view *view = 5037ec681f3Smrg vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN, 5047ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 5057ec681f3Smrg if (!view) 5067ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 5077ec681f3Smrg 5087ec681f3Smrg vn_object_base_init(&view->base, VK_OBJECT_TYPE_IMAGE_VIEW, &dev->base); 5097ec681f3Smrg view->image = vn_image_from_handle(pCreateInfo->image); 5107ec681f3Smrg 5117ec681f3Smrg VkImageView view_handle = vn_image_view_to_handle(view); 5127ec681f3Smrg vn_async_vkCreateImageView(dev->instance, device, pCreateInfo, NULL, 5137ec681f3Smrg &view_handle); 5147ec681f3Smrg 5157ec681f3Smrg *pView = view_handle; 5167ec681f3Smrg 5177ec681f3Smrg return VK_SUCCESS; 5187ec681f3Smrg} 5197ec681f3Smrg 5207ec681f3Smrgvoid 5217ec681f3Smrgvn_DestroyImageView(VkDevice device, 5227ec681f3Smrg VkImageView imageView, 5237ec681f3Smrg const VkAllocationCallbacks *pAllocator) 5247ec681f3Smrg{ 5257ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 5267ec681f3Smrg struct vn_image_view *view = vn_image_view_from_handle(imageView); 5277ec681f3Smrg const VkAllocationCallbacks *alloc = 5287ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 5297ec681f3Smrg 5307ec681f3Smrg if (!view) 5317ec681f3Smrg return; 5327ec681f3Smrg 5337ec681f3Smrg vn_async_vkDestroyImageView(dev->instance, device, imageView, NULL); 5347ec681f3Smrg 5357ec681f3Smrg vn_object_base_fini(&view->base); 5367ec681f3Smrg vk_free(alloc, view); 5377ec681f3Smrg} 5387ec681f3Smrg 5397ec681f3Smrg/* sampler commands */ 5407ec681f3Smrg 5417ec681f3SmrgVkResult 5427ec681f3Smrgvn_CreateSampler(VkDevice device, 5437ec681f3Smrg const VkSamplerCreateInfo *pCreateInfo, 5447ec681f3Smrg const VkAllocationCallbacks *pAllocator, 5457ec681f3Smrg VkSampler *pSampler) 5467ec681f3Smrg{ 5477ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 5487ec681f3Smrg const VkAllocationCallbacks *alloc = 5497ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 5507ec681f3Smrg 5517ec681f3Smrg struct vn_sampler *sampler = 5527ec681f3Smrg vk_zalloc(alloc, sizeof(*sampler), VN_DEFAULT_ALIGN, 5537ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 5547ec681f3Smrg if (!sampler) 5557ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 5567ec681f3Smrg 5577ec681f3Smrg vn_object_base_init(&sampler->base, VK_OBJECT_TYPE_SAMPLER, &dev->base); 5587ec681f3Smrg 5597ec681f3Smrg VkSampler sampler_handle = vn_sampler_to_handle(sampler); 5607ec681f3Smrg vn_async_vkCreateSampler(dev->instance, device, pCreateInfo, NULL, 5617ec681f3Smrg &sampler_handle); 5627ec681f3Smrg 5637ec681f3Smrg *pSampler = sampler_handle; 5647ec681f3Smrg 5657ec681f3Smrg return VK_SUCCESS; 5667ec681f3Smrg} 5677ec681f3Smrg 5687ec681f3Smrgvoid 5697ec681f3Smrgvn_DestroySampler(VkDevice device, 5707ec681f3Smrg VkSampler _sampler, 5717ec681f3Smrg const VkAllocationCallbacks *pAllocator) 5727ec681f3Smrg{ 5737ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 5747ec681f3Smrg struct vn_sampler *sampler = vn_sampler_from_handle(_sampler); 5757ec681f3Smrg const VkAllocationCallbacks *alloc = 5767ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 5777ec681f3Smrg 5787ec681f3Smrg if (!sampler) 5797ec681f3Smrg return; 5807ec681f3Smrg 5817ec681f3Smrg vn_async_vkDestroySampler(dev->instance, device, _sampler, NULL); 5827ec681f3Smrg 5837ec681f3Smrg vn_object_base_fini(&sampler->base); 5847ec681f3Smrg vk_free(alloc, sampler); 5857ec681f3Smrg} 5867ec681f3Smrg 5877ec681f3Smrg/* sampler YCbCr conversion commands */ 5887ec681f3Smrg 5897ec681f3SmrgVkResult 5907ec681f3Smrgvn_CreateSamplerYcbcrConversion( 5917ec681f3Smrg VkDevice device, 5927ec681f3Smrg const VkSamplerYcbcrConversionCreateInfo *pCreateInfo, 5937ec681f3Smrg const VkAllocationCallbacks *pAllocator, 5947ec681f3Smrg VkSamplerYcbcrConversion *pYcbcrConversion) 5957ec681f3Smrg{ 5967ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 5977ec681f3Smrg const VkAllocationCallbacks *alloc = 5987ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 5997ec681f3Smrg const VkExternalFormatANDROID *ext_info = 6007ec681f3Smrg vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID); 6017ec681f3Smrg 6027ec681f3Smrg VkSamplerYcbcrConversionCreateInfo local_info; 6037ec681f3Smrg if (ext_info && ext_info->externalFormat) { 6047ec681f3Smrg assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); 6057ec681f3Smrg 6067ec681f3Smrg local_info = *pCreateInfo; 6077ec681f3Smrg local_info.format = 6087ec681f3Smrg vn_android_drm_format_to_vk_format(ext_info->externalFormat); 6097ec681f3Smrg local_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; 6107ec681f3Smrg local_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; 6117ec681f3Smrg local_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; 6127ec681f3Smrg local_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; 6137ec681f3Smrg pCreateInfo = &local_info; 6147ec681f3Smrg 6157ec681f3Smrg assert(pCreateInfo->format != VK_FORMAT_UNDEFINED); 6167ec681f3Smrg } 6177ec681f3Smrg 6187ec681f3Smrg struct vn_sampler_ycbcr_conversion *conv = 6197ec681f3Smrg vk_zalloc(alloc, sizeof(*conv), VN_DEFAULT_ALIGN, 6207ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 6217ec681f3Smrg if (!conv) 6227ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 6237ec681f3Smrg 6247ec681f3Smrg vn_object_base_init(&conv->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, 6257ec681f3Smrg &dev->base); 6267ec681f3Smrg 6277ec681f3Smrg VkSamplerYcbcrConversion conv_handle = 6287ec681f3Smrg vn_sampler_ycbcr_conversion_to_handle(conv); 6297ec681f3Smrg vn_async_vkCreateSamplerYcbcrConversion(dev->instance, device, pCreateInfo, 6307ec681f3Smrg NULL, &conv_handle); 6317ec681f3Smrg 6327ec681f3Smrg *pYcbcrConversion = conv_handle; 6337ec681f3Smrg 6347ec681f3Smrg return VK_SUCCESS; 6357ec681f3Smrg} 6367ec681f3Smrg 6377ec681f3Smrgvoid 6387ec681f3Smrgvn_DestroySamplerYcbcrConversion(VkDevice device, 6397ec681f3Smrg VkSamplerYcbcrConversion ycbcrConversion, 6407ec681f3Smrg const VkAllocationCallbacks *pAllocator) 6417ec681f3Smrg{ 6427ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 6437ec681f3Smrg struct vn_sampler_ycbcr_conversion *conv = 6447ec681f3Smrg vn_sampler_ycbcr_conversion_from_handle(ycbcrConversion); 6457ec681f3Smrg const VkAllocationCallbacks *alloc = 6467ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 6477ec681f3Smrg 6487ec681f3Smrg if (!conv) 6497ec681f3Smrg return; 6507ec681f3Smrg 6517ec681f3Smrg vn_async_vkDestroySamplerYcbcrConversion(dev->instance, device, 6527ec681f3Smrg ycbcrConversion, NULL); 6537ec681f3Smrg 6547ec681f3Smrg vn_object_base_fini(&conv->base); 6557ec681f3Smrg vk_free(alloc, conv); 6567ec681f3Smrg} 657