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