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