• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 MAX_MIP_LEVELS   17
48 #define MAX_IMAGE_PLANES 3
49 
50 #define PAN_MODIFIER_COUNT 14
51 extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
52 
53 struct pan_image_slice_layout {
54    unsigned offset;
55 
56    /* For AFBC images, the number of bytes between two rows of AFBC
57     * headers.
58     *
59     * For non-AFBC images, the number of bytes between two rows of texels.
60     * For linear images, this will equal the logical stride. For
61     * images that are compressed or interleaved, this will be greater than
62     * the logical stride.
63     */
64    unsigned row_stride;
65 
66    unsigned surface_stride;
67 
68    struct {
69       /* Stride in number of superblocks */
70       unsigned stride;
71 
72       /* Number of superblocks */
73       unsigned nr_blocks;
74 
75       /* Size of the AFBC header preceding each slice */
76       unsigned header_size;
77 
78       /* Size of the AFBC body */
79       unsigned body_size;
80 
81       /* Stride between AFBC headers of two consecutive surfaces.
82        * For 3D textures, this must be set to header size since
83        * AFBC headers are allocated together, for 2D arrays this
84        * should be set to size0, since AFBC headers are placed at
85        * the beginning of each layer
86        */
87       unsigned surface_stride;
88    } afbc;
89 
90    /* If checksumming is enabled following the slice, what
91     * is its offset/stride? */
92    struct {
93       unsigned offset;
94       unsigned stride;
95       unsigned size;
96    } crc;
97 
98    unsigned size;
99 };
100 
101 struct pan_image_layout {
102    uint64_t modifier;
103    enum pipe_format format;
104    unsigned width, height, depth;
105    unsigned nr_samples;
106    enum mali_texture_dimension dim;
107    unsigned nr_slices;
108    unsigned array_size;
109    bool crc;
110 
111    /* The remaining fields may be derived from the above by calling
112     * pan_image_layout_init
113     */
114 
115    struct pan_image_slice_layout slices[MAX_MIP_LEVELS];
116 
117    uint64_t data_size;
118    uint64_t array_stride;
119 };
120 
121 struct pan_image_mem {
122    uint64_t base;
123    unsigned offset;
124 };
125 
126 struct pan_image {
127    struct pan_image_mem data;
128    struct pan_image_layout layout;
129 };
130 
131 struct pan_image_view {
132    /* Format, dimension and sample count of the view might differ from
133     * those of the image (2D view of a 3D image surface for instance).
134     */
135    enum pipe_format format;
136    enum mali_texture_dimension dim;
137    unsigned first_level, last_level;
138    unsigned first_layer, last_layer;
139    unsigned char swizzle[4];
140 
141    /* planes 1 and 2 are NULL for single plane formats */
142    const struct pan_image *planes[MAX_IMAGE_PLANES];
143 
144    /* If EXT_multisampled_render_to_texture is used, this may be
145     * greater than image->layout.nr_samples. */
146    unsigned nr_samples;
147 
148    /* Only valid if dim == 1D, needed to implement buffer views */
149    struct {
150       unsigned offset;
151       unsigned size;
152    } buf;
153 
154    struct {
155       unsigned narrow;
156    } astc;
157 };
158 
159 static inline const struct pan_image *
pan_image_view_get_plane(const struct pan_image_view * iview,uint32_t idx)160 pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
161 {
162    if (idx >= ARRAY_SIZE(iview->planes))
163       return NULL;
164 
165    return iview->planes[idx];
166 }
167 
168 static inline unsigned
pan_image_view_get_plane_mask(const struct pan_image_view * iview)169 pan_image_view_get_plane_mask(const struct pan_image_view *iview)
170 {
171    unsigned mask = 0;
172 
173    for (unsigned i = 0; i < ARRAY_SIZE(iview->planes); i++) {
174       if (iview->planes[i])
175          mask |= BITFIELD_BIT(i);
176    }
177 
178    return mask;
179 }
180 
181 static inline unsigned
pan_image_view_get_first_plane_idx(const struct pan_image_view * iview)182 pan_image_view_get_first_plane_idx(const struct pan_image_view *iview)
183 {
184    unsigned mask = pan_image_view_get_plane_mask(iview);
185 
186    assert(mask);
187    return ffs(mask) - 1;
188 }
189 
190 static inline const struct pan_image *
pan_image_view_get_first_plane(const struct pan_image_view * iview)191 pan_image_view_get_first_plane(const struct pan_image_view *iview)
192 {
193    unsigned first_plane_idx = pan_image_view_get_first_plane_idx(iview);
194    return pan_image_view_get_plane(iview, first_plane_idx);
195 }
196 
197 static inline uint32_t
pan_image_view_get_nr_samples(const struct pan_image_view * iview)198 pan_image_view_get_nr_samples(const struct pan_image_view *iview)
199 {
200    const struct pan_image *image = pan_image_view_get_first_plane(iview);
201 
202    if (!image)
203       return 0;
204 
205    return image->layout.nr_samples;
206 }
207 
208 static inline const struct pan_image *
pan_image_view_get_color_plane(const struct pan_image_view * iview)209 pan_image_view_get_color_plane(const struct pan_image_view *iview)
210 {
211    /* We only support rendering to plane 0 */
212    assert(pan_image_view_get_plane(iview, 1) == NULL);
213    return pan_image_view_get_plane(iview, 0);
214 }
215 
216 static inline bool
pan_image_view_has_crc(const struct pan_image_view * iview)217 pan_image_view_has_crc(const struct pan_image_view *iview)
218 {
219    const struct pan_image *image = pan_image_view_get_color_plane(iview);
220 
221    if (!image)
222       return false;
223 
224    return image->layout.crc;
225 }
226 
227 static inline const struct pan_image *
pan_image_view_get_s_plane(const struct pan_image_view * iview)228 pan_image_view_get_s_plane(const struct pan_image_view *iview)
229 {
230    ASSERTED const struct util_format_description *fdesc =
231       util_format_description(iview->format);
232    assert(util_format_has_stencil(fdesc));
233 
234    /* In case of multiplanar depth/stencil, the stencil is always on
235     * plane 1. Combined depth/stencil only has one plane, so depth
236     * will be on plane 0 in either case.
237     */
238    const struct pan_image *plane = iview->planes[1] ?: iview->planes[0];
239 
240    assert(plane);
241    fdesc = util_format_description(plane->layout.format);
242    assert(util_format_has_stencil(fdesc));
243    return plane;
244 }
245 
246 static inline const struct pan_image *
pan_image_view_get_zs_plane(const struct pan_image_view * iview)247 pan_image_view_get_zs_plane(const struct pan_image_view *iview)
248 {
249    assert(util_format_is_depth_or_stencil(iview->format));
250 
251    /* Depth or combined depth-stencil is always on plane 0. */
252    return pan_image_view_get_plane(iview, 0);
253 }
254 
255 unsigned panfrost_compute_checksum_size(struct pan_image_slice_layout *slice,
256                                         unsigned width, unsigned height);
257 
258 /* AFBC format mode. The ordering is intended to match the Valhall hardware enum
259  * ("AFBC Compression Mode"), but this enum is required in software on older
260  * hardware for correct handling of texture views. Defining the enum lets us
261  * unify these code paths.
262  */
263 enum pan_afbc_mode {
264    PAN_AFBC_MODE_R8,
265    PAN_AFBC_MODE_R8G8,
266    PAN_AFBC_MODE_R5G6B5,
267    PAN_AFBC_MODE_R4G4B4A4,
268    PAN_AFBC_MODE_R5G5B5A1,
269    PAN_AFBC_MODE_R8G8B8,
270    PAN_AFBC_MODE_R8G8B8A8,
271    PAN_AFBC_MODE_R10G10B10A2,
272    PAN_AFBC_MODE_R11G11B10,
273    PAN_AFBC_MODE_S8,
274 
275    /* Sentintel signalling a format that cannot be compressed */
276    PAN_AFBC_MODE_INVALID
277 };
278 
279 enum pan_afbc_mode panfrost_afbc_format(unsigned arch, enum pipe_format format);
280 
281 /* A format may be compressed as AFBC if it has an AFBC internal format */
282 
283 static inline bool
panfrost_format_supports_afbc(unsigned arch,enum pipe_format format)284 panfrost_format_supports_afbc(unsigned arch, enum pipe_format format)
285 {
286    return panfrost_afbc_format(arch, format) != PAN_AFBC_MODE_INVALID;
287 }
288 
289 #define AFBC_HEADER_BYTES_PER_TILE 16
290 
291 bool panfrost_afbc_can_ytr(enum pipe_format format);
292 
293 bool panfrost_afbc_can_split(unsigned arch, enum pipe_format format,
294                              uint64_t modifier);
295 
296 bool panfrost_afbc_can_pack(enum pipe_format format);
297 
298 /*
299  * Check if a gen supports AFBC with tiled headers (and hence also solid
300  * colour blocks).
301  */
panfrost_afbc_can_tile(unsigned arch)302 static inline bool panfrost_afbc_can_tile(unsigned arch)
303 {
304    return arch >= 7;
305 }
306 
307 /*
308  * Represents the block size of a single plane. For AFBC, this represents the
309  * superblock size. For u-interleaving, this represents the tile size.
310  */
311 struct pan_block_size {
312    /** Width of block */
313    unsigned width;
314 
315    /** Height of blocks */
316    unsigned height;
317 };
318 
319 struct pan_block_size panfrost_afbc_superblock_size(uint64_t modifier);
320 
321 unsigned panfrost_afbc_superblock_width(uint64_t modifier);
322 
323 unsigned panfrost_afbc_superblock_height(uint64_t modifier);
324 
325 struct pan_block_size panfrost_afbc_renderblock_size(uint64_t modifier);
326 
327 bool panfrost_afbc_is_wide(uint64_t modifier);
328 
329 struct pan_block_size panfrost_afbc_subblock_size(uint64_t modifier);
330 
331 uint32_t pan_afbc_row_stride(uint64_t modifier, uint32_t width);
332 
333 uint32_t pan_afbc_stride_blocks(uint64_t modifier, uint32_t row_stride_bytes);
334 
335 uint32_t pan_slice_align(uint64_t modifier);
336 
337 uint32_t pan_afbc_body_align(unsigned arch, uint64_t modifier);
338 
339 /* AFRC */
340 
341 #define AFRC_CLUMPS_PER_TILE 64
342 
343 enum pan_afrc_rate {
344    PAN_AFRC_RATE_NONE,
345    PAN_AFRC_RATE_1BPC,
346    PAN_AFRC_RATE_2BPC,
347    PAN_AFRC_RATE_3BPC,
348    PAN_AFRC_RATE_4BPC,
349    PAN_AFRC_RATE_5BPC,
350    PAN_AFRC_RATE_6BPC,
351    PAN_AFRC_RATE_7BPC,
352    PAN_AFRC_RATE_8BPC,
353    PAN_AFRC_RATE_9BPC,
354    PAN_AFRC_RATE_10BPC,
355    PAN_AFRC_RATE_11BPC,
356    PAN_AFRC_RATE_12BPC,
357    PAN_AFRC_RATE_DEFAULT = 0xF
358 };
359 
360 enum pan_afrc_interchange_format {
361    PAN_AFRC_ICHANGE_FORMAT_RAW,
362    PAN_AFRC_ICHANGE_FORMAT_YUV444,
363    PAN_AFRC_ICHANGE_FORMAT_YUV422,
364    PAN_AFRC_ICHANGE_FORMAT_YUV420,
365 };
366 
367 struct pan_afrc_format_info {
368    unsigned bpc : 4;
369    unsigned num_comps : 3;
370    unsigned ichange_fmt : 2;
371    unsigned num_planes : 2;
372 };
373 
374 struct pan_afrc_format_info
375 panfrost_afrc_get_format_info(enum pipe_format format);
376 
377 bool panfrost_format_supports_afrc(enum pipe_format format);
378 
379 bool panfrost_afrc_is_scan(uint64_t modifier);
380 
381 struct pan_block_size panfrost_afrc_clump_size(enum pipe_format format,
382                                                bool scan);
383 
384 struct pan_block_size panfrost_afrc_tile_size(enum pipe_format format,
385                                               uint64_t modifier);
386 
387 unsigned panfrost_afrc_block_size_from_modifier(uint64_t modifier);
388 
389 unsigned pan_afrc_row_stride(enum pipe_format format, uint64_t modifier,
390                              uint32_t width);
391 
392 unsigned panfrost_afrc_query_rates(enum pipe_format format, unsigned max,
393                                    uint32_t *rates);
394 
395 unsigned panfrost_afrc_get_modifiers(enum pipe_format format, uint32_t rate,
396                                      unsigned max, uint64_t *modifiers);
397 
398 uint32_t panfrost_afrc_get_rate(enum pipe_format format, uint64_t modifier);
399 
400 struct pan_block_size panfrost_block_size(uint64_t modifier,
401                                           enum pipe_format format);
402 
403 struct pan_block_size panfrost_renderblock_size(uint64_t modifier,
404                                                 enum pipe_format format);
405 
406 #ifdef PAN_ARCH
407 unsigned GENX(panfrost_estimate_texture_payload_size)(
408    const struct pan_image_view *iview);
409 
410 #if PAN_ARCH >= 7
411 void GENX(panfrost_texture_swizzle_replicate_x)(struct pan_image_view *iview);
412 #endif
413 
414 #if PAN_ARCH == 7
415 void GENX(panfrost_texture_afbc_reswizzle)(struct pan_image_view *iview);
416 #endif
417 
418 void GENX(panfrost_new_texture)(const struct pan_image_view *iview,
419                                 struct mali_texture_packed *out,
420                                 const struct panfrost_ptr *payload);
421 #endif
422 
423 unsigned panfrost_get_layer_stride(const struct pan_image_layout *layout,
424                                    unsigned level);
425 
426 unsigned panfrost_texture_offset(const struct pan_image_layout *layout,
427                                  unsigned level, unsigned array_idx,
428                                  unsigned surface_idx);
429 
430 /* DRM modifier helper */
431 
432 #define drm_is_afbc(mod)                                                       \
433    ((mod >> 52) ==                                                             \
434     (DRM_FORMAT_MOD_ARM_TYPE_AFBC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
435 
436 #define drm_is_afrc(mod)                                                       \
437    ((mod >> 52) ==                                                             \
438     (DRM_FORMAT_MOD_ARM_TYPE_AFRC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
439 
440 struct pan_image_explicit_layout {
441    unsigned offset;
442    unsigned row_stride;
443 };
444 
445 bool
446 pan_image_layout_init(unsigned arch, struct pan_image_layout *layout,
447                       const struct pan_image_explicit_layout *explicit_layout);
448 
449 unsigned panfrost_get_legacy_stride(const struct pan_image_layout *layout,
450                                     unsigned level);
451 
452 unsigned panfrost_from_legacy_stride(unsigned legacy_stride,
453                                      enum pipe_format format,
454                                      uint64_t modifier);
455 
456 struct pan_surface {
457    union {
458       uint64_t data;
459       struct {
460          uint64_t header;
461          uint64_t body;
462       } afbc;
463    };
464 };
465 
466 void pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
467                            unsigned layer, unsigned sample,
468                            struct pan_surface *surf);
469 
470 #if PAN_ARCH >= 9
471 enum mali_afbc_compression_mode
472 GENX(pan_afbc_compression_mode)(enum pipe_format format);
473 #endif
474 
475 #if PAN_ARCH >= 10
476 enum mali_afrc_format
477 GENX(pan_afrc_format)(struct pan_afrc_format_info info, uint64_t modifier,
478                       unsigned plane);
479 enum mali_afrc_block_size GENX(pan_afrc_block_size)(uint64_t modifier,
480                                                     unsigned index);
481 #endif
482 
483 #ifdef __cplusplus
484 } /* extern C */
485 #endif
486 
487 #endif
488