xref: /aosp_15_r20/external/mesa3d/src/panfrost/lib/pan_texture.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2008 VMware, Inc.
3  * Copyright (C) 2014 Broadcom
4  * Copyright (C) 2018-2019 Alyssa Rosenzweig
5  * Copyright (C) 2019-2020 Collabora, Ltd.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  *
26  */
27 
28 #ifndef __PAN_TEXTURE_H
29 #define __PAN_TEXTURE_H
30 
31 #include "genxml/gen_macros.h"
32 
33 #include <stdbool.h>
34 #include "compiler/shader_enums.h"
35 #include "drm-uapi/drm_fourcc.h"
36 #include "genxml/gen_macros.h"
37 #include "util/format/u_format.h"
38 #include "pan_format.h"
39 #include "pan_pool.h"
40 #include "pan_props.h"
41 #include "pan_util.h"
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 #define PAN_MODIFIER_COUNT 12
48 extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
49 
50 struct pan_image_slice_layout {
51    unsigned offset;
52 
53    /* For AFBC images, the number of bytes between two rows of AFBC
54     * headers.
55     *
56     * For non-AFBC images, the number of bytes between two rows of texels.
57     * For linear images, this will equal the logical stride. For
58     * images that are compressed or interleaved, this will be greater than
59     * the logical stride.
60     */
61    unsigned row_stride;
62 
63    unsigned surface_stride;
64 
65    struct {
66       /* Stride in number of superblocks */
67       unsigned stride;
68 
69       /* Number of superblocks */
70       unsigned nr_blocks;
71 
72       /* Size of the AFBC header preceding each slice */
73       unsigned header_size;
74 
75       /* Size of the AFBC body */
76       unsigned body_size;
77 
78       /* Stride between AFBC headers of two consecutive surfaces.
79        * For 3D textures, this must be set to header size since
80        * AFBC headers are allocated together, for 2D arrays this
81        * should be set to size0, since AFBC headers are placed at
82        * the beginning of each layer
83        */
84       unsigned surface_stride;
85    } afbc;
86 
87    /* If checksumming is enabled following the slice, what
88     * is its offset/stride? */
89    struct {
90       unsigned offset;
91       unsigned stride;
92       unsigned size;
93    } crc;
94 
95    unsigned size;
96 };
97 
98 struct pan_image_layout {
99    uint64_t modifier;
100    enum pipe_format format;
101    unsigned width, height, depth;
102    unsigned nr_samples;
103    enum mali_texture_dimension dim;
104    unsigned nr_slices;
105    unsigned array_size;
106    bool crc;
107 
108    /* The remaining fields may be derived from the above by calling
109     * pan_image_layout_init
110     */
111 
112    struct pan_image_slice_layout slices[MAX_MIP_LEVELS];
113 
114    uint64_t data_size;
115    unsigned array_stride;
116 };
117 
118 struct pan_image_mem {
119    mali_ptr base;
120    unsigned offset;
121 };
122 
123 struct pan_image {
124    struct pan_image_mem data;
125    struct pan_image_layout layout;
126 };
127 
128 struct pan_image_view {
129    /* Format, dimension and sample count of the view might differ from
130     * those of the image (2D view of a 3D image surface for instance).
131     */
132    enum pipe_format format;
133    enum mali_texture_dimension dim;
134    unsigned first_level, last_level;
135    unsigned first_layer, last_layer;
136    unsigned char swizzle[4];
137 
138    /* planes 1 and 2 are NULL for single plane formats */
139    const struct pan_image *planes[MAX_IMAGE_PLANES];
140 
141    /* If EXT_multisampled_render_to_texture is used, this may be
142     * greater than image->layout.nr_samples. */
143    unsigned nr_samples;
144 
145    /* Only valid if dim == 1D, needed to implement buffer views */
146    struct {
147       unsigned offset;
148       unsigned size;
149    } buf;
150 
151    struct {
152       unsigned narrow;
153    } astc;
154 };
155 
156 static inline const struct pan_image *
pan_image_view_get_plane(const struct pan_image_view * iview,uint32_t idx)157 pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
158 {
159    if (idx >= ARRAY_SIZE(iview->planes))
160       return NULL;
161 
162    return iview->planes[idx];
163 }
164 
165 static inline uint32_t
pan_image_view_get_nr_samples(const struct pan_image_view * iview)166 pan_image_view_get_nr_samples(const struct pan_image_view *iview)
167 {
168    /* All planes should have the same nr_samples value, so we
169     * just pick the first plane. */
170    const struct pan_image *image = pan_image_view_get_plane(iview, 0);
171 
172    if (!image)
173       return 0;
174 
175    return image->layout.nr_samples;
176 }
177 
178 static inline const struct pan_image *
pan_image_view_get_rt_image(const struct pan_image_view * iview)179 pan_image_view_get_rt_image(const struct pan_image_view *iview)
180 {
181    /* We only support rendering to plane 0 */
182    assert(pan_image_view_get_plane(iview, 1) == NULL);
183    return pan_image_view_get_plane(iview, 0);
184 }
185 
186 static inline bool
pan_image_view_has_crc(const struct pan_image_view * iview)187 pan_image_view_has_crc(const struct pan_image_view *iview)
188 {
189    const struct pan_image *image = pan_image_view_get_rt_image(iview);
190 
191    if (!image)
192       return false;
193 
194    return image->layout.crc;
195 }
196 
197 static inline const struct pan_image *
pan_image_view_get_zs_image(const struct pan_image_view * iview)198 pan_image_view_get_zs_image(const struct pan_image_view *iview)
199 {
200    /* We split depth/stencil combined formats, and end up with only
201     * singleplanar depth and stencil formats. */
202    assert(util_format_is_depth_or_stencil(iview->format));
203    assert(pan_image_view_get_plane(iview, 1) == NULL);
204    return pan_image_view_get_plane(iview, 0);
205 }
206 
207 unsigned panfrost_compute_checksum_size(struct pan_image_slice_layout *slice,
208                                         unsigned width, unsigned height);
209 
210 /* AFBC format mode. The ordering is intended to match the Valhall hardware enum
211  * ("AFBC Compression Mode"), but this enum is required in software on older
212  * hardware for correct handling of texture views. Defining the enum lets us
213  * unify these code paths.
214  */
215 enum pan_afbc_mode {
216    PAN_AFBC_MODE_R8,
217    PAN_AFBC_MODE_R8G8,
218    PAN_AFBC_MODE_R5G6B5,
219    PAN_AFBC_MODE_R4G4B4A4,
220    PAN_AFBC_MODE_R5G5B5A1,
221    PAN_AFBC_MODE_R8G8B8,
222    PAN_AFBC_MODE_R8G8B8A8,
223    PAN_AFBC_MODE_R10G10B10A2,
224    PAN_AFBC_MODE_R11G11B10,
225    PAN_AFBC_MODE_S8,
226 
227    /* Sentintel signalling a format that cannot be compressed */
228    PAN_AFBC_MODE_INVALID
229 };
230 
231 enum pan_afbc_mode panfrost_afbc_format(unsigned arch, enum pipe_format format);
232 
233 /* A format may be compressed as AFBC if it has an AFBC internal format */
234 
235 static inline bool
panfrost_format_supports_afbc(unsigned arch,enum pipe_format format)236 panfrost_format_supports_afbc(unsigned arch, enum pipe_format format)
237 {
238    return panfrost_afbc_format(arch, format) != PAN_AFBC_MODE_INVALID;
239 }
240 
241 #define AFBC_HEADER_BYTES_PER_TILE 16
242 
243 bool panfrost_afbc_can_ytr(enum pipe_format format);
244 
245 bool panfrost_afbc_can_pack(enum pipe_format format);
246 
247 /*
248  * Check if a gen supports AFBC with tiled headers (and hence also solid
249  * colour blocks).
250  */
panfrost_afbc_can_tile(unsigned arch)251 static inline bool panfrost_afbc_can_tile(unsigned arch)
252 {
253    return arch >= 7;
254 }
255 
256 /*
257  * Represents the block size of a single plane. For AFBC, this represents the
258  * superblock size. For u-interleaving, this represents the tile size.
259  */
260 struct pan_block_size {
261    /** Width of block */
262    unsigned width;
263 
264    /** Height of blocks */
265    unsigned height;
266 };
267 
268 struct pan_block_size panfrost_afbc_superblock_size(uint64_t modifier);
269 
270 unsigned panfrost_afbc_superblock_width(uint64_t modifier);
271 
272 unsigned panfrost_afbc_superblock_height(uint64_t modifier);
273 
274 bool panfrost_afbc_is_wide(uint64_t modifier);
275 
276 struct pan_block_size panfrost_afbc_subblock_size(uint64_t modifier);
277 
278 uint32_t pan_afbc_row_stride(uint64_t modifier, uint32_t width);
279 
280 uint32_t pan_afbc_stride_blocks(uint64_t modifier, uint32_t row_stride_bytes);
281 
282 uint32_t pan_slice_align(uint64_t modifier);
283 
284 uint32_t pan_afbc_body_align(uint64_t modifier);
285 
286 /* AFRC */
287 
288 #define AFRC_CLUMPS_PER_TILE 64
289 
290 enum pan_afrc_rate {
291    PAN_AFRC_RATE_NONE,
292    PAN_AFRC_RATE_1BPC,
293    PAN_AFRC_RATE_2BPC,
294    PAN_AFRC_RATE_3BPC,
295    PAN_AFRC_RATE_4BPC,
296    PAN_AFRC_RATE_5BPC,
297    PAN_AFRC_RATE_6BPC,
298    PAN_AFRC_RATE_7BPC,
299    PAN_AFRC_RATE_8BPC,
300    PAN_AFRC_RATE_9BPC,
301    PAN_AFRC_RATE_10BPC,
302    PAN_AFRC_RATE_11BPC,
303    PAN_AFRC_RATE_12BPC,
304    PAN_AFRC_RATE_DEFAULT = 0xF
305 };
306 
307 enum pan_afrc_interchange_format {
308    PAN_AFRC_ICHANGE_FORMAT_RAW,
309    PAN_AFRC_ICHANGE_FORMAT_YUV444,
310    PAN_AFRC_ICHANGE_FORMAT_YUV422,
311    PAN_AFRC_ICHANGE_FORMAT_YUV420,
312 };
313 
314 struct pan_afrc_format_info {
315    unsigned bpc : 4;
316    unsigned num_comps : 3;
317    unsigned ichange_fmt : 2;
318    unsigned num_planes : 2;
319 };
320 
321 struct pan_afrc_format_info
322 panfrost_afrc_get_format_info(enum pipe_format format);
323 
324 bool panfrost_format_supports_afrc(enum pipe_format format);
325 
326 bool panfrost_afrc_is_scan(uint64_t modifier);
327 
328 struct pan_block_size panfrost_afrc_clump_size(enum pipe_format format,
329                                                bool scan);
330 
331 struct pan_block_size panfrost_afrc_tile_size(enum pipe_format format,
332                                               uint64_t modifier);
333 
334 unsigned panfrost_afrc_block_size_from_modifier(uint64_t modifier);
335 
336 unsigned pan_afrc_row_stride(enum pipe_format format, uint64_t modifier,
337                              uint32_t width);
338 
339 unsigned panfrost_afrc_query_rates(enum pipe_format format, unsigned max,
340                                    uint32_t *rates);
341 
342 unsigned panfrost_afrc_get_modifiers(enum pipe_format format, uint32_t rate,
343                                      unsigned max, uint64_t *modifiers);
344 
345 uint32_t panfrost_afrc_get_rate(enum pipe_format format, uint64_t modifier);
346 
347 struct pan_block_size panfrost_block_size(uint64_t modifier,
348                                           enum pipe_format format);
349 
350 #ifdef PAN_ARCH
351 unsigned GENX(panfrost_estimate_texture_payload_size)(
352    const struct pan_image_view *iview);
353 
354 void GENX(panfrost_new_texture)(const struct pan_image_view *iview, void *out,
355                                 const struct panfrost_ptr *payload);
356 #endif
357 
358 unsigned panfrost_get_layer_stride(const struct pan_image_layout *layout,
359                                    unsigned level);
360 
361 unsigned panfrost_texture_offset(const struct pan_image_layout *layout,
362                                  unsigned level, unsigned array_idx,
363                                  unsigned surface_idx);
364 
365 /* DRM modifier helper */
366 
367 #define drm_is_afbc(mod)                                                       \
368    ((mod >> 52) ==                                                             \
369     (DRM_FORMAT_MOD_ARM_TYPE_AFBC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
370 
371 #define drm_is_afrc(mod)                                                       \
372    ((mod >> 52) ==                                                             \
373     (DRM_FORMAT_MOD_ARM_TYPE_AFRC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
374 
375 struct pan_image_explicit_layout {
376    unsigned offset;
377    unsigned row_stride;
378 };
379 
380 bool
381 pan_image_layout_init(unsigned arch, struct pan_image_layout *layout,
382                       const struct pan_image_explicit_layout *explicit_layout);
383 
384 unsigned panfrost_get_legacy_stride(const struct pan_image_layout *layout,
385                                     unsigned level);
386 
387 unsigned panfrost_from_legacy_stride(unsigned legacy_stride,
388                                      enum pipe_format format,
389                                      uint64_t modifier);
390 
391 struct pan_surface {
392    union {
393       mali_ptr data;
394       struct {
395          mali_ptr header;
396          mali_ptr body;
397       } afbc;
398    };
399 };
400 
401 void pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
402                            unsigned layer, unsigned sample,
403                            struct pan_surface *surf);
404 
405 #if PAN_ARCH >= 9
406 enum mali_afbc_compression_mode
407 GENX(pan_afbc_compression_mode)(enum pipe_format format);
408 #endif
409 
410 #if PAN_ARCH >= 10
411 enum mali_afrc_format
412 GENX(pan_afrc_format)(struct pan_afrc_format_info info, uint64_t modifier,
413                       unsigned plane);
414 enum mali_afrc_block_size GENX(pan_afrc_block_size)(uint64_t modifier,
415                                                     unsigned index);
416 #endif
417 
418 #ifdef __cplusplus
419 } /* extern C */
420 #endif
421 
422 #endif
423