xref: /aosp_15_r20/external/mesa3d/src/panfrost/vulkan/panvk_image.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Collabora Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Derived from tu_image.c which is:
5*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
6*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
7*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
8*61046927SAndroid Build Coastguard Worker  *
9*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
10*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
11*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
12*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
14*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
17*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
18*61046927SAndroid Build Coastguard Worker  * Software.
19*61046927SAndroid Build Coastguard Worker  *
20*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
27*61046927SAndroid Build Coastguard Worker  */
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "pan_props.h"
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker #include "panvk_device.h"
32*61046927SAndroid Build Coastguard Worker #include "panvk_device_memory.h"
33*61046927SAndroid Build Coastguard Worker #include "panvk_entrypoints.h"
34*61046927SAndroid Build Coastguard Worker #include "panvk_image.h"
35*61046927SAndroid Build Coastguard Worker #include "panvk_instance.h"
36*61046927SAndroid Build Coastguard Worker #include "panvk_physical_device.h"
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker #include "drm-uapi/drm_fourcc.h"
39*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
40*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
41*61046927SAndroid Build Coastguard Worker #include "util/u_drm.h"
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
44*61046927SAndroid Build Coastguard Worker #include "vk_log.h"
45*61046927SAndroid Build Coastguard Worker #include "vk_object.h"
46*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker #define PANVK_MAX_PLANES 1
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker static bool
panvk_image_can_use_mod(struct panvk_image * image,uint64_t mod)51*61046927SAndroid Build Coastguard Worker panvk_image_can_use_mod(struct panvk_image *image, uint64_t mod)
52*61046927SAndroid Build Coastguard Worker {
53*61046927SAndroid Build Coastguard Worker    struct panvk_physical_device *phys_dev =
54*61046927SAndroid Build Coastguard Worker       to_panvk_physical_device(image->vk.base.device->physical);
55*61046927SAndroid Build Coastguard Worker    unsigned arch = pan_arch(phys_dev->kmod.props.gpu_prod_id);
56*61046927SAndroid Build Coastguard Worker    struct panvk_instance *instance =
57*61046927SAndroid Build Coastguard Worker       to_panvk_instance(image->vk.base.device->physical->instance);
58*61046927SAndroid Build Coastguard Worker    enum pipe_format pfmt = vk_format_to_pipe_format(image->vk.format);
59*61046927SAndroid Build Coastguard Worker    bool forced_linear = (instance->debug_flags & PANVK_DEBUG_LINEAR) ||
60*61046927SAndroid Build Coastguard Worker                         image->vk.tiling == VK_IMAGE_TILING_LINEAR ||
61*61046927SAndroid Build Coastguard Worker                         image->vk.image_type == VK_IMAGE_TYPE_1D;
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker    /* If the image is meant to be linear, don't bother testing the
64*61046927SAndroid Build Coastguard Worker     * other cases. */
65*61046927SAndroid Build Coastguard Worker    if (forced_linear)
66*61046927SAndroid Build Coastguard Worker       return mod == DRM_FORMAT_MOD_LINEAR;
67*61046927SAndroid Build Coastguard Worker 
68*61046927SAndroid Build Coastguard Worker    if (drm_is_afbc(mod)) {
69*61046927SAndroid Build Coastguard Worker       /* Disallow AFBC if either of these is true
70*61046927SAndroid Build Coastguard Worker        * - PANVK_DEBUG does not have the 'afbc' flag set
71*61046927SAndroid Build Coastguard Worker        * - storage image views are requested
72*61046927SAndroid Build Coastguard Worker        * - this is a multisample image
73*61046927SAndroid Build Coastguard Worker        * - the GPU doesn't support AFBC
74*61046927SAndroid Build Coastguard Worker        * - the format is not AFBC-able
75*61046927SAndroid Build Coastguard Worker        * - tiling is set to linear
76*61046927SAndroid Build Coastguard Worker        * - this is a 1D image
77*61046927SAndroid Build Coastguard Worker        * - this is a 3D image on a pre-v7 GPU
78*61046927SAndroid Build Coastguard Worker        */
79*61046927SAndroid Build Coastguard Worker       if (!(instance->debug_flags & PANVK_DEBUG_AFBC) ||
80*61046927SAndroid Build Coastguard Worker           ((image->vk.usage | image->vk.stencil_usage) &
81*61046927SAndroid Build Coastguard Worker            VK_IMAGE_USAGE_STORAGE_BIT) ||
82*61046927SAndroid Build Coastguard Worker           image->vk.samples > 1 ||
83*61046927SAndroid Build Coastguard Worker           !panfrost_query_afbc(&phys_dev->kmod.props) ||
84*61046927SAndroid Build Coastguard Worker           !panfrost_format_supports_afbc(arch, pfmt) ||
85*61046927SAndroid Build Coastguard Worker           image->vk.tiling == VK_IMAGE_TILING_LINEAR ||
86*61046927SAndroid Build Coastguard Worker           image->vk.image_type == VK_IMAGE_TYPE_1D ||
87*61046927SAndroid Build Coastguard Worker           (image->vk.image_type == VK_IMAGE_TYPE_3D && arch < 7))
88*61046927SAndroid Build Coastguard Worker          return false;
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker       const struct util_format_description *fdesc =
91*61046927SAndroid Build Coastguard Worker          util_format_description(pfmt);
92*61046927SAndroid Build Coastguard Worker       bool is_rgb = fdesc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
93*61046927SAndroid Build Coastguard Worker                     fdesc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker       if ((mod & AFBC_FORMAT_MOD_YTR) && (!is_rgb || fdesc->nr_channels >= 3))
96*61046927SAndroid Build Coastguard Worker          return false;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker       /* We assume all other unsupported AFBC modes have been filtered out
99*61046927SAndroid Build Coastguard Worker        * through pan_best_modifiers[]. */
100*61046927SAndroid Build Coastguard Worker       return true;
101*61046927SAndroid Build Coastguard Worker    }
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    if (mod == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
104*61046927SAndroid Build Coastguard Worker       /* If we're dealing with a compressed format that requires non-compressed
105*61046927SAndroid Build Coastguard Worker        * views we can't use U_INTERLEAVED tiling because the tiling is different
106*61046927SAndroid Build Coastguard Worker        * between compressed and non-compressed formats. If we wanted to support
107*61046927SAndroid Build Coastguard Worker        * format re-interpretation we would have to specialize the shaders
108*61046927SAndroid Build Coastguard Worker        * accessing non-compressed image views (coordinate patching for
109*61046927SAndroid Build Coastguard Worker        * sampled/storage image, frag_coord patching for color attachments). Let's
110*61046927SAndroid Build Coastguard Worker        * keep things simple for now and make all compressed images that
111*61046927SAndroid Build Coastguard Worker        * have VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT set linear. */
112*61046927SAndroid Build Coastguard Worker       return !(image->vk.create_flags &
113*61046927SAndroid Build Coastguard Worker                VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT);
114*61046927SAndroid Build Coastguard Worker    }
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    /* If we get there, it must be linear to be supported. */
117*61046927SAndroid Build Coastguard Worker    return mod == DRM_FORMAT_MOD_LINEAR;
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker static void
panvk_image_apply_explicit_mod(struct panvk_image * image,const VkImageDrmFormatModifierExplicitCreateInfoEXT * explicit)121*61046927SAndroid Build Coastguard Worker panvk_image_apply_explicit_mod(
122*61046927SAndroid Build Coastguard Worker    struct panvk_image *image,
123*61046927SAndroid Build Coastguard Worker    const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker    struct panvk_physical_device *phys_dev =
126*61046927SAndroid Build Coastguard Worker       to_panvk_physical_device(image->vk.base.device->physical);
127*61046927SAndroid Build Coastguard Worker    unsigned arch = pan_arch(phys_dev->kmod.props.gpu_prod_id);
128*61046927SAndroid Build Coastguard Worker    uint64_t mod = explicit->drmFormatModifier;
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker    /* TODO: support arrays, 3D, multisample and depth-stencil. */
131*61046927SAndroid Build Coastguard Worker    struct pan_image_explicit_layout plane0_layout = {
132*61046927SAndroid Build Coastguard Worker       .offset = explicit->pPlaneLayouts[0].offset,
133*61046927SAndroid Build Coastguard Worker       .row_stride = explicit->pPlaneLayouts[0].rowPitch,
134*61046927SAndroid Build Coastguard Worker    };
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker    assert(!vk_format_is_depth_or_stencil(image->vk.format));
137*61046927SAndroid Build Coastguard Worker    assert(image->vk.samples == 1);
138*61046927SAndroid Build Coastguard Worker    assert(image->vk.array_layers == 1);
139*61046927SAndroid Build Coastguard Worker    assert(image->vk.image_type != VK_IMAGE_TYPE_3D);
140*61046927SAndroid Build Coastguard Worker    assert(explicit->drmFormatModifierPlaneCount == 1);
141*61046927SAndroid Build Coastguard Worker    assert(panvk_image_can_use_mod(image, mod));
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker    image->pimage.layout.modifier = mod;
144*61046927SAndroid Build Coastguard Worker    pan_image_layout_init(arch, &image->pimage.layout, &plane0_layout);
145*61046927SAndroid Build Coastguard Worker }
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker static void
panvk_image_select_mod_from_list(struct panvk_image * image,const uint64_t * mods,uint32_t mod_count)148*61046927SAndroid Build Coastguard Worker panvk_image_select_mod_from_list(struct panvk_image *image,
149*61046927SAndroid Build Coastguard Worker                                  const uint64_t *mods, uint32_t mod_count)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    struct panvk_physical_device *phys_dev =
152*61046927SAndroid Build Coastguard Worker       to_panvk_physical_device(image->vk.base.device->physical);
153*61046927SAndroid Build Coastguard Worker    unsigned arch = pan_arch(phys_dev->kmod.props.gpu_prod_id);
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < PAN_MODIFIER_COUNT; ++i) {
156*61046927SAndroid Build Coastguard Worker       if (!panvk_image_can_use_mod(image, pan_best_modifiers[i]))
157*61046927SAndroid Build Coastguard Worker          continue;
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker       if (!mod_count ||
160*61046927SAndroid Build Coastguard Worker           drm_find_modifier(pan_best_modifiers[i], mods, mod_count)) {
161*61046927SAndroid Build Coastguard Worker          image->pimage.layout.modifier = pan_best_modifiers[i];
162*61046927SAndroid Build Coastguard Worker          pan_image_layout_init(arch, &image->pimage.layout, NULL);
163*61046927SAndroid Build Coastguard Worker          return;
164*61046927SAndroid Build Coastguard Worker       }
165*61046927SAndroid Build Coastguard Worker    }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker    /* If we reached that point without finding a proper modifier, there's
168*61046927SAndroid Build Coastguard Worker     * a serious issue. */
169*61046927SAndroid Build Coastguard Worker    image->pimage.layout.modifier = DRM_FORMAT_MOD_INVALID;
170*61046927SAndroid Build Coastguard Worker    assert(!"Invalid modifier");
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker static void
panvk_image_select_mod(struct panvk_image * image,const VkImageCreateInfo * pCreateInfo)174*61046927SAndroid Build Coastguard Worker panvk_image_select_mod(struct panvk_image *image,
175*61046927SAndroid Build Coastguard Worker                        const VkImageCreateInfo *pCreateInfo)
176*61046927SAndroid Build Coastguard Worker {
177*61046927SAndroid Build Coastguard Worker    if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
178*61046927SAndroid Build Coastguard Worker       const VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
179*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(pCreateInfo->pNext,
180*61046927SAndroid Build Coastguard Worker                               IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
181*61046927SAndroid Build Coastguard Worker       const VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
182*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(
183*61046927SAndroid Build Coastguard Worker             pCreateInfo->pNext,
184*61046927SAndroid Build Coastguard Worker             IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker       if (explicit_mod)
187*61046927SAndroid Build Coastguard Worker          panvk_image_apply_explicit_mod(image, explicit_mod);
188*61046927SAndroid Build Coastguard Worker       else if (mod_list)
189*61046927SAndroid Build Coastguard Worker          panvk_image_select_mod_from_list(image, mod_list->pDrmFormatModifiers,
190*61046927SAndroid Build Coastguard Worker                                           mod_list->drmFormatModifierCount);
191*61046927SAndroid Build Coastguard Worker       else
192*61046927SAndroid Build Coastguard Worker          assert(!"Missing modifier info");
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker       return;
195*61046927SAndroid Build Coastguard Worker    }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker    panvk_image_select_mod_from_list(image, NULL, 0);
198*61046927SAndroid Build Coastguard Worker }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker static void
panvk_image_pre_mod_select_meta_adjustments(struct panvk_image * image)201*61046927SAndroid Build Coastguard Worker panvk_image_pre_mod_select_meta_adjustments(struct panvk_image *image)
202*61046927SAndroid Build Coastguard Worker {
203*61046927SAndroid Build Coastguard Worker    const VkImageAspectFlags aspects = vk_format_aspects(image->vk.format);
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker    /* We do image blit/resolve with vk_meta, so when an image is flagged as
206*61046927SAndroid Build Coastguard Worker     * being a potential transfer source, we also need to add the sampled usage.
207*61046927SAndroid Build Coastguard Worker     */
208*61046927SAndroid Build Coastguard Worker    if (image->vk.usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
209*61046927SAndroid Build Coastguard Worker       image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
210*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
211*61046927SAndroid Build Coastguard Worker          image->vk.stencil_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
212*61046927SAndroid Build Coastguard Worker    }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker    if (image->vk.usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
215*61046927SAndroid Build Coastguard Worker       /* Similarly, image that can be a transfer destination can be attached
216*61046927SAndroid Build Coastguard Worker        * as a color or depth-stencil attachment by vk_meta. */
217*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
218*61046927SAndroid Build Coastguard Worker          image->vk.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
221*61046927SAndroid Build Coastguard Worker          image->vk.stencil_usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
224*61046927SAndroid Build Coastguard Worker          image->vk.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
225*61046927SAndroid Build Coastguard Worker          image->vk.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
226*61046927SAndroid Build Coastguard Worker       }
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker       /* vk_meta creates 2D array views of 3D images. */
229*61046927SAndroid Build Coastguard Worker       if (image->vk.image_type == VK_IMAGE_TYPE_3D)
230*61046927SAndroid Build Coastguard Worker          image->vk.create_flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
231*61046927SAndroid Build Coastguard Worker    }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker    /* Needed for resolve operations. */
234*61046927SAndroid Build Coastguard Worker    if (image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
235*61046927SAndroid Build Coastguard Worker       image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker    if (image->vk.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
238*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
239*61046927SAndroid Build Coastguard Worker          image->vk.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker       if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
242*61046927SAndroid Build Coastguard Worker          image->vk.stencil_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
243*61046927SAndroid Build Coastguard Worker    }
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    if ((image->vk.usage &
246*61046927SAndroid Build Coastguard Worker         (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)) &&
247*61046927SAndroid Build Coastguard Worker        util_format_is_compressed(image->pimage.layout.format)) {
248*61046927SAndroid Build Coastguard Worker       /* We need to be able to create RGBA views of compressed formats for
249*61046927SAndroid Build Coastguard Worker        * vk_meta copies. */
250*61046927SAndroid Build Coastguard Worker       image->vk.create_flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT |
251*61046927SAndroid Build Coastguard Worker                                 VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT;
252*61046927SAndroid Build Coastguard Worker    }
253*61046927SAndroid Build Coastguard Worker }
254*61046927SAndroid Build Coastguard Worker 
255*61046927SAndroid Build Coastguard Worker static uint64_t
panvk_image_get_total_size(const struct panvk_image * image)256*61046927SAndroid Build Coastguard Worker panvk_image_get_total_size(const struct panvk_image *image)
257*61046927SAndroid Build Coastguard Worker {
258*61046927SAndroid Build Coastguard Worker    assert(util_format_get_num_planes(image->pimage.layout.format) == 1);
259*61046927SAndroid Build Coastguard Worker    return image->pimage.layout.data_size;
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker static enum mali_texture_dimension
panvk_image_type_to_mali_tex_dim(VkImageType type)263*61046927SAndroid Build Coastguard Worker panvk_image_type_to_mali_tex_dim(VkImageType type)
264*61046927SAndroid Build Coastguard Worker {
265*61046927SAndroid Build Coastguard Worker    switch (type) {
266*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_TYPE_1D:
267*61046927SAndroid Build Coastguard Worker       return MALI_TEXTURE_DIMENSION_1D;
268*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_TYPE_2D:
269*61046927SAndroid Build Coastguard Worker       return MALI_TEXTURE_DIMENSION_2D;
270*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_TYPE_3D:
271*61046927SAndroid Build Coastguard Worker       return MALI_TEXTURE_DIMENSION_3D;
272*61046927SAndroid Build Coastguard Worker    default:
273*61046927SAndroid Build Coastguard Worker       unreachable("Invalid image type");
274*61046927SAndroid Build Coastguard Worker    }
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)278*61046927SAndroid Build Coastguard Worker panvk_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
279*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *pAllocator, VkImage *pImage)
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_device, dev, device);
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker    struct panvk_image *image =
284*61046927SAndroid Build Coastguard Worker       vk_image_create(&dev->vk, pCreateInfo, pAllocator, sizeof(*image));
285*61046927SAndroid Build Coastguard Worker    if (!image)
286*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    image->pimage.layout = (struct pan_image_layout){
289*61046927SAndroid Build Coastguard Worker       .format = vk_format_to_pipe_format(image->vk.format),
290*61046927SAndroid Build Coastguard Worker       .dim = panvk_image_type_to_mali_tex_dim(image->vk.image_type),
291*61046927SAndroid Build Coastguard Worker       .width = image->vk.extent.width,
292*61046927SAndroid Build Coastguard Worker       .height = image->vk.extent.height,
293*61046927SAndroid Build Coastguard Worker       .depth = image->vk.extent.depth,
294*61046927SAndroid Build Coastguard Worker       .array_size = image->vk.array_layers,
295*61046927SAndroid Build Coastguard Worker       .nr_samples = image->vk.samples,
296*61046927SAndroid Build Coastguard Worker       .nr_slices = image->vk.mip_levels,
297*61046927SAndroid Build Coastguard Worker    };
298*61046927SAndroid Build Coastguard Worker 
299*61046927SAndroid Build Coastguard Worker    /* Add any create/usage flags that might be needed for meta operations.
300*61046927SAndroid Build Coastguard Worker     * This is run before the modifier selection because some
301*61046927SAndroid Build Coastguard Worker     * usage/create_flags influence the modifier selection logic. */
302*61046927SAndroid Build Coastguard Worker    panvk_image_pre_mod_select_meta_adjustments(image);
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker    /* Now that we've patched the create/usage flags, we can proceed with the
305*61046927SAndroid Build Coastguard Worker     * modifier selection. */
306*61046927SAndroid Build Coastguard Worker    panvk_image_select_mod(image, pCreateInfo);
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker    *pImage = panvk_image_to_handle(image);
309*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
310*61046927SAndroid Build Coastguard Worker }
311*61046927SAndroid Build Coastguard Worker 
312*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
panvk_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)313*61046927SAndroid Build Coastguard Worker panvk_DestroyImage(VkDevice _device, VkImage _image,
314*61046927SAndroid Build Coastguard Worker                    const VkAllocationCallbacks *pAllocator)
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_device, device, _device);
317*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_image, image, _image);
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker    if (!image)
320*61046927SAndroid Build Coastguard Worker       return;
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker    if (image->bo)
323*61046927SAndroid Build Coastguard Worker       pan_kmod_bo_put(image->bo);
324*61046927SAndroid Build Coastguard Worker 
325*61046927SAndroid Build Coastguard Worker    vk_image_destroy(&device->vk, pAllocator, &image->vk);
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker static unsigned
panvk_plane_index(VkFormat format,VkImageAspectFlags aspect_mask)329*61046927SAndroid Build Coastguard Worker panvk_plane_index(VkFormat format, VkImageAspectFlags aspect_mask)
330*61046927SAndroid Build Coastguard Worker {
331*61046927SAndroid Build Coastguard Worker    switch (aspect_mask) {
332*61046927SAndroid Build Coastguard Worker    default:
333*61046927SAndroid Build Coastguard Worker       return 0;
334*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_1_BIT:
335*61046927SAndroid Build Coastguard Worker       return 1;
336*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_PLANE_2_BIT:
337*61046927SAndroid Build Coastguard Worker       return 2;
338*61046927SAndroid Build Coastguard Worker    case VK_IMAGE_ASPECT_STENCIL_BIT:
339*61046927SAndroid Build Coastguard Worker       return format == VK_FORMAT_D32_SFLOAT_S8_UINT;
340*61046927SAndroid Build Coastguard Worker    }
341*61046927SAndroid Build Coastguard Worker }
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
panvk_GetImageSubresourceLayout(VkDevice _device,VkImage _image,const VkImageSubresource * pSubresource,VkSubresourceLayout * pLayout)344*61046927SAndroid Build Coastguard Worker panvk_GetImageSubresourceLayout(VkDevice _device, VkImage _image,
345*61046927SAndroid Build Coastguard Worker                                 const VkImageSubresource *pSubresource,
346*61046927SAndroid Build Coastguard Worker                                 VkSubresourceLayout *pLayout)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_image, image, _image);
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker    unsigned plane =
351*61046927SAndroid Build Coastguard Worker       panvk_plane_index(image->vk.format, pSubresource->aspectMask);
352*61046927SAndroid Build Coastguard Worker    assert(plane < PANVK_MAX_PLANES);
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker    const struct pan_image_slice_layout *slice_layout =
355*61046927SAndroid Build Coastguard Worker       &image->pimage.layout.slices[pSubresource->mipLevel];
356*61046927SAndroid Build Coastguard Worker 
357*61046927SAndroid Build Coastguard Worker    pLayout->offset = slice_layout->offset + (pSubresource->arrayLayer *
358*61046927SAndroid Build Coastguard Worker                                              image->pimage.layout.array_stride);
359*61046927SAndroid Build Coastguard Worker    pLayout->size = slice_layout->size;
360*61046927SAndroid Build Coastguard Worker    pLayout->rowPitch = slice_layout->row_stride;
361*61046927SAndroid Build Coastguard Worker    pLayout->arrayPitch = image->pimage.layout.array_stride;
362*61046927SAndroid Build Coastguard Worker    pLayout->depthPitch = slice_layout->surface_stride;
363*61046927SAndroid Build Coastguard Worker }
364*61046927SAndroid Build Coastguard Worker 
365*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
panvk_GetImageMemoryRequirements2(VkDevice device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)366*61046927SAndroid Build Coastguard Worker panvk_GetImageMemoryRequirements2(VkDevice device,
367*61046927SAndroid Build Coastguard Worker                                   const VkImageMemoryRequirementsInfo2 *pInfo,
368*61046927SAndroid Build Coastguard Worker                                   VkMemoryRequirements2 *pMemoryRequirements)
369*61046927SAndroid Build Coastguard Worker {
370*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_image, image, pInfo->image);
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    const uint64_t alignment = 4096;
373*61046927SAndroid Build Coastguard Worker    const uint64_t size = panvk_image_get_total_size(image);
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.memoryTypeBits = 1;
376*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.alignment = alignment;
377*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.size = size;
378*61046927SAndroid Build Coastguard Worker }
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
panvk_GetImageSparseMemoryRequirements2(VkDevice device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)381*61046927SAndroid Build Coastguard Worker panvk_GetImageSparseMemoryRequirements2(
382*61046927SAndroid Build Coastguard Worker    VkDevice device, const VkImageSparseMemoryRequirementsInfo2 *pInfo,
383*61046927SAndroid Build Coastguard Worker    uint32_t *pSparseMemoryRequirementCount,
384*61046927SAndroid Build Coastguard Worker    VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
385*61046927SAndroid Build Coastguard Worker {
386*61046927SAndroid Build Coastguard Worker    panvk_stub();
387*61046927SAndroid Build Coastguard Worker }
388*61046927SAndroid Build Coastguard Worker 
389*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_BindImageMemory2(VkDevice device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)390*61046927SAndroid Build Coastguard Worker panvk_BindImageMemory2(VkDevice device, uint32_t bindInfoCount,
391*61046927SAndroid Build Coastguard Worker                        const VkBindImageMemoryInfo *pBindInfos)
392*61046927SAndroid Build Coastguard Worker {
393*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < bindInfoCount; ++i) {
394*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(panvk_image, image, pBindInfos[i].image);
395*61046927SAndroid Build Coastguard Worker       VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory);
396*61046927SAndroid Build Coastguard Worker       struct pan_kmod_bo *old_bo = image->bo;
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker       assert(mem);
399*61046927SAndroid Build Coastguard Worker       image->bo = pan_kmod_bo_get(mem->bo);
400*61046927SAndroid Build Coastguard Worker       image->pimage.data.base = mem->addr.dev;
401*61046927SAndroid Build Coastguard Worker       image->pimage.data.offset = pBindInfos[i].memoryOffset;
402*61046927SAndroid Build Coastguard Worker       /* Reset the AFBC headers */
403*61046927SAndroid Build Coastguard Worker       if (drm_is_afbc(image->pimage.layout.modifier)) {
404*61046927SAndroid Build Coastguard Worker          /* Transient CPU mapping */
405*61046927SAndroid Build Coastguard Worker          void *base = pan_kmod_bo_mmap(mem->bo, 0, pan_kmod_bo_size(mem->bo),
406*61046927SAndroid Build Coastguard Worker                                        PROT_WRITE, MAP_SHARED, NULL);
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker          assert(base != MAP_FAILED);
409*61046927SAndroid Build Coastguard Worker 
410*61046927SAndroid Build Coastguard Worker          for (unsigned layer = 0; layer < image->pimage.layout.array_size;
411*61046927SAndroid Build Coastguard Worker               layer++) {
412*61046927SAndroid Build Coastguard Worker             for (unsigned level = 0; level < image->pimage.layout.nr_slices;
413*61046927SAndroid Build Coastguard Worker                  level++) {
414*61046927SAndroid Build Coastguard Worker                void *header = base + image->pimage.data.offset +
415*61046927SAndroid Build Coastguard Worker                               (layer * image->pimage.layout.array_stride) +
416*61046927SAndroid Build Coastguard Worker                               image->pimage.layout.slices[level].offset;
417*61046927SAndroid Build Coastguard Worker                memset(header, 0,
418*61046927SAndroid Build Coastguard Worker                       image->pimage.layout.slices[level].afbc.header_size);
419*61046927SAndroid Build Coastguard Worker             }
420*61046927SAndroid Build Coastguard Worker          }
421*61046927SAndroid Build Coastguard Worker 
422*61046927SAndroid Build Coastguard Worker          ASSERTED int ret = os_munmap(base, pan_kmod_bo_size(mem->bo));
423*61046927SAndroid Build Coastguard Worker          assert(!ret);
424*61046927SAndroid Build Coastguard Worker       }
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker       pan_kmod_bo_put(old_bo);
427*61046927SAndroid Build Coastguard Worker    }
428*61046927SAndroid Build Coastguard Worker 
429*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
430*61046927SAndroid Build Coastguard Worker }
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
panvk_GetImageDrmFormatModifierPropertiesEXT(VkDevice device,VkImage _image,VkImageDrmFormatModifierPropertiesEXT * pProperties)433*61046927SAndroid Build Coastguard Worker panvk_GetImageDrmFormatModifierPropertiesEXT(
434*61046927SAndroid Build Coastguard Worker    VkDevice device, VkImage _image,
435*61046927SAndroid Build Coastguard Worker    VkImageDrmFormatModifierPropertiesEXT *pProperties)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(panvk_image, image, _image);
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker    assert(pProperties->sType ==
440*61046927SAndroid Build Coastguard Worker           VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker    pProperties->drmFormatModifier = image->pimage.layout.modifier;
443*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
444*61046927SAndroid Build Coastguard Worker }
445