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_util.h"
41
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45
46 #define PAN_MODIFIER_COUNT 6
47 extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
48
49 struct pan_image_slice_layout {
50 unsigned offset;
51
52 /* For AFBC images, the number of bytes between two rows of AFBC
53 * headers.
54 *
55 * For non-AFBC images, the number of bytes between two rows of texels.
56 * For linear images, this will equal the logical stride. For
57 * images that are compressed or interleaved, this will be greater than
58 * the logical stride.
59 */
60 unsigned row_stride;
61
62 unsigned surface_stride;
63
64 struct {
65 /* Stride in number of superblocks */
66 unsigned stride;
67
68 /* Number of superblocks */
69 unsigned nr_blocks;
70
71 /* Size of the AFBC header preceding each slice */
72 unsigned header_size;
73
74 /* Size of the AFBC body */
75 unsigned body_size;
76
77 /* Stride between AFBC headers of two consecutive surfaces.
78 * For 3D textures, this must be set to header size since
79 * AFBC headers are allocated together, for 2D arrays this
80 * should be set to size0, since AFBC headers are placed at
81 * the beginning of each layer
82 */
83 unsigned surface_stride;
84 } afbc;
85
86 /* If checksumming is enabled following the slice, what
87 * is its offset/stride? */
88 struct {
89 unsigned offset;
90 unsigned stride;
91 unsigned size;
92 } crc;
93
94 unsigned size;
95 };
96
97 struct pan_image_layout {
98 uint64_t modifier;
99 enum pipe_format format;
100 unsigned width, height, depth;
101 unsigned nr_samples;
102 enum mali_texture_dimension dim;
103 unsigned nr_slices;
104 unsigned array_size;
105 bool crc;
106
107 /* The remaining fields may be derived from the above by calling
108 * pan_image_layout_init
109 */
110
111 struct pan_image_slice_layout slices[MAX_MIP_LEVELS];
112
113 unsigned data_size;
114 unsigned array_stride;
115 };
116
117 struct pan_image_mem {
118 mali_ptr base;
119 unsigned offset;
120 };
121
122 struct pan_image {
123 struct pan_image_mem data;
124 struct pan_image_layout layout;
125 };
126
127 struct pan_image_view {
128 /* Format, dimension and sample count of the view might differ from
129 * those of the image (2D view of a 3D image surface for instance).
130 */
131 enum pipe_format format;
132 enum mali_texture_dimension dim;
133 unsigned first_level, last_level;
134 unsigned first_layer, last_layer;
135 unsigned char swizzle[4];
136
137 /* planes 1 and 2 are NULL for single plane formats */
138 const struct pan_image *planes[MAX_IMAGE_PLANES];
139
140 /* If EXT_multisampled_render_to_texture is used, this may be
141 * greater than image->layout.nr_samples. */
142 unsigned nr_samples;
143
144 /* Only valid if dim == 1D, needed to implement buffer views */
145 struct {
146 unsigned offset;
147 unsigned size;
148 } buf;
149 };
150
151 static inline const struct pan_image *
pan_image_view_get_plane(const struct pan_image_view * iview,uint32_t idx)152 pan_image_view_get_plane(const struct pan_image_view *iview, uint32_t idx)
153 {
154 if (idx >= ARRAY_SIZE(iview->planes))
155 return NULL;
156
157 return iview->planes[idx];
158 }
159
160 static inline uint32_t
pan_image_view_get_nr_samples(const struct pan_image_view * iview)161 pan_image_view_get_nr_samples(const struct pan_image_view *iview)
162 {
163 /* All planes should have the same nr_samples value, so we
164 * just pick the first plane. */
165 const struct pan_image *image = pan_image_view_get_plane(iview, 0);
166
167 if (!image)
168 return 0;
169
170 return image->layout.nr_samples;
171 }
172
173 static inline const struct pan_image *
pan_image_view_get_rt_image(const struct pan_image_view * iview)174 pan_image_view_get_rt_image(const struct pan_image_view *iview)
175 {
176 /* We only support rendering to plane 0 */
177 assert(pan_image_view_get_plane(iview, 1) == NULL);
178 return pan_image_view_get_plane(iview, 0);
179 }
180
181 static inline bool
pan_image_view_has_crc(const struct pan_image_view * iview)182 pan_image_view_has_crc(const struct pan_image_view *iview)
183 {
184 const struct pan_image *image = pan_image_view_get_rt_image(iview);
185
186 if (!image)
187 return false;
188
189 return image->layout.crc;
190 }
191
192 static inline const struct pan_image *
pan_image_view_get_zs_image(const struct pan_image_view * iview)193 pan_image_view_get_zs_image(const struct pan_image_view *iview)
194 {
195 /* We split depth/stencil combined formats, and end up with only
196 * singleplanar depth and stencil formats. */
197 assert(util_format_is_depth_or_stencil(iview->format));
198 assert(pan_image_view_get_plane(iview, 1) == NULL);
199 return pan_image_view_get_plane(iview, 0);
200 }
201
202 unsigned panfrost_compute_checksum_size(struct pan_image_slice_layout *slice,
203 unsigned width, unsigned height);
204
205 /* AFBC format mode. The ordering is intended to match the Valhall hardware enum
206 * ("AFBC Compression Mode"), but this enum is required in software on older
207 * hardware for correct handling of texture views. Defining the enum lets us
208 * unify these code paths.
209 */
210 enum pan_afbc_mode {
211 PAN_AFBC_MODE_R8,
212 PAN_AFBC_MODE_R8G8,
213 PAN_AFBC_MODE_R5G6B5,
214 PAN_AFBC_MODE_R4G4B4A4,
215 PAN_AFBC_MODE_R5G5B5A1,
216 PAN_AFBC_MODE_R8G8B8,
217 PAN_AFBC_MODE_R8G8B8A8,
218 PAN_AFBC_MODE_R10G10B10A2,
219 PAN_AFBC_MODE_R11G11B10,
220 PAN_AFBC_MODE_S8,
221
222 /* Sentintel signalling a format that cannot be compressed */
223 PAN_AFBC_MODE_INVALID
224 };
225
226 enum pan_afbc_mode panfrost_afbc_format(unsigned arch, enum pipe_format format);
227
228 /* A format may be compressed as AFBC if it has an AFBC internal format */
229
230 static inline bool
panfrost_format_supports_afbc(unsigned arch,enum pipe_format format)231 panfrost_format_supports_afbc(unsigned arch, enum pipe_format format)
232 {
233 return panfrost_afbc_format(arch, format) != PAN_AFBC_MODE_INVALID;
234 }
235
236 #define AFBC_HEADER_BYTES_PER_TILE 16
237
238 bool panfrost_afbc_can_ytr(enum pipe_format format);
239
240 bool panfrost_afbc_can_pack(enum pipe_format format);
241
242 /*
243 * Check if a gen supports AFBC with tiled headers (and hence also solid
244 * colour blocks).
245 */
panfrost_afbc_can_tile(unsigned arch)246 static inline bool panfrost_afbc_can_tile(unsigned arch)
247 {
248 return arch >= 7;
249 }
250
251 /*
252 * Represents the block size of a single plane. For AFBC, this represents the
253 * superblock size. For u-interleaving, this represents the tile size.
254 */
255 struct pan_block_size {
256 /** Width of block */
257 unsigned width;
258
259 /** Height of blocks */
260 unsigned height;
261 };
262
263 struct pan_block_size panfrost_afbc_superblock_size(uint64_t modifier);
264
265 unsigned panfrost_afbc_superblock_width(uint64_t modifier);
266
267 unsigned panfrost_afbc_superblock_height(uint64_t modifier);
268
269 bool panfrost_afbc_is_wide(uint64_t modifier);
270
271 struct pan_block_size panfrost_afbc_subblock_size(uint64_t modifier);
272
273 uint32_t pan_afbc_row_stride(uint64_t modifier, uint32_t width);
274
275 uint32_t pan_afbc_stride_blocks(uint64_t modifier, uint32_t row_stride_bytes);
276
277 uint32_t pan_slice_align(uint64_t modifier);
278
279 uint32_t pan_afbc_body_align(uint64_t modifier);
280
281 struct pan_block_size panfrost_block_size(uint64_t modifier,
282 enum pipe_format format);
283
284 #ifdef PAN_ARCH
285 unsigned GENX(panfrost_estimate_texture_payload_size)(
286 const struct pan_image_view *iview);
287
288 void GENX(panfrost_new_texture)(const struct pan_image_view *iview, void *out,
289 const struct panfrost_ptr *payload);
290 #endif
291
292 unsigned panfrost_get_layer_stride(const struct pan_image_layout *layout,
293 unsigned level);
294
295 unsigned panfrost_texture_offset(const struct pan_image_layout *layout,
296 unsigned level, unsigned array_idx,
297 unsigned surface_idx);
298
299 /* DRM modifier helper */
300
301 #define drm_is_afbc(mod) \
302 ((mod >> 52) == \
303 (DRM_FORMAT_MOD_ARM_TYPE_AFBC | (DRM_FORMAT_MOD_VENDOR_ARM << 4)))
304
305 struct pan_image_explicit_layout {
306 unsigned offset;
307 unsigned row_stride;
308 };
309
310 bool
311 pan_image_layout_init(unsigned arch, struct pan_image_layout *layout,
312 const struct pan_image_explicit_layout *explicit_layout);
313
314 unsigned panfrost_get_legacy_stride(const struct pan_image_layout *layout,
315 unsigned level);
316
317 unsigned panfrost_from_legacy_stride(unsigned legacy_stride,
318 enum pipe_format format,
319 uint64_t modifier);
320
321 struct pan_surface {
322 union {
323 mali_ptr data;
324 struct {
325 mali_ptr header;
326 mali_ptr body;
327 } afbc;
328 };
329 };
330
331 void pan_iview_get_surface(const struct pan_image_view *iview, unsigned level,
332 unsigned layer, unsigned sample,
333 struct pan_surface *surf);
334
335 #if PAN_ARCH >= 9
336 enum mali_afbc_compression_mode
337 GENX(pan_afbc_compression_mode)(enum pipe_format format);
338 #endif
339
340 #ifdef __cplusplus
341 } /* extern C */
342 #endif
343
344 #endif
345