• 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_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