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