xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_image.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2019 Google LLC
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * based in part on anv and radv which are:
6*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
8*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
9*61046927SAndroid Build Coastguard Worker  */
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "vn_image.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_image.h"
14*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_image_view.h"
15*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_sampler.h"
16*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_sampler_ycbcr_conversion.h"
17*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker #include "vn_android.h"
20*61046927SAndroid Build Coastguard Worker #include "vn_device.h"
21*61046927SAndroid Build Coastguard Worker #include "vn_device_memory.h"
22*61046927SAndroid Build Coastguard Worker #include "vn_physical_device.h"
23*61046927SAndroid Build Coastguard Worker #include "vn_wsi.h"
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker #define IMAGE_REQS_CACHE_MAX_ENTRIES 500
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker /* image commands */
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_image_get_plane_count(const VkImageCreateInfo * create_info)30*61046927SAndroid Build Coastguard Worker vn_image_get_plane_count(const VkImageCreateInfo *create_info)
31*61046927SAndroid Build Coastguard Worker {
32*61046927SAndroid Build Coastguard Worker    if (!(create_info->flags & VK_IMAGE_CREATE_DISJOINT_BIT))
33*61046927SAndroid Build Coastguard Worker       return 1;
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker    /* TODO VkDrmFormatModifierPropertiesEXT::drmFormatModifierPlaneCount */
36*61046927SAndroid Build Coastguard Worker    assert(create_info->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT);
37*61046927SAndroid Build Coastguard Worker    return vk_format_get_plane_count(create_info->format);
38*61046927SAndroid Build Coastguard Worker }
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_image_get_plane(const VkImageAspectFlagBits plane_aspect)41*61046927SAndroid Build Coastguard Worker vn_image_get_plane(const VkImageAspectFlagBits plane_aspect)
42*61046927SAndroid Build Coastguard Worker {
43*61046927SAndroid Build Coastguard Worker    switch (plane_aspect) {
44*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_1_BIT:
45*61046927SAndroid Build Coastguard Worker       return 1;
46*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_2_BIT:
47*61046927SAndroid Build Coastguard Worker       return 2;
48*61046927SAndroid Build Coastguard Worker    default:
49*61046927SAndroid Build Coastguard Worker       return 0;
50*61046927SAndroid Build Coastguard Worker    }
51*61046927SAndroid Build Coastguard Worker }
52*61046927SAndroid Build Coastguard Worker 
53*61046927SAndroid Build Coastguard Worker static void
vn_image_fill_reqs(const struct vn_image_memory_requirements * req,VkMemoryRequirements2 * out_reqs)54*61046927SAndroid Build Coastguard Worker vn_image_fill_reqs(const struct vn_image_memory_requirements *req,
55*61046927SAndroid Build Coastguard Worker                    VkMemoryRequirements2 *out_reqs)
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker    union {
58*61046927SAndroid Build Coastguard Worker       VkBaseOutStructure *pnext;
59*61046927SAndroid Build Coastguard Worker       VkMemoryRequirements2 *two;
60*61046927SAndroid Build Coastguard Worker       VkMemoryDedicatedRequirements *dedicated;
61*61046927SAndroid Build Coastguard Worker    } u = { .two = out_reqs };
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker    while (u.pnext) {
64*61046927SAndroid Build Coastguard Worker       switch (u.pnext->sType) {
65*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2:
66*61046927SAndroid Build Coastguard Worker          u.two->memoryRequirements = req->memory.memoryRequirements;
67*61046927SAndroid Build Coastguard Worker          break;
68*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:
69*61046927SAndroid Build Coastguard Worker          u.dedicated->prefersDedicatedAllocation =
70*61046927SAndroid Build Coastguard Worker             req->dedicated.prefersDedicatedAllocation;
71*61046927SAndroid Build Coastguard Worker          u.dedicated->requiresDedicatedAllocation =
72*61046927SAndroid Build Coastguard Worker             req->dedicated.requiresDedicatedAllocation;
73*61046927SAndroid Build Coastguard Worker          break;
74*61046927SAndroid Build Coastguard Worker       default:
75*61046927SAndroid Build Coastguard Worker          break;
76*61046927SAndroid Build Coastguard Worker       }
77*61046927SAndroid Build Coastguard Worker       u.pnext = u.pnext->pNext;
78*61046927SAndroid Build Coastguard Worker    }
79*61046927SAndroid Build Coastguard Worker }
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker static void
vn_image_cache_debug_dump(struct vn_image_reqs_cache * cache)82*61046927SAndroid Build Coastguard Worker vn_image_cache_debug_dump(struct vn_image_reqs_cache *cache)
83*61046927SAndroid Build Coastguard Worker {
84*61046927SAndroid Build Coastguard Worker    vn_log(NULL, "dumping image reqs cache statistics");
85*61046927SAndroid Build Coastguard Worker    vn_log(NULL, "  hit %u\n", cache->debug.cache_hit_count);
86*61046927SAndroid Build Coastguard Worker    vn_log(NULL, "  miss %u\n", cache->debug.cache_miss_count);
87*61046927SAndroid Build Coastguard Worker    vn_log(NULL, "  skip %u\n", cache->debug.cache_skip_count);
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker static bool
vn_image_get_image_reqs_key(struct vn_device * dev,const VkImageCreateInfo * create_info,uint8_t * key)91*61046927SAndroid Build Coastguard Worker vn_image_get_image_reqs_key(struct vn_device *dev,
92*61046927SAndroid Build Coastguard Worker                             const VkImageCreateInfo *create_info,
93*61046927SAndroid Build Coastguard Worker                             uint8_t *key)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker    struct mesa_sha1 sha1_ctx;
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker    if (!dev->image_reqs_cache.ht)
98*61046927SAndroid Build Coastguard Worker       return false;
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    _mesa_sha1_init(&sha1_ctx);
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    /* Hash relevant fields in the pNext chain */
103*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(src, create_info->pNext) {
104*61046927SAndroid Build Coastguard Worker       switch (src->sType) {
105*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO: {
106*61046927SAndroid Build Coastguard Worker          struct VkExternalMemoryImageCreateInfo *ext_mem =
107*61046927SAndroid Build Coastguard Worker             (struct VkExternalMemoryImageCreateInfo *)src;
108*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(&sha1_ctx, &ext_mem->handleTypes,
109*61046927SAndroid Build Coastguard Worker                            sizeof(VkExternalMemoryHandleTypeFlags));
110*61046927SAndroid Build Coastguard Worker          break;
111*61046927SAndroid Build Coastguard Worker       }
112*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: {
113*61046927SAndroid Build Coastguard Worker          struct VkImageFormatListCreateInfo *format_list =
114*61046927SAndroid Build Coastguard Worker             (struct VkImageFormatListCreateInfo *)src;
115*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(&sha1_ctx, format_list->pViewFormats,
116*61046927SAndroid Build Coastguard Worker                            sizeof(VkFormat) * format_list->viewFormatCount);
117*61046927SAndroid Build Coastguard Worker          break;
118*61046927SAndroid Build Coastguard Worker       }
119*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT: {
120*61046927SAndroid Build Coastguard Worker          struct VkImageDrmFormatModifierListCreateInfoEXT *format_mod_list =
121*61046927SAndroid Build Coastguard Worker             (struct VkImageDrmFormatModifierListCreateInfoEXT *)src;
122*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(
123*61046927SAndroid Build Coastguard Worker             &sha1_ctx, format_mod_list->pDrmFormatModifiers,
124*61046927SAndroid Build Coastguard Worker             sizeof(uint64_t) * format_mod_list->drmFormatModifierCount);
125*61046927SAndroid Build Coastguard Worker          break;
126*61046927SAndroid Build Coastguard Worker       }
127*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT: {
128*61046927SAndroid Build Coastguard Worker          struct VkImageDrmFormatModifierExplicitCreateInfoEXT
129*61046927SAndroid Build Coastguard Worker             *format_mod_explicit =
130*61046927SAndroid Build Coastguard Worker                (struct VkImageDrmFormatModifierExplicitCreateInfoEXT *)src;
131*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(&sha1_ctx, &format_mod_explicit->drmFormatModifier,
132*61046927SAndroid Build Coastguard Worker                            sizeof(uint64_t));
133*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(
134*61046927SAndroid Build Coastguard Worker             &sha1_ctx, format_mod_explicit->pPlaneLayouts,
135*61046927SAndroid Build Coastguard Worker             sizeof(VkSubresourceLayout) *
136*61046927SAndroid Build Coastguard Worker                format_mod_explicit->drmFormatModifierPlaneCount);
137*61046927SAndroid Build Coastguard Worker          break;
138*61046927SAndroid Build Coastguard Worker       }
139*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO: {
140*61046927SAndroid Build Coastguard Worker          struct VkImageStencilUsageCreateInfo *stencil_usage =
141*61046927SAndroid Build Coastguard Worker             (struct VkImageStencilUsageCreateInfo *)src;
142*61046927SAndroid Build Coastguard Worker          _mesa_sha1_update(&sha1_ctx, &stencil_usage->stencilUsage,
143*61046927SAndroid Build Coastguard Worker                            sizeof(VkImageUsageFlags));
144*61046927SAndroid Build Coastguard Worker          break;
145*61046927SAndroid Build Coastguard Worker       }
146*61046927SAndroid Build Coastguard Worker       default:
147*61046927SAndroid Build Coastguard Worker          /* Skip cache for unsupported pNext */
148*61046927SAndroid Build Coastguard Worker          dev->image_reqs_cache.debug.cache_skip_count++;
149*61046927SAndroid Build Coastguard Worker          return false;
150*61046927SAndroid Build Coastguard Worker       }
151*61046927SAndroid Build Coastguard Worker    }
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker    /* Hash contingous block of VkImageCreateInfo starting with
154*61046927SAndroid Build Coastguard Worker     * VkImageCreateInfo->flags and ending with VkImageCreateInfo->sharingMode
155*61046927SAndroid Build Coastguard Worker     *
156*61046927SAndroid Build Coastguard Worker     * There's no padding in involved in this hash block so no concern for C
157*61046927SAndroid Build Coastguard Worker     * enum sizes or alignment.
158*61046927SAndroid Build Coastguard Worker     */
159*61046927SAndroid Build Coastguard Worker    static const size_t create_image_hash_block_size =
160*61046927SAndroid Build Coastguard Worker       offsetof(VkImageCreateInfo, queueFamilyIndexCount) -
161*61046927SAndroid Build Coastguard Worker       offsetof(VkImageCreateInfo, flags);
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    _mesa_sha1_update(&sha1_ctx, &create_info->flags,
164*61046927SAndroid Build Coastguard Worker                      create_image_hash_block_size);
165*61046927SAndroid Build Coastguard Worker 
166*61046927SAndroid Build Coastguard Worker    /* Follow pointer and hash pQueueFamilyIndices separately.
167*61046927SAndroid Build Coastguard Worker     * pQueueFamilyIndices is ignored if sharingMode is not
168*61046927SAndroid Build Coastguard Worker     * VK_SHARING_MODE_CONCURRENT
169*61046927SAndroid Build Coastguard Worker     */
170*61046927SAndroid Build Coastguard Worker    if (create_info->sharingMode == VK_SHARING_MODE_CONCURRENT) {
171*61046927SAndroid Build Coastguard Worker       _mesa_sha1_update(
172*61046927SAndroid Build Coastguard Worker          &sha1_ctx, create_info->pQueueFamilyIndices,
173*61046927SAndroid Build Coastguard Worker          sizeof(uint32_t) * create_info->queueFamilyIndexCount);
174*61046927SAndroid Build Coastguard Worker    }
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    _mesa_sha1_update(&sha1_ctx, &create_info->initialLayout,
177*61046927SAndroid Build Coastguard Worker                      sizeof(create_info->initialLayout));
178*61046927SAndroid Build Coastguard Worker    _mesa_sha1_final(&sha1_ctx, key);
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    return true;
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker void
vn_image_reqs_cache_init(struct vn_device * dev)184*61046927SAndroid Build Coastguard Worker vn_image_reqs_cache_init(struct vn_device *dev)
185*61046927SAndroid Build Coastguard Worker {
186*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache *cache = &dev->image_reqs_cache;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_ASYNC_IMAGE_CREATE))
189*61046927SAndroid Build Coastguard Worker       return;
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    cache->ht = _mesa_hash_table_create(NULL, vn_cache_key_hash_function,
192*61046927SAndroid Build Coastguard Worker                                        vn_cache_key_equal_function);
193*61046927SAndroid Build Coastguard Worker    if (!cache->ht)
194*61046927SAndroid Build Coastguard Worker       return;
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&cache->mutex, mtx_plain);
197*61046927SAndroid Build Coastguard Worker    list_inithead(&dev->image_reqs_cache.lru);
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker void
vn_image_reqs_cache_fini(struct vn_device * dev)201*61046927SAndroid Build Coastguard Worker vn_image_reqs_cache_fini(struct vn_device *dev)
202*61046927SAndroid Build Coastguard Worker {
203*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
204*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache *cache = &dev->image_reqs_cache;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker    if (!cache->ht)
207*61046927SAndroid Build Coastguard Worker       return;
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker    hash_table_foreach(cache->ht, hash_entry) {
210*61046927SAndroid Build Coastguard Worker       struct vn_image_reqs_cache_entry *cache_entry = hash_entry->data;
211*61046927SAndroid Build Coastguard Worker       list_del(&cache_entry->head);
212*61046927SAndroid Build Coastguard Worker       vk_free(alloc, cache_entry);
213*61046927SAndroid Build Coastguard Worker    }
214*61046927SAndroid Build Coastguard Worker    assert(list_is_empty(&dev->image_reqs_cache.lru));
215*61046927SAndroid Build Coastguard Worker 
216*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(cache->ht, NULL);
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&cache->mutex);
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker    if (VN_DEBUG(CACHE))
221*61046927SAndroid Build Coastguard Worker       vn_image_cache_debug_dump(cache);
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker static bool
vn_image_init_reqs_from_cache(struct vn_device * dev,struct vn_image * img,uint8_t * key)225*61046927SAndroid Build Coastguard Worker vn_image_init_reqs_from_cache(struct vn_device *dev,
226*61046927SAndroid Build Coastguard Worker                               struct vn_image *img,
227*61046927SAndroid Build Coastguard Worker                               uint8_t *key)
228*61046927SAndroid Build Coastguard Worker {
229*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache *cache = &dev->image_reqs_cache;
230*61046927SAndroid Build Coastguard Worker 
231*61046927SAndroid Build Coastguard Worker    assert(cache->ht);
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&cache->mutex);
234*61046927SAndroid Build Coastguard Worker    struct hash_entry *hash_entry = _mesa_hash_table_search(cache->ht, key);
235*61046927SAndroid Build Coastguard Worker    if (hash_entry) {
236*61046927SAndroid Build Coastguard Worker       struct vn_image_reqs_cache_entry *cache_entry = hash_entry->data;
237*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < cache_entry->plane_count; i++)
238*61046927SAndroid Build Coastguard Worker          img->requirements[i] = cache_entry->requirements[i];
239*61046927SAndroid Build Coastguard Worker       list_move_to(&cache_entry->head, &dev->image_reqs_cache.lru);
240*61046927SAndroid Build Coastguard Worker       p_atomic_inc(&cache->debug.cache_hit_count);
241*61046927SAndroid Build Coastguard Worker    } else {
242*61046927SAndroid Build Coastguard Worker       p_atomic_inc(&cache->debug.cache_miss_count);
243*61046927SAndroid Build Coastguard Worker    }
244*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&cache->mutex);
245*61046927SAndroid Build Coastguard Worker 
246*61046927SAndroid Build Coastguard Worker    return !!hash_entry;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker static struct vn_image_memory_requirements *
vn_image_get_reqs_from_cache(struct vn_device * dev,uint8_t * key,uint32_t plane)250*61046927SAndroid Build Coastguard Worker vn_image_get_reqs_from_cache(struct vn_device *dev,
251*61046927SAndroid Build Coastguard Worker                              uint8_t *key,
252*61046927SAndroid Build Coastguard Worker                              uint32_t plane)
253*61046927SAndroid Build Coastguard Worker {
254*61046927SAndroid Build Coastguard Worker    struct vn_image_memory_requirements *requirements = NULL;
255*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache *cache = &dev->image_reqs_cache;
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker    assert(cache->ht);
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&cache->mutex);
260*61046927SAndroid Build Coastguard Worker    struct hash_entry *hash_entry = _mesa_hash_table_search(cache->ht, key);
261*61046927SAndroid Build Coastguard Worker    if (hash_entry) {
262*61046927SAndroid Build Coastguard Worker       struct vn_image_reqs_cache_entry *cache_entry = hash_entry->data;
263*61046927SAndroid Build Coastguard Worker       requirements = &cache_entry->requirements[plane];
264*61046927SAndroid Build Coastguard Worker       list_move_to(&cache_entry->head, &dev->image_reqs_cache.lru);
265*61046927SAndroid Build Coastguard Worker       p_atomic_inc(&cache->debug.cache_hit_count);
266*61046927SAndroid Build Coastguard Worker    } else {
267*61046927SAndroid Build Coastguard Worker       p_atomic_inc(&cache->debug.cache_miss_count);
268*61046927SAndroid Build Coastguard Worker    }
269*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&cache->mutex);
270*61046927SAndroid Build Coastguard Worker 
271*61046927SAndroid Build Coastguard Worker    return requirements;
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker 
274*61046927SAndroid Build Coastguard Worker static void
vn_image_store_reqs_in_cache(struct vn_device * dev,uint8_t * key,uint32_t plane_count,struct vn_image_memory_requirements * requirements)275*61046927SAndroid Build Coastguard Worker vn_image_store_reqs_in_cache(struct vn_device *dev,
276*61046927SAndroid Build Coastguard Worker                              uint8_t *key,
277*61046927SAndroid Build Coastguard Worker                              uint32_t plane_count,
278*61046927SAndroid Build Coastguard Worker                              struct vn_image_memory_requirements *requirements)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
281*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache *cache = &dev->image_reqs_cache;
282*61046927SAndroid Build Coastguard Worker    struct vn_image_reqs_cache_entry *cache_entry;
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    assert(cache->ht);
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&cache->mutex);
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    /* Check if entry was added before lock */
289*61046927SAndroid Build Coastguard Worker    if (_mesa_hash_table_search(cache->ht, key)) {
290*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&cache->mutex);
291*61046927SAndroid Build Coastguard Worker       return;
292*61046927SAndroid Build Coastguard Worker    }
293*61046927SAndroid Build Coastguard Worker 
294*61046927SAndroid Build Coastguard Worker    if (_mesa_hash_table_num_entries(cache->ht) ==
295*61046927SAndroid Build Coastguard Worker        IMAGE_REQS_CACHE_MAX_ENTRIES) {
296*61046927SAndroid Build Coastguard Worker       /* Evict/use the last entry in the lru list for this new entry */
297*61046927SAndroid Build Coastguard Worker       cache_entry =
298*61046927SAndroid Build Coastguard Worker          list_last_entry(&cache->lru, struct vn_image_reqs_cache_entry, head);
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_remove_key(cache->ht, cache_entry->key);
301*61046927SAndroid Build Coastguard Worker       list_del(&cache_entry->head);
302*61046927SAndroid Build Coastguard Worker    } else {
303*61046927SAndroid Build Coastguard Worker       cache_entry = vk_zalloc(alloc, sizeof(*cache_entry), VN_DEFAULT_ALIGN,
304*61046927SAndroid Build Coastguard Worker                               VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
305*61046927SAndroid Build Coastguard Worker       if (!cache_entry) {
306*61046927SAndroid Build Coastguard Worker          simple_mtx_unlock(&cache->mutex);
307*61046927SAndroid Build Coastguard Worker          return;
308*61046927SAndroid Build Coastguard Worker       }
309*61046927SAndroid Build Coastguard Worker    }
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < plane_count; i++)
312*61046927SAndroid Build Coastguard Worker       cache_entry->requirements[i] = requirements[i];
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker    memcpy(cache_entry->key, key, SHA1_DIGEST_LENGTH);
315*61046927SAndroid Build Coastguard Worker    cache_entry->plane_count = plane_count;
316*61046927SAndroid Build Coastguard Worker 
317*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(dev->image_reqs_cache.ht, cache_entry->key,
318*61046927SAndroid Build Coastguard Worker                            cache_entry);
319*61046927SAndroid Build Coastguard Worker    list_add(&cache_entry->head, &cache->lru);
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&cache->mutex);
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker static void
vn_image_init_memory_requirements(struct vn_image * img,struct vn_device * dev,uint32_t plane_count)325*61046927SAndroid Build Coastguard Worker vn_image_init_memory_requirements(struct vn_image *img,
326*61046927SAndroid Build Coastguard Worker                                   struct vn_device *dev,
327*61046927SAndroid Build Coastguard Worker                                   uint32_t plane_count)
328*61046927SAndroid Build Coastguard Worker {
329*61046927SAndroid Build Coastguard Worker    assert(plane_count <= ARRAY_SIZE(img->requirements));
330*61046927SAndroid Build Coastguard Worker 
331*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < plane_count; i++) {
332*61046927SAndroid Build Coastguard Worker       img->requirements[i].memory.sType =
333*61046927SAndroid Build Coastguard Worker          VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
334*61046927SAndroid Build Coastguard Worker       img->requirements[i].memory.pNext = &img->requirements[i].dedicated;
335*61046927SAndroid Build Coastguard Worker       img->requirements[i].dedicated.sType =
336*61046927SAndroid Build Coastguard Worker          VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
337*61046927SAndroid Build Coastguard Worker       img->requirements[i].dedicated.pNext = NULL;
338*61046927SAndroid Build Coastguard Worker    }
339*61046927SAndroid Build Coastguard Worker 
340*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
341*61046927SAndroid Build Coastguard Worker    VkImage img_handle = vn_image_to_handle(img);
342*61046927SAndroid Build Coastguard Worker    if (plane_count == 1) {
343*61046927SAndroid Build Coastguard Worker       vn_call_vkGetImageMemoryRequirements2(
344*61046927SAndroid Build Coastguard Worker          dev->primary_ring, dev_handle,
345*61046927SAndroid Build Coastguard Worker          &(VkImageMemoryRequirementsInfo2){
346*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
347*61046927SAndroid Build Coastguard Worker             .image = img_handle,
348*61046927SAndroid Build Coastguard Worker          },
349*61046927SAndroid Build Coastguard Worker          &img->requirements[0].memory);
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker       /* AHB backed image requires dedicated allocation */
352*61046927SAndroid Build Coastguard Worker       if (img->deferred_info) {
353*61046927SAndroid Build Coastguard Worker          img->requirements[0].dedicated.prefersDedicatedAllocation = VK_TRUE;
354*61046927SAndroid Build Coastguard Worker          img->requirements[0].dedicated.requiresDedicatedAllocation = VK_TRUE;
355*61046927SAndroid Build Coastguard Worker       }
356*61046927SAndroid Build Coastguard Worker    } else {
357*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < plane_count; i++) {
358*61046927SAndroid Build Coastguard Worker          vn_call_vkGetImageMemoryRequirements2(
359*61046927SAndroid Build Coastguard Worker             dev->primary_ring, dev_handle,
360*61046927SAndroid Build Coastguard Worker             &(VkImageMemoryRequirementsInfo2){
361*61046927SAndroid Build Coastguard Worker                .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
362*61046927SAndroid Build Coastguard Worker                .pNext =
363*61046927SAndroid Build Coastguard Worker                   &(VkImagePlaneMemoryRequirementsInfo){
364*61046927SAndroid Build Coastguard Worker                      .sType =
365*61046927SAndroid Build Coastguard Worker                         VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
366*61046927SAndroid Build Coastguard Worker                      .planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT << i,
367*61046927SAndroid Build Coastguard Worker                   },
368*61046927SAndroid Build Coastguard Worker                .image = img_handle,
369*61046927SAndroid Build Coastguard Worker             },
370*61046927SAndroid Build Coastguard Worker             &img->requirements[i].memory);
371*61046927SAndroid Build Coastguard Worker       }
372*61046927SAndroid Build Coastguard Worker    }
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker static VkResult
vn_image_deferred_info_init(struct vn_image * img,const VkImageCreateInfo * create_info,const VkAllocationCallbacks * alloc)376*61046927SAndroid Build Coastguard Worker vn_image_deferred_info_init(struct vn_image *img,
377*61046927SAndroid Build Coastguard Worker                             const VkImageCreateInfo *create_info,
378*61046927SAndroid Build Coastguard Worker                             const VkAllocationCallbacks *alloc)
379*61046927SAndroid Build Coastguard Worker {
380*61046927SAndroid Build Coastguard Worker    struct vn_image_create_deferred_info *info = NULL;
381*61046927SAndroid Build Coastguard Worker    VkBaseOutStructure *dst = NULL;
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker    info = vk_zalloc(alloc, sizeof(*info), VN_DEFAULT_ALIGN,
384*61046927SAndroid Build Coastguard Worker                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
385*61046927SAndroid Build Coastguard Worker    if (!info)
386*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
387*61046927SAndroid Build Coastguard Worker 
388*61046927SAndroid Build Coastguard Worker    info->create = *create_info;
389*61046927SAndroid Build Coastguard Worker    dst = (void *)&info->create;
390*61046927SAndroid Build Coastguard Worker 
391*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(src, create_info->pNext) {
392*61046927SAndroid Build Coastguard Worker       void *pnext = NULL;
393*61046927SAndroid Build Coastguard Worker       switch (src->sType) {
394*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: {
395*61046927SAndroid Build Coastguard Worker          /* 12.3. Images
396*61046927SAndroid Build Coastguard Worker           *
397*61046927SAndroid Build Coastguard Worker           * If viewFormatCount is zero, pViewFormats is ignored and the image
398*61046927SAndroid Build Coastguard Worker           * is created as if the VkImageFormatListCreateInfo structure were
399*61046927SAndroid Build Coastguard Worker           * not included in the pNext chain of VkImageCreateInfo.
400*61046927SAndroid Build Coastguard Worker           */
401*61046927SAndroid Build Coastguard Worker          if (!((const VkImageFormatListCreateInfo *)src)->viewFormatCount)
402*61046927SAndroid Build Coastguard Worker             break;
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker          memcpy(&info->list, src, sizeof(info->list));
405*61046927SAndroid Build Coastguard Worker          pnext = &info->list;
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker          /* need a deep copy for view formats array */
408*61046927SAndroid Build Coastguard Worker          const size_t size = sizeof(VkFormat) * info->list.viewFormatCount;
409*61046927SAndroid Build Coastguard Worker          VkFormat *view_formats = vk_zalloc(
410*61046927SAndroid Build Coastguard Worker             alloc, size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
411*61046927SAndroid Build Coastguard Worker          if (!view_formats) {
412*61046927SAndroid Build Coastguard Worker             vk_free(alloc, info);
413*61046927SAndroid Build Coastguard Worker             return VK_ERROR_OUT_OF_HOST_MEMORY;
414*61046927SAndroid Build Coastguard Worker          }
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker          memcpy(view_formats,
417*61046927SAndroid Build Coastguard Worker                 ((const VkImageFormatListCreateInfo *)src)->pViewFormats,
418*61046927SAndroid Build Coastguard Worker                 size);
419*61046927SAndroid Build Coastguard Worker          info->list.pViewFormats = view_formats;
420*61046927SAndroid Build Coastguard Worker       } break;
421*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
422*61046927SAndroid Build Coastguard Worker          memcpy(&info->stencil, src, sizeof(info->stencil));
423*61046927SAndroid Build Coastguard Worker          pnext = &info->stencil;
424*61046927SAndroid Build Coastguard Worker          break;
425*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID: {
426*61046927SAndroid Build Coastguard Worker          const uint32_t drm_format =
427*61046927SAndroid Build Coastguard Worker             (uint32_t)((const VkExternalFormatANDROID *)src)->externalFormat;
428*61046927SAndroid Build Coastguard Worker          if (drm_format) {
429*61046927SAndroid Build Coastguard Worker             info->create.format =
430*61046927SAndroid Build Coastguard Worker                vn_android_drm_format_to_vk_format(drm_format);
431*61046927SAndroid Build Coastguard Worker             info->from_external_format = true;
432*61046927SAndroid Build Coastguard Worker          }
433*61046927SAndroid Build Coastguard Worker       } break;
434*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
435*61046927SAndroid Build Coastguard Worker          img->wsi.is_wsi = true;
436*61046927SAndroid Build Coastguard Worker          break;
437*61046927SAndroid Build Coastguard Worker       default:
438*61046927SAndroid Build Coastguard Worker          break;
439*61046927SAndroid Build Coastguard Worker       }
440*61046927SAndroid Build Coastguard Worker 
441*61046927SAndroid Build Coastguard Worker       if (pnext) {
442*61046927SAndroid Build Coastguard Worker          dst->pNext = pnext;
443*61046927SAndroid Build Coastguard Worker          dst = pnext;
444*61046927SAndroid Build Coastguard Worker       }
445*61046927SAndroid Build Coastguard Worker    }
446*61046927SAndroid Build Coastguard Worker    dst->pNext = NULL;
447*61046927SAndroid Build Coastguard Worker 
448*61046927SAndroid Build Coastguard Worker    img->deferred_info = info;
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
451*61046927SAndroid Build Coastguard Worker }
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker static void
vn_image_deferred_info_fini(struct vn_image * img,const VkAllocationCallbacks * alloc)454*61046927SAndroid Build Coastguard Worker vn_image_deferred_info_fini(struct vn_image *img,
455*61046927SAndroid Build Coastguard Worker                             const VkAllocationCallbacks *alloc)
456*61046927SAndroid Build Coastguard Worker {
457*61046927SAndroid Build Coastguard Worker    if (!img->deferred_info)
458*61046927SAndroid Build Coastguard Worker       return;
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker    if (img->deferred_info->list.pViewFormats)
461*61046927SAndroid Build Coastguard Worker       vk_free(alloc, (void *)img->deferred_info->list.pViewFormats);
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker    vk_free(alloc, img->deferred_info);
464*61046927SAndroid Build Coastguard Worker }
465*61046927SAndroid Build Coastguard Worker 
466*61046927SAndroid Build Coastguard Worker static VkResult
vn_image_init(struct vn_device * dev,const VkImageCreateInfo * create_info,struct vn_image * img)467*61046927SAndroid Build Coastguard Worker vn_image_init(struct vn_device *dev,
468*61046927SAndroid Build Coastguard Worker               const VkImageCreateInfo *create_info,
469*61046927SAndroid Build Coastguard Worker               struct vn_image *img)
470*61046927SAndroid Build Coastguard Worker {
471*61046927SAndroid Build Coastguard Worker    VkDevice device = vn_device_to_handle(dev);
472*61046927SAndroid Build Coastguard Worker    VkImage image = vn_image_to_handle(img);
473*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
474*61046927SAndroid Build Coastguard Worker 
475*61046927SAndroid Build Coastguard Worker    img->sharing_mode = create_info->sharingMode;
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker    /* Check if mem reqs in cache. If found, make async call */
478*61046927SAndroid Build Coastguard Worker    uint8_t key[SHA1_DIGEST_LENGTH] = { 0 };
479*61046927SAndroid Build Coastguard Worker    const bool cacheable = vn_image_get_image_reqs_key(dev, create_info, key);
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker    if (cacheable && vn_image_init_reqs_from_cache(dev, img, key)) {
482*61046927SAndroid Build Coastguard Worker       vn_async_vkCreateImage(dev->primary_ring, device, create_info, NULL,
483*61046927SAndroid Build Coastguard Worker                              &image);
484*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
485*61046927SAndroid Build Coastguard Worker    }
486*61046927SAndroid Build Coastguard Worker 
487*61046927SAndroid Build Coastguard Worker    result = vn_call_vkCreateImage(dev->primary_ring, device, create_info,
488*61046927SAndroid Build Coastguard Worker                                   NULL, &image);
489*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
490*61046927SAndroid Build Coastguard Worker       return result;
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker    const uint32_t plane_count = vn_image_get_plane_count(create_info);
493*61046927SAndroid Build Coastguard Worker    vn_image_init_memory_requirements(img, dev, plane_count);
494*61046927SAndroid Build Coastguard Worker 
495*61046927SAndroid Build Coastguard Worker    if (cacheable)
496*61046927SAndroid Build Coastguard Worker       vn_image_store_reqs_in_cache(dev, key, plane_count, img->requirements);
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker 
501*61046927SAndroid Build Coastguard Worker VkResult
vn_image_create(struct vn_device * dev,const VkImageCreateInfo * create_info,const VkAllocationCallbacks * alloc,struct vn_image ** out_img)502*61046927SAndroid Build Coastguard Worker vn_image_create(struct vn_device *dev,
503*61046927SAndroid Build Coastguard Worker                 const VkImageCreateInfo *create_info,
504*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *alloc,
505*61046927SAndroid Build Coastguard Worker                 struct vn_image **out_img)
506*61046927SAndroid Build Coastguard Worker {
507*61046927SAndroid Build Coastguard Worker    struct vn_image *img =
508*61046927SAndroid Build Coastguard Worker       vk_image_create(&dev->base.base, create_info, alloc, sizeof(*img));
509*61046927SAndroid Build Coastguard Worker    if (!img)
510*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
511*61046927SAndroid Build Coastguard Worker 
512*61046927SAndroid Build Coastguard Worker    vn_object_set_id(img, vn_get_next_obj_id(), VK_OBJECT_TYPE_IMAGE);
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker    VkResult result = vn_image_init(dev, create_info, img);
515*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
516*61046927SAndroid Build Coastguard Worker       vk_image_destroy(&dev->base.base, alloc, &img->base.base);
517*61046927SAndroid Build Coastguard Worker       return result;
518*61046927SAndroid Build Coastguard Worker    }
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker    *out_img = img;
521*61046927SAndroid Build Coastguard Worker 
522*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
523*61046927SAndroid Build Coastguard Worker }
524*61046927SAndroid Build Coastguard Worker 
525*61046927SAndroid Build Coastguard Worker VkResult
vn_image_init_deferred(struct vn_device * dev,const VkImageCreateInfo * create_info,struct vn_image * img)526*61046927SAndroid Build Coastguard Worker vn_image_init_deferred(struct vn_device *dev,
527*61046927SAndroid Build Coastguard Worker                        const VkImageCreateInfo *create_info,
528*61046927SAndroid Build Coastguard Worker                        struct vn_image *img)
529*61046927SAndroid Build Coastguard Worker {
530*61046927SAndroid Build Coastguard Worker    VkResult result = vn_image_init(dev, create_info, img);
531*61046927SAndroid Build Coastguard Worker    img->deferred_info->initialized = result == VK_SUCCESS;
532*61046927SAndroid Build Coastguard Worker    return result;
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker 
535*61046927SAndroid Build Coastguard Worker static VkResult
vn_image_create_deferred(struct vn_device * dev,const VkImageCreateInfo * create_info,const VkAllocationCallbacks * alloc,struct vn_image ** out_img)536*61046927SAndroid Build Coastguard Worker vn_image_create_deferred(struct vn_device *dev,
537*61046927SAndroid Build Coastguard Worker                          const VkImageCreateInfo *create_info,
538*61046927SAndroid Build Coastguard Worker                          const VkAllocationCallbacks *alloc,
539*61046927SAndroid Build Coastguard Worker                          struct vn_image **out_img)
540*61046927SAndroid Build Coastguard Worker {
541*61046927SAndroid Build Coastguard Worker    struct vn_image *img =
542*61046927SAndroid Build Coastguard Worker       vk_image_create(&dev->base.base, create_info, alloc, sizeof(*img));
543*61046927SAndroid Build Coastguard Worker    if (!img)
544*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
545*61046927SAndroid Build Coastguard Worker 
546*61046927SAndroid Build Coastguard Worker    vn_object_set_id(img, vn_get_next_obj_id(), VK_OBJECT_TYPE_IMAGE);
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    VkResult result = vn_image_deferred_info_init(img, create_info, alloc);
549*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
550*61046927SAndroid Build Coastguard Worker       vk_image_destroy(&dev->base.base, alloc, &img->base.base);
551*61046927SAndroid Build Coastguard Worker       return result;
552*61046927SAndroid Build Coastguard Worker    }
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker    *out_img = img;
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
557*61046927SAndroid Build Coastguard Worker }
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker struct vn_image_create_info {
560*61046927SAndroid Build Coastguard Worker    VkImageCreateInfo create;
561*61046927SAndroid Build Coastguard Worker    VkExternalMemoryImageCreateInfo external;
562*61046927SAndroid Build Coastguard Worker    VkImageFormatListCreateInfo format_list;
563*61046927SAndroid Build Coastguard Worker    VkImageStencilUsageCreateInfo stencil;
564*61046927SAndroid Build Coastguard Worker    VkImageDrmFormatModifierListCreateInfoEXT modifier_list;
565*61046927SAndroid Build Coastguard Worker    VkImageDrmFormatModifierExplicitCreateInfoEXT modifier_explicit;
566*61046927SAndroid Build Coastguard Worker };
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker static const VkImageCreateInfo *
vn_image_fix_create_info(const VkImageCreateInfo * create_info,const VkExternalMemoryHandleTypeFlagBits renderer_handle_type,struct vn_image_create_info * local_info)569*61046927SAndroid Build Coastguard Worker vn_image_fix_create_info(
570*61046927SAndroid Build Coastguard Worker    const VkImageCreateInfo *create_info,
571*61046927SAndroid Build Coastguard Worker    const VkExternalMemoryHandleTypeFlagBits renderer_handle_type,
572*61046927SAndroid Build Coastguard Worker    struct vn_image_create_info *local_info)
573*61046927SAndroid Build Coastguard Worker {
574*61046927SAndroid Build Coastguard Worker    local_info->create = *create_info;
575*61046927SAndroid Build Coastguard Worker    VkBaseOutStructure *cur = (void *)&local_info->create;
576*61046927SAndroid Build Coastguard Worker 
577*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(src, create_info->pNext) {
578*61046927SAndroid Build Coastguard Worker       void *next = NULL;
579*61046927SAndroid Build Coastguard Worker       switch (src->sType) {
580*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO:
581*61046927SAndroid Build Coastguard Worker          memcpy(&local_info->external, src, sizeof(local_info->external));
582*61046927SAndroid Build Coastguard Worker          local_info->external.handleTypes = renderer_handle_type;
583*61046927SAndroid Build Coastguard Worker          next = &local_info->external;
584*61046927SAndroid Build Coastguard Worker          break;
585*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO:
586*61046927SAndroid Build Coastguard Worker          memcpy(&local_info->format_list, src,
587*61046927SAndroid Build Coastguard Worker                 sizeof(local_info->format_list));
588*61046927SAndroid Build Coastguard Worker          next = &local_info->format_list;
589*61046927SAndroid Build Coastguard Worker          break;
590*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO:
591*61046927SAndroid Build Coastguard Worker          memcpy(&local_info->stencil, src, sizeof(local_info->stencil));
592*61046927SAndroid Build Coastguard Worker          next = &local_info->stencil;
593*61046927SAndroid Build Coastguard Worker          break;
594*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT:
595*61046927SAndroid Build Coastguard Worker          memcpy(&local_info->modifier_list, src,
596*61046927SAndroid Build Coastguard Worker                 sizeof(local_info->modifier_list));
597*61046927SAndroid Build Coastguard Worker          next = &local_info->modifier_list;
598*61046927SAndroid Build Coastguard Worker          break;
599*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT:
600*61046927SAndroid Build Coastguard Worker          memcpy(&local_info->modifier_explicit, src,
601*61046927SAndroid Build Coastguard Worker                 sizeof(local_info->modifier_explicit));
602*61046927SAndroid Build Coastguard Worker          next = &local_info->modifier_explicit;
603*61046927SAndroid Build Coastguard Worker          break;
604*61046927SAndroid Build Coastguard Worker       default:
605*61046927SAndroid Build Coastguard Worker          break;
606*61046927SAndroid Build Coastguard Worker       }
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker       if (next) {
609*61046927SAndroid Build Coastguard Worker          cur->pNext = next;
610*61046927SAndroid Build Coastguard Worker          cur = next;
611*61046927SAndroid Build Coastguard Worker       }
612*61046927SAndroid Build Coastguard Worker    }
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker    cur->pNext = NULL;
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker    return &local_info->create;
617*61046927SAndroid Build Coastguard Worker }
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)620*61046927SAndroid Build Coastguard Worker vn_CreateImage(VkDevice device,
621*61046927SAndroid Build Coastguard Worker                const VkImageCreateInfo *pCreateInfo,
622*61046927SAndroid Build Coastguard Worker                const VkAllocationCallbacks *pAllocator,
623*61046927SAndroid Build Coastguard Worker                VkImage *pImage)
624*61046927SAndroid Build Coastguard Worker {
625*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
626*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
627*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
628*61046927SAndroid Build Coastguard Worker    const VkExternalMemoryHandleTypeFlagBits renderer_handle_type =
629*61046927SAndroid Build Coastguard Worker       dev->physical_device->external_memory.renderer_handle_type;
630*61046927SAndroid Build Coastguard Worker    struct vn_image *img;
631*61046927SAndroid Build Coastguard Worker    VkResult result;
632*61046927SAndroid Build Coastguard Worker 
633*61046927SAndroid Build Coastguard Worker    const struct wsi_image_create_info *wsi_info = NULL;
634*61046927SAndroid Build Coastguard Worker    const VkNativeBufferANDROID *anb_info = NULL;
635*61046927SAndroid Build Coastguard Worker    const VkImageSwapchainCreateInfoKHR *swapchain_info = NULL;
636*61046927SAndroid Build Coastguard Worker    const VkExternalMemoryImageCreateInfo *external_info = NULL;
637*61046927SAndroid Build Coastguard Worker    bool ahb_info = false;
638*61046927SAndroid Build Coastguard Worker 
639*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const(pnext, pCreateInfo->pNext) {
640*61046927SAndroid Build Coastguard Worker       switch ((uint32_t)pnext->sType) {
641*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA:
642*61046927SAndroid Build Coastguard Worker          wsi_info = (void *)pnext;
643*61046927SAndroid Build Coastguard Worker          break;
644*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID:
645*61046927SAndroid Build Coastguard Worker          anb_info = (void *)pnext;
646*61046927SAndroid Build Coastguard Worker          break;
647*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
648*61046927SAndroid Build Coastguard Worker          swapchain_info = (void *)pnext;
649*61046927SAndroid Build Coastguard Worker          if (!swapchain_info->swapchain)
650*61046927SAndroid Build Coastguard Worker             swapchain_info = NULL;
651*61046927SAndroid Build Coastguard Worker          break;
652*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO:
653*61046927SAndroid Build Coastguard Worker          external_info = (void *)pnext;
654*61046927SAndroid Build Coastguard Worker          if (!external_info->handleTypes)
655*61046927SAndroid Build Coastguard Worker             external_info = NULL;
656*61046927SAndroid Build Coastguard Worker          else if (
657*61046927SAndroid Build Coastguard Worker             external_info->handleTypes ==
658*61046927SAndroid Build Coastguard Worker             VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
659*61046927SAndroid Build Coastguard Worker             ahb_info = true;
660*61046927SAndroid Build Coastguard Worker          break;
661*61046927SAndroid Build Coastguard Worker       default:
662*61046927SAndroid Build Coastguard Worker          break;
663*61046927SAndroid Build Coastguard Worker       }
664*61046927SAndroid Build Coastguard Worker    }
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker    /* No need to fix external handle type for:
667*61046927SAndroid Build Coastguard Worker     * - common wsi image: dma_buf is hard-coded in wsi_configure_native_image
668*61046927SAndroid Build Coastguard Worker     * - common wsi image alias: it aligns with wsi_info on external handle
669*61046927SAndroid Build Coastguard Worker     * - Android wsi image: VK_ANDROID_native_buffer involves no external info
670*61046927SAndroid Build Coastguard Worker     * - AHB external image: deferred creation reconstructs external info
671*61046927SAndroid Build Coastguard Worker     *
672*61046927SAndroid Build Coastguard Worker     * Must fix the external handle type for:
673*61046927SAndroid Build Coastguard Worker     * - non-AHB external image requesting handle types different from renderer
674*61046927SAndroid Build Coastguard Worker     *
675*61046927SAndroid Build Coastguard Worker     * Will have to fix more when renderer handle type is no longer dma_buf.
676*61046927SAndroid Build Coastguard Worker     */
677*61046927SAndroid Build Coastguard Worker    if (wsi_info) {
678*61046927SAndroid Build Coastguard Worker       assert(external_info->handleTypes == renderer_handle_type);
679*61046927SAndroid Build Coastguard Worker       result = vn_wsi_create_image(dev, pCreateInfo, wsi_info, alloc, &img);
680*61046927SAndroid Build Coastguard Worker    } else if (anb_info) {
681*61046927SAndroid Build Coastguard Worker       result =
682*61046927SAndroid Build Coastguard Worker          vn_android_image_from_anb(dev, pCreateInfo, anb_info, alloc, &img);
683*61046927SAndroid Build Coastguard Worker    } else if (ahb_info) {
684*61046927SAndroid Build Coastguard Worker       result = vn_image_create_deferred(dev, pCreateInfo, alloc, &img);
685*61046927SAndroid Build Coastguard Worker    } else if (swapchain_info) {
686*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
687*61046927SAndroid Build Coastguard Worker       result = vn_image_create_deferred(dev, pCreateInfo, alloc, &img);
688*61046927SAndroid Build Coastguard Worker #else
689*61046927SAndroid Build Coastguard Worker       result = vn_wsi_create_image_from_swapchain(
690*61046927SAndroid Build Coastguard Worker          dev, pCreateInfo, swapchain_info, alloc, &img);
691*61046927SAndroid Build Coastguard Worker #endif
692*61046927SAndroid Build Coastguard Worker    } else {
693*61046927SAndroid Build Coastguard Worker       struct vn_image_create_info local_info;
694*61046927SAndroid Build Coastguard Worker       if (external_info &&
695*61046927SAndroid Build Coastguard Worker           external_info->handleTypes != renderer_handle_type) {
696*61046927SAndroid Build Coastguard Worker          pCreateInfo = vn_image_fix_create_info(
697*61046927SAndroid Build Coastguard Worker             pCreateInfo, renderer_handle_type, &local_info);
698*61046927SAndroid Build Coastguard Worker       }
699*61046927SAndroid Build Coastguard Worker 
700*61046927SAndroid Build Coastguard Worker       result = vn_image_create(dev, pCreateInfo, alloc, &img);
701*61046927SAndroid Build Coastguard Worker    }
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
704*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, result);
705*61046927SAndroid Build Coastguard Worker 
706*61046927SAndroid Build Coastguard Worker    *pImage = vn_image_to_handle(img);
707*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker 
710*61046927SAndroid Build Coastguard Worker void
vn_DestroyImage(VkDevice device,VkImage image,const VkAllocationCallbacks * pAllocator)711*61046927SAndroid Build Coastguard Worker vn_DestroyImage(VkDevice device,
712*61046927SAndroid Build Coastguard Worker                 VkImage image,
713*61046927SAndroid Build Coastguard Worker                 const VkAllocationCallbacks *pAllocator)
714*61046927SAndroid Build Coastguard Worker {
715*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
716*61046927SAndroid Build Coastguard Worker    struct vn_image *img = vn_image_from_handle(image);
717*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
718*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker    if (!img)
721*61046927SAndroid Build Coastguard Worker       return;
722*61046927SAndroid Build Coastguard Worker 
723*61046927SAndroid Build Coastguard Worker    if (img->wsi.memory && img->wsi.memory_owned) {
724*61046927SAndroid Build Coastguard Worker       VkDeviceMemory mem_handle = vn_device_memory_to_handle(img->wsi.memory);
725*61046927SAndroid Build Coastguard Worker       vn_FreeMemory(device, mem_handle, pAllocator);
726*61046927SAndroid Build Coastguard Worker    }
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker    /* must not ask renderer to destroy uninitialized deferred image */
729*61046927SAndroid Build Coastguard Worker    if (!img->deferred_info || img->deferred_info->initialized)
730*61046927SAndroid Build Coastguard Worker       vn_async_vkDestroyImage(dev->primary_ring, device, image, NULL);
731*61046927SAndroid Build Coastguard Worker 
732*61046927SAndroid Build Coastguard Worker    vn_image_deferred_info_fini(img, alloc);
733*61046927SAndroid Build Coastguard Worker 
734*61046927SAndroid Build Coastguard Worker    vk_image_destroy(&dev->base.base, alloc, &img->base.base);
735*61046927SAndroid Build Coastguard Worker }
736*61046927SAndroid Build Coastguard Worker 
737*61046927SAndroid Build Coastguard Worker void
vn_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)738*61046927SAndroid Build Coastguard Worker vn_GetImageMemoryRequirements2(VkDevice device,
739*61046927SAndroid Build Coastguard Worker                                const VkImageMemoryRequirementsInfo2 *pInfo,
740*61046927SAndroid Build Coastguard Worker                                VkMemoryRequirements2 *pMemoryRequirements)
741*61046927SAndroid Build Coastguard Worker {
742*61046927SAndroid Build Coastguard Worker    const struct vn_image *img = vn_image_from_handle(pInfo->image);
743*61046927SAndroid Build Coastguard Worker 
744*61046927SAndroid Build Coastguard Worker    uint32_t plane = 0;
745*61046927SAndroid Build Coastguard Worker    const VkImagePlaneMemoryRequirementsInfo *plane_info =
746*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pInfo->pNext,
747*61046927SAndroid Build Coastguard Worker                            IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO);
748*61046927SAndroid Build Coastguard Worker    if (plane_info)
749*61046927SAndroid Build Coastguard Worker       plane = vn_image_get_plane(plane_info->planeAspect);
750*61046927SAndroid Build Coastguard Worker 
751*61046927SAndroid Build Coastguard Worker    vn_image_fill_reqs(&img->requirements[plane], pMemoryRequirements);
752*61046927SAndroid Build Coastguard Worker }
753*61046927SAndroid Build Coastguard Worker 
754*61046927SAndroid Build Coastguard Worker void
vn_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)755*61046927SAndroid Build Coastguard Worker vn_GetImageSparseMemoryRequirements2(
756*61046927SAndroid Build Coastguard Worker    VkDevice device,
757*61046927SAndroid Build Coastguard Worker    const VkImageSparseMemoryRequirementsInfo2 *pInfo,
758*61046927SAndroid Build Coastguard Worker    uint32_t *pSparseMemoryRequirementCount,
759*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
760*61046927SAndroid Build Coastguard Worker {
761*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
762*61046927SAndroid Build Coastguard Worker 
763*61046927SAndroid Build Coastguard Worker    /* see vn_GetPhysicalDeviceSparseImageFormatProperties2 */
764*61046927SAndroid Build Coastguard Worker    if (dev->physical_device->sparse_binding_disabled) {
765*61046927SAndroid Build Coastguard Worker       *pSparseMemoryRequirementCount = 0;
766*61046927SAndroid Build Coastguard Worker       return;
767*61046927SAndroid Build Coastguard Worker    }
768*61046927SAndroid Build Coastguard Worker 
769*61046927SAndroid Build Coastguard Worker    /* TODO local or per-device cache */
770*61046927SAndroid Build Coastguard Worker    vn_call_vkGetImageSparseMemoryRequirements2(
771*61046927SAndroid Build Coastguard Worker       dev->primary_ring, device, pInfo, pSparseMemoryRequirementCount,
772*61046927SAndroid Build Coastguard Worker       pSparseMemoryRequirements);
773*61046927SAndroid Build Coastguard Worker }
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker static VkResult
vn_image_bind_wsi_memory(struct vn_device * dev,uint32_t count,const VkBindImageMemoryInfo * infos)776*61046927SAndroid Build Coastguard Worker vn_image_bind_wsi_memory(struct vn_device *dev,
777*61046927SAndroid Build Coastguard Worker                          uint32_t count,
778*61046927SAndroid Build Coastguard Worker                          const VkBindImageMemoryInfo *infos)
779*61046927SAndroid Build Coastguard Worker {
780*61046927SAndroid Build Coastguard Worker    STACK_ARRAY(VkBindImageMemoryInfo, local_infos, count);
781*61046927SAndroid Build Coastguard Worker    typed_memcpy(local_infos, infos, count);
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < count; i++) {
784*61046927SAndroid Build Coastguard Worker       VkBindImageMemoryInfo *info = &local_infos[i];
785*61046927SAndroid Build Coastguard Worker       struct vn_image *img = vn_image_from_handle(info->image);
786*61046927SAndroid Build Coastguard Worker       struct vn_device_memory *mem =
787*61046927SAndroid Build Coastguard Worker          vn_device_memory_from_handle(info->memory);
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker       if (!mem) {
790*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
791*61046927SAndroid Build Coastguard Worker          mem = vn_android_get_wsi_memory_from_bind_info(dev, info);
792*61046927SAndroid Build Coastguard Worker          if (!mem) {
793*61046927SAndroid Build Coastguard Worker             STACK_ARRAY_FINISH(local_infos);
794*61046927SAndroid Build Coastguard Worker             return VK_ERROR_OUT_OF_HOST_MEMORY;
795*61046927SAndroid Build Coastguard Worker          }
796*61046927SAndroid Build Coastguard Worker #else
797*61046927SAndroid Build Coastguard Worker          const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
798*61046927SAndroid Build Coastguard Worker             vk_find_struct_const(info->pNext,
799*61046927SAndroid Build Coastguard Worker                                  BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
800*61046927SAndroid Build Coastguard Worker          assert(img->wsi.is_wsi && swapchain_info);
801*61046927SAndroid Build Coastguard Worker 
802*61046927SAndroid Build Coastguard Worker          struct vn_image *swapchain_img =
803*61046927SAndroid Build Coastguard Worker             vn_image_from_handle(wsi_common_get_image(
804*61046927SAndroid Build Coastguard Worker                swapchain_info->swapchain, swapchain_info->imageIndex));
805*61046927SAndroid Build Coastguard Worker          mem = swapchain_img->wsi.memory;
806*61046927SAndroid Build Coastguard Worker #endif
807*61046927SAndroid Build Coastguard Worker          info->memory = vn_device_memory_to_handle(mem);
808*61046927SAndroid Build Coastguard Worker       }
809*61046927SAndroid Build Coastguard Worker       assert(mem && info->memory != VK_NULL_HANDLE);
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker #if DETECT_OS_ANDROID
812*61046927SAndroid Build Coastguard Worker       assert(img->wsi.memory);
813*61046927SAndroid Build Coastguard Worker #else
814*61046927SAndroid Build Coastguard Worker       assert(!img->wsi.memory);
815*61046927SAndroid Build Coastguard Worker       img->wsi.memory = mem;
816*61046927SAndroid Build Coastguard Worker #endif
817*61046927SAndroid Build Coastguard Worker    }
818*61046927SAndroid Build Coastguard Worker 
819*61046927SAndroid Build Coastguard Worker    vn_async_vkBindImageMemory2(dev->primary_ring, vn_device_to_handle(dev),
820*61046927SAndroid Build Coastguard Worker                                count, local_infos);
821*61046927SAndroid Build Coastguard Worker 
822*61046927SAndroid Build Coastguard Worker    STACK_ARRAY_FINISH(local_infos);
823*61046927SAndroid Build Coastguard Worker 
824*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
825*61046927SAndroid Build Coastguard Worker }
826*61046927SAndroid Build Coastguard Worker 
827*61046927SAndroid Build Coastguard Worker VkResult
vn_BindImageMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)828*61046927SAndroid Build Coastguard Worker vn_BindImageMemory2(VkDevice device,
829*61046927SAndroid Build Coastguard Worker                     uint32_t bindInfoCount,
830*61046927SAndroid Build Coastguard Worker                     const VkBindImageMemoryInfo *pBindInfos)
831*61046927SAndroid Build Coastguard Worker {
832*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
833*61046927SAndroid Build Coastguard Worker 
834*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < bindInfoCount; i++) {
835*61046927SAndroid Build Coastguard Worker       struct vn_image *img = vn_image_from_handle(pBindInfos[i].image);
836*61046927SAndroid Build Coastguard Worker       if (img->wsi.is_wsi)
837*61046927SAndroid Build Coastguard Worker          return vn_image_bind_wsi_memory(dev, bindInfoCount, pBindInfos);
838*61046927SAndroid Build Coastguard Worker    }
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker    vn_async_vkBindImageMemory2(dev->primary_ring, device, bindInfoCount,
841*61046927SAndroid Build Coastguard Worker                                pBindInfos);
842*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
843*61046927SAndroid Build Coastguard Worker }
844*61046927SAndroid Build Coastguard Worker 
845*61046927SAndroid Build Coastguard Worker VkResult
vn_GetImageDrmFormatModifierPropertiesEXT(VkDevice device,VkImage image,VkImageDrmFormatModifierPropertiesEXT * pProperties)846*61046927SAndroid Build Coastguard Worker vn_GetImageDrmFormatModifierPropertiesEXT(
847*61046927SAndroid Build Coastguard Worker    VkDevice device,
848*61046927SAndroid Build Coastguard Worker    VkImage image,
849*61046927SAndroid Build Coastguard Worker    VkImageDrmFormatModifierPropertiesEXT *pProperties)
850*61046927SAndroid Build Coastguard Worker {
851*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker    /* TODO local cache */
854*61046927SAndroid Build Coastguard Worker    return vn_call_vkGetImageDrmFormatModifierPropertiesEXT(
855*61046927SAndroid Build Coastguard Worker       dev->primary_ring, device, image, pProperties);
856*61046927SAndroid Build Coastguard Worker }
857*61046927SAndroid Build Coastguard Worker 
858*61046927SAndroid Build Coastguard Worker void
vn_GetImageSubresourceLayout(VkDevice device,VkImage image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)859*61046927SAndroid Build Coastguard Worker vn_GetImageSubresourceLayout(VkDevice device,
860*61046927SAndroid Build Coastguard Worker                              VkImage image,
861*61046927SAndroid Build Coastguard Worker                              const VkImageSubresource *pSubresource,
862*61046927SAndroid Build Coastguard Worker                              VkSubresourceLayout *pLayout)
863*61046927SAndroid Build Coastguard Worker {
864*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
865*61046927SAndroid Build Coastguard Worker    struct vn_image *img = vn_image_from_handle(image);
866*61046927SAndroid Build Coastguard Worker 
867*61046927SAndroid Build Coastguard Worker    /* override aspect mask for wsi/ahb images with tiling modifier */
868*61046927SAndroid Build Coastguard Worker    VkImageSubresource local_subresource;
869*61046927SAndroid Build Coastguard Worker    if ((img->wsi.is_wsi && img->wsi.tiling_override ==
870*61046927SAndroid Build Coastguard Worker                               VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ||
871*61046927SAndroid Build Coastguard Worker        img->deferred_info) {
872*61046927SAndroid Build Coastguard Worker       VkImageAspectFlags aspect = pSubresource->aspectMask;
873*61046927SAndroid Build Coastguard Worker       switch (aspect) {
874*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_COLOR_BIT:
875*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_DEPTH_BIT:
876*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_STENCIL_BIT:
877*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_0_BIT:
878*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
879*61046927SAndroid Build Coastguard Worker          break;
880*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_1_BIT:
881*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
882*61046927SAndroid Build Coastguard Worker          break;
883*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_2_BIT:
884*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
885*61046927SAndroid Build Coastguard Worker          break;
886*61046927SAndroid Build Coastguard Worker       default:
887*61046927SAndroid Build Coastguard Worker          break;
888*61046927SAndroid Build Coastguard Worker       }
889*61046927SAndroid Build Coastguard Worker 
890*61046927SAndroid Build Coastguard Worker       /* only handle supported aspect override */
891*61046927SAndroid Build Coastguard Worker       if (aspect != pSubresource->aspectMask) {
892*61046927SAndroid Build Coastguard Worker          local_subresource = *pSubresource;
893*61046927SAndroid Build Coastguard Worker          local_subresource.aspectMask = aspect;
894*61046927SAndroid Build Coastguard Worker          pSubresource = &local_subresource;
895*61046927SAndroid Build Coastguard Worker       }
896*61046927SAndroid Build Coastguard Worker    }
897*61046927SAndroid Build Coastguard Worker 
898*61046927SAndroid Build Coastguard Worker    /* TODO local cache */
899*61046927SAndroid Build Coastguard Worker    vn_call_vkGetImageSubresourceLayout(dev->primary_ring, device, image,
900*61046927SAndroid Build Coastguard Worker                                        pSubresource, pLayout);
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker 
903*61046927SAndroid Build Coastguard Worker /* image view commands */
904*61046927SAndroid Build Coastguard Worker 
905*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateImageView(VkDevice device,const VkImageViewCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImageView * pView)906*61046927SAndroid Build Coastguard Worker vn_CreateImageView(VkDevice device,
907*61046927SAndroid Build Coastguard Worker                    const VkImageViewCreateInfo *pCreateInfo,
908*61046927SAndroid Build Coastguard Worker                    const VkAllocationCallbacks *pAllocator,
909*61046927SAndroid Build Coastguard Worker                    VkImageView *pView)
910*61046927SAndroid Build Coastguard Worker {
911*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
912*61046927SAndroid Build Coastguard Worker    struct vn_image *img = vn_image_from_handle(pCreateInfo->image);
913*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
914*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
915*61046927SAndroid Build Coastguard Worker 
916*61046927SAndroid Build Coastguard Worker    VkImageViewCreateInfo local_info;
917*61046927SAndroid Build Coastguard Worker    if (img->deferred_info && img->deferred_info->from_external_format) {
918*61046927SAndroid Build Coastguard Worker       assert(pCreateInfo->format == VK_FORMAT_UNDEFINED);
919*61046927SAndroid Build Coastguard Worker 
920*61046927SAndroid Build Coastguard Worker       local_info = *pCreateInfo;
921*61046927SAndroid Build Coastguard Worker       local_info.format = img->deferred_info->create.format;
922*61046927SAndroid Build Coastguard Worker       pCreateInfo = &local_info;
923*61046927SAndroid Build Coastguard Worker 
924*61046927SAndroid Build Coastguard Worker       assert(pCreateInfo->format != VK_FORMAT_UNDEFINED);
925*61046927SAndroid Build Coastguard Worker    }
926*61046927SAndroid Build Coastguard Worker 
927*61046927SAndroid Build Coastguard Worker    struct vn_image_view *view =
928*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN,
929*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
930*61046927SAndroid Build Coastguard Worker    if (!view)
931*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
932*61046927SAndroid Build Coastguard Worker 
933*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&view->base, VK_OBJECT_TYPE_IMAGE_VIEW, &dev->base);
934*61046927SAndroid Build Coastguard Worker    view->image = img;
935*61046927SAndroid Build Coastguard Worker 
936*61046927SAndroid Build Coastguard Worker    VkImageView view_handle = vn_image_view_to_handle(view);
937*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateImageView(dev->primary_ring, device, pCreateInfo, NULL,
938*61046927SAndroid Build Coastguard Worker                               &view_handle);
939*61046927SAndroid Build Coastguard Worker 
940*61046927SAndroid Build Coastguard Worker    *pView = view_handle;
941*61046927SAndroid Build Coastguard Worker 
942*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
943*61046927SAndroid Build Coastguard Worker }
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker void
vn_DestroyImageView(VkDevice device,VkImageView imageView,const VkAllocationCallbacks * pAllocator)946*61046927SAndroid Build Coastguard Worker vn_DestroyImageView(VkDevice device,
947*61046927SAndroid Build Coastguard Worker                     VkImageView imageView,
948*61046927SAndroid Build Coastguard Worker                     const VkAllocationCallbacks *pAllocator)
949*61046927SAndroid Build Coastguard Worker {
950*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
951*61046927SAndroid Build Coastguard Worker    struct vn_image_view *view = vn_image_view_from_handle(imageView);
952*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
953*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
954*61046927SAndroid Build Coastguard Worker 
955*61046927SAndroid Build Coastguard Worker    if (!view)
956*61046927SAndroid Build Coastguard Worker       return;
957*61046927SAndroid Build Coastguard Worker 
958*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroyImageView(dev->primary_ring, device, imageView, NULL);
959*61046927SAndroid Build Coastguard Worker 
960*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&view->base);
961*61046927SAndroid Build Coastguard Worker    vk_free(alloc, view);
962*61046927SAndroid Build Coastguard Worker }
963*61046927SAndroid Build Coastguard Worker 
964*61046927SAndroid Build Coastguard Worker /* sampler commands */
965*61046927SAndroid Build Coastguard Worker 
966*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateSampler(VkDevice device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)967*61046927SAndroid Build Coastguard Worker vn_CreateSampler(VkDevice device,
968*61046927SAndroid Build Coastguard Worker                  const VkSamplerCreateInfo *pCreateInfo,
969*61046927SAndroid Build Coastguard Worker                  const VkAllocationCallbacks *pAllocator,
970*61046927SAndroid Build Coastguard Worker                  VkSampler *pSampler)
971*61046927SAndroid Build Coastguard Worker {
972*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
973*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
974*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker    struct vn_sampler *sampler =
977*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*sampler), VN_DEFAULT_ALIGN,
978*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
979*61046927SAndroid Build Coastguard Worker    if (!sampler)
980*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
981*61046927SAndroid Build Coastguard Worker 
982*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&sampler->base, VK_OBJECT_TYPE_SAMPLER, &dev->base);
983*61046927SAndroid Build Coastguard Worker 
984*61046927SAndroid Build Coastguard Worker    VkSampler sampler_handle = vn_sampler_to_handle(sampler);
985*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateSampler(dev->primary_ring, device, pCreateInfo, NULL,
986*61046927SAndroid Build Coastguard Worker                             &sampler_handle);
987*61046927SAndroid Build Coastguard Worker 
988*61046927SAndroid Build Coastguard Worker    *pSampler = sampler_handle;
989*61046927SAndroid Build Coastguard Worker 
990*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
991*61046927SAndroid Build Coastguard Worker }
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker void
vn_DestroySampler(VkDevice device,VkSampler _sampler,const VkAllocationCallbacks * pAllocator)994*61046927SAndroid Build Coastguard Worker vn_DestroySampler(VkDevice device,
995*61046927SAndroid Build Coastguard Worker                   VkSampler _sampler,
996*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *pAllocator)
997*61046927SAndroid Build Coastguard Worker {
998*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
999*61046927SAndroid Build Coastguard Worker    struct vn_sampler *sampler = vn_sampler_from_handle(_sampler);
1000*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
1001*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
1002*61046927SAndroid Build Coastguard Worker 
1003*61046927SAndroid Build Coastguard Worker    if (!sampler)
1004*61046927SAndroid Build Coastguard Worker       return;
1005*61046927SAndroid Build Coastguard Worker 
1006*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroySampler(dev->primary_ring, device, _sampler, NULL);
1007*61046927SAndroid Build Coastguard Worker 
1008*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&sampler->base);
1009*61046927SAndroid Build Coastguard Worker    vk_free(alloc, sampler);
1010*61046927SAndroid Build Coastguard Worker }
1011*61046927SAndroid Build Coastguard Worker 
1012*61046927SAndroid Build Coastguard Worker /* sampler YCbCr conversion commands */
1013*61046927SAndroid Build Coastguard Worker 
1014*61046927SAndroid Build Coastguard Worker VkResult
vn_CreateSamplerYcbcrConversion(VkDevice device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)1015*61046927SAndroid Build Coastguard Worker vn_CreateSamplerYcbcrConversion(
1016*61046927SAndroid Build Coastguard Worker    VkDevice device,
1017*61046927SAndroid Build Coastguard Worker    const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
1018*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *pAllocator,
1019*61046927SAndroid Build Coastguard Worker    VkSamplerYcbcrConversion *pYcbcrConversion)
1020*61046927SAndroid Build Coastguard Worker {
1021*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1022*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
1023*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
1024*61046927SAndroid Build Coastguard Worker    const VkExternalFormatANDROID *ext_info =
1025*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
1026*61046927SAndroid Build Coastguard Worker 
1027*61046927SAndroid Build Coastguard Worker    VkSamplerYcbcrConversionCreateInfo local_info;
1028*61046927SAndroid Build Coastguard Worker    if (ext_info && ext_info->externalFormat) {
1029*61046927SAndroid Build Coastguard Worker       assert(pCreateInfo->format == VK_FORMAT_UNDEFINED);
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker       local_info = *pCreateInfo;
1032*61046927SAndroid Build Coastguard Worker       local_info.format =
1033*61046927SAndroid Build Coastguard Worker          vn_android_drm_format_to_vk_format(ext_info->externalFormat);
1034*61046927SAndroid Build Coastguard Worker       local_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
1035*61046927SAndroid Build Coastguard Worker       local_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
1036*61046927SAndroid Build Coastguard Worker       local_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
1037*61046927SAndroid Build Coastguard Worker       local_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
1038*61046927SAndroid Build Coastguard Worker       pCreateInfo = &local_info;
1039*61046927SAndroid Build Coastguard Worker 
1040*61046927SAndroid Build Coastguard Worker       assert(pCreateInfo->format != VK_FORMAT_UNDEFINED);
1041*61046927SAndroid Build Coastguard Worker    }
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    struct vn_sampler_ycbcr_conversion *conv =
1044*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*conv), VN_DEFAULT_ALIGN,
1045*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1046*61046927SAndroid Build Coastguard Worker    if (!conv)
1047*61046927SAndroid Build Coastguard Worker       return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1048*61046927SAndroid Build Coastguard Worker 
1049*61046927SAndroid Build Coastguard Worker    vn_object_base_init(&conv->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION,
1050*61046927SAndroid Build Coastguard Worker                        &dev->base);
1051*61046927SAndroid Build Coastguard Worker 
1052*61046927SAndroid Build Coastguard Worker    VkSamplerYcbcrConversion conv_handle =
1053*61046927SAndroid Build Coastguard Worker       vn_sampler_ycbcr_conversion_to_handle(conv);
1054*61046927SAndroid Build Coastguard Worker    vn_async_vkCreateSamplerYcbcrConversion(dev->primary_ring, device,
1055*61046927SAndroid Build Coastguard Worker                                            pCreateInfo, NULL, &conv_handle);
1056*61046927SAndroid Build Coastguard Worker 
1057*61046927SAndroid Build Coastguard Worker    *pYcbcrConversion = conv_handle;
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1060*61046927SAndroid Build Coastguard Worker }
1061*61046927SAndroid Build Coastguard Worker 
1062*61046927SAndroid Build Coastguard Worker void
vn_DestroySamplerYcbcrConversion(VkDevice device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)1063*61046927SAndroid Build Coastguard Worker vn_DestroySamplerYcbcrConversion(VkDevice device,
1064*61046927SAndroid Build Coastguard Worker                                  VkSamplerYcbcrConversion ycbcrConversion,
1065*61046927SAndroid Build Coastguard Worker                                  const VkAllocationCallbacks *pAllocator)
1066*61046927SAndroid Build Coastguard Worker {
1067*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1068*61046927SAndroid Build Coastguard Worker    struct vn_sampler_ycbcr_conversion *conv =
1069*61046927SAndroid Build Coastguard Worker       vn_sampler_ycbcr_conversion_from_handle(ycbcrConversion);
1070*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc =
1071*61046927SAndroid Build Coastguard Worker       pAllocator ? pAllocator : &dev->base.base.alloc;
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker    if (!conv)
1074*61046927SAndroid Build Coastguard Worker       return;
1075*61046927SAndroid Build Coastguard Worker 
1076*61046927SAndroid Build Coastguard Worker    vn_async_vkDestroySamplerYcbcrConversion(dev->primary_ring, device,
1077*61046927SAndroid Build Coastguard Worker                                             ycbcrConversion, NULL);
1078*61046927SAndroid Build Coastguard Worker 
1079*61046927SAndroid Build Coastguard Worker    vn_object_base_fini(&conv->base);
1080*61046927SAndroid Build Coastguard Worker    vk_free(alloc, conv);
1081*61046927SAndroid Build Coastguard Worker }
1082*61046927SAndroid Build Coastguard Worker 
1083*61046927SAndroid Build Coastguard Worker void
vn_GetDeviceImageMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1084*61046927SAndroid Build Coastguard Worker vn_GetDeviceImageMemoryRequirements(
1085*61046927SAndroid Build Coastguard Worker    VkDevice device,
1086*61046927SAndroid Build Coastguard Worker    const VkDeviceImageMemoryRequirements *pInfo,
1087*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements2 *pMemoryRequirements)
1088*61046927SAndroid Build Coastguard Worker {
1089*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1090*61046927SAndroid Build Coastguard Worker 
1091*61046927SAndroid Build Coastguard Worker    uint8_t key[SHA1_DIGEST_LENGTH] = { 0 };
1092*61046927SAndroid Build Coastguard Worker    const bool cacheable =
1093*61046927SAndroid Build Coastguard Worker       vn_image_get_image_reqs_key(dev, pInfo->pCreateInfo, key);
1094*61046927SAndroid Build Coastguard Worker 
1095*61046927SAndroid Build Coastguard Worker    if (cacheable) {
1096*61046927SAndroid Build Coastguard Worker       uint32_t plane = 0;
1097*61046927SAndroid Build Coastguard Worker       if (pInfo->pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT)
1098*61046927SAndroid Build Coastguard Worker          vn_image_get_plane(pInfo->planeAspect);
1099*61046927SAndroid Build Coastguard Worker 
1100*61046927SAndroid Build Coastguard Worker       const struct vn_image_memory_requirements *cached_reqs =
1101*61046927SAndroid Build Coastguard Worker          vn_image_get_reqs_from_cache(dev, key, plane);
1102*61046927SAndroid Build Coastguard Worker       if (cached_reqs) {
1103*61046927SAndroid Build Coastguard Worker          vn_image_fill_reqs(cached_reqs, pMemoryRequirements);
1104*61046927SAndroid Build Coastguard Worker          return;
1105*61046927SAndroid Build Coastguard Worker       }
1106*61046927SAndroid Build Coastguard Worker 
1107*61046927SAndroid Build Coastguard Worker       const uint32_t plane_count =
1108*61046927SAndroid Build Coastguard Worker          vn_image_get_plane_count(pInfo->pCreateInfo);
1109*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(VkDeviceImageMemoryRequirements, req_info, plane_count);
1110*61046927SAndroid Build Coastguard Worker       STACK_ARRAY(struct vn_image_memory_requirements, reqs, plane_count);
1111*61046927SAndroid Build Coastguard Worker 
1112*61046927SAndroid Build Coastguard Worker       /* Retrieve reqs for all planes so the cache entry is complete */
1113*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < plane_count; i++) {
1114*61046927SAndroid Build Coastguard Worker          req_info[i].sType =
1115*61046927SAndroid Build Coastguard Worker             VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS;
1116*61046927SAndroid Build Coastguard Worker          req_info[i].pNext = NULL;
1117*61046927SAndroid Build Coastguard Worker          req_info[i].pCreateInfo = pInfo->pCreateInfo;
1118*61046927SAndroid Build Coastguard Worker          req_info[i].planeAspect = VK_IMAGE_ASPECT_PLANE_0_BIT << i;
1119*61046927SAndroid Build Coastguard Worker 
1120*61046927SAndroid Build Coastguard Worker          reqs[i].memory.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
1121*61046927SAndroid Build Coastguard Worker          reqs[i].memory.pNext = &reqs[i].dedicated;
1122*61046927SAndroid Build Coastguard Worker          reqs[i].dedicated.sType =
1123*61046927SAndroid Build Coastguard Worker             VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
1124*61046927SAndroid Build Coastguard Worker          reqs[i].dedicated.pNext = NULL;
1125*61046927SAndroid Build Coastguard Worker 
1126*61046927SAndroid Build Coastguard Worker          vn_call_vkGetDeviceImageMemoryRequirements(
1127*61046927SAndroid Build Coastguard Worker             dev->primary_ring, device, &req_info[i], &reqs[i].memory);
1128*61046927SAndroid Build Coastguard Worker       }
1129*61046927SAndroid Build Coastguard Worker       vn_image_fill_reqs(&reqs[plane], pMemoryRequirements);
1130*61046927SAndroid Build Coastguard Worker       vn_image_store_reqs_in_cache(dev, key, plane_count, reqs);
1131*61046927SAndroid Build Coastguard Worker 
1132*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(req_info);
1133*61046927SAndroid Build Coastguard Worker       STACK_ARRAY_FINISH(reqs);
1134*61046927SAndroid Build Coastguard Worker    } else {
1135*61046927SAndroid Build Coastguard Worker       vn_call_vkGetDeviceImageMemoryRequirements(dev->primary_ring, device,
1136*61046927SAndroid Build Coastguard Worker                                                  pInfo, pMemoryRequirements);
1137*61046927SAndroid Build Coastguard Worker    }
1138*61046927SAndroid Build Coastguard Worker }
1139*61046927SAndroid Build Coastguard Worker 
1140*61046927SAndroid Build Coastguard Worker void
vn_GetDeviceImageSparseMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1141*61046927SAndroid Build Coastguard Worker vn_GetDeviceImageSparseMemoryRequirements(
1142*61046927SAndroid Build Coastguard Worker    VkDevice device,
1143*61046927SAndroid Build Coastguard Worker    const VkDeviceImageMemoryRequirements *pInfo,
1144*61046927SAndroid Build Coastguard Worker    uint32_t *pSparseMemoryRequirementCount,
1145*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1146*61046927SAndroid Build Coastguard Worker {
1147*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1148*61046927SAndroid Build Coastguard Worker 
1149*61046927SAndroid Build Coastguard Worker    /* see vn_GetPhysicalDeviceSparseImageFormatProperties2 */
1150*61046927SAndroid Build Coastguard Worker    if (dev->physical_device->sparse_binding_disabled) {
1151*61046927SAndroid Build Coastguard Worker       *pSparseMemoryRequirementCount = 0;
1152*61046927SAndroid Build Coastguard Worker       return;
1153*61046927SAndroid Build Coastguard Worker    }
1154*61046927SAndroid Build Coastguard Worker 
1155*61046927SAndroid Build Coastguard Worker    /* TODO per-device cache */
1156*61046927SAndroid Build Coastguard Worker    vn_call_vkGetDeviceImageSparseMemoryRequirements(
1157*61046927SAndroid Build Coastguard Worker       dev->primary_ring, device, pInfo, pSparseMemoryRequirementCount,
1158*61046927SAndroid Build Coastguard Worker       pSparseMemoryRequirements);
1159*61046927SAndroid Build Coastguard Worker }
1160*61046927SAndroid Build Coastguard Worker 
1161*61046927SAndroid Build Coastguard Worker void
vn_GetDeviceImageSubresourceLayoutKHR(VkDevice device,const VkDeviceImageSubresourceInfoKHR * pInfo,VkSubresourceLayout2KHR * pLayout)1162*61046927SAndroid Build Coastguard Worker vn_GetDeviceImageSubresourceLayoutKHR(VkDevice device,
1163*61046927SAndroid Build Coastguard Worker                                       const VkDeviceImageSubresourceInfoKHR *pInfo,
1164*61046927SAndroid Build Coastguard Worker                                       VkSubresourceLayout2KHR *pLayout)
1165*61046927SAndroid Build Coastguard Worker {
1166*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    /* TODO per-device cache */
1169*61046927SAndroid Build Coastguard Worker    vn_call_vkGetDeviceImageSubresourceLayoutKHR(
1170*61046927SAndroid Build Coastguard Worker       dev->primary_ring, device, pInfo, pLayout);
1171*61046927SAndroid Build Coastguard Worker }
1172*61046927SAndroid Build Coastguard Worker 
1173*61046927SAndroid Build Coastguard Worker void
vn_GetImageSubresourceLayout2KHR(VkDevice device,VkImage image,const VkImageSubresource2KHR * pSubresource,VkSubresourceLayout2KHR * pLayout)1174*61046927SAndroid Build Coastguard Worker vn_GetImageSubresourceLayout2KHR(VkDevice device,
1175*61046927SAndroid Build Coastguard Worker                                  VkImage image,
1176*61046927SAndroid Build Coastguard Worker                                  const VkImageSubresource2KHR *pSubresource,
1177*61046927SAndroid Build Coastguard Worker                                  VkSubresourceLayout2KHR *pLayout)
1178*61046927SAndroid Build Coastguard Worker {
1179*61046927SAndroid Build Coastguard Worker    struct vn_device *dev = vn_device_from_handle(device);
1180*61046927SAndroid Build Coastguard Worker    struct vn_image *img = vn_image_from_handle(image);
1181*61046927SAndroid Build Coastguard Worker 
1182*61046927SAndroid Build Coastguard Worker    /* override aspect mask for wsi/ahb images with tiling modifier */
1183*61046927SAndroid Build Coastguard Worker    VkImageSubresource2KHR local_subresource;
1184*61046927SAndroid Build Coastguard Worker    if ((img->wsi.is_wsi && img->wsi.tiling_override ==
1185*61046927SAndroid Build Coastguard Worker                               VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ||
1186*61046927SAndroid Build Coastguard Worker        img->deferred_info) {
1187*61046927SAndroid Build Coastguard Worker       VkImageAspectFlags aspect = pSubresource->imageSubresource.aspectMask;
1188*61046927SAndroid Build Coastguard Worker       switch (aspect) {
1189*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_COLOR_BIT:
1190*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_DEPTH_BIT:
1191*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_STENCIL_BIT:
1192*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_0_BIT:
1193*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;
1194*61046927SAndroid Build Coastguard Worker          break;
1195*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_1_BIT:
1196*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT;
1197*61046927SAndroid Build Coastguard Worker          break;
1198*61046927SAndroid Build Coastguard Worker       case VK_IMAGE_ASPECT_PLANE_2_BIT:
1199*61046927SAndroid Build Coastguard Worker          aspect = VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT;
1200*61046927SAndroid Build Coastguard Worker          break;
1201*61046927SAndroid Build Coastguard Worker       default:
1202*61046927SAndroid Build Coastguard Worker          break;
1203*61046927SAndroid Build Coastguard Worker       }
1204*61046927SAndroid Build Coastguard Worker 
1205*61046927SAndroid Build Coastguard Worker       /* only handle supported aspect override */
1206*61046927SAndroid Build Coastguard Worker       if (aspect != pSubresource->imageSubresource.aspectMask) {
1207*61046927SAndroid Build Coastguard Worker          local_subresource = *pSubresource;
1208*61046927SAndroid Build Coastguard Worker          local_subresource.imageSubresource.aspectMask = aspect;
1209*61046927SAndroid Build Coastguard Worker          pSubresource = &local_subresource;
1210*61046927SAndroid Build Coastguard Worker       }
1211*61046927SAndroid Build Coastguard Worker    }
1212*61046927SAndroid Build Coastguard Worker 
1213*61046927SAndroid Build Coastguard Worker    vn_call_vkGetImageSubresourceLayout2KHR(
1214*61046927SAndroid Build Coastguard Worker       dev->primary_ring, device, image, pSubresource, pLayout);
1215*61046927SAndroid Build Coastguard Worker }
1216