1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright (C) 2008 VMware, Inc.
3*61046927SAndroid Build Coastguard Worker * Copyright (C) 2014 Broadcom
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 2018-2019 Alyssa Rosenzweig
5*61046927SAndroid Build Coastguard Worker * Copyright (C) 2019-2020 Collabora, Ltd.
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
15*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
16*61046927SAndroid Build Coastguard Worker * Software.
17*61046927SAndroid Build Coastguard Worker *
18*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24*61046927SAndroid Build Coastguard Worker * SOFTWARE.
25*61046927SAndroid Build Coastguard Worker *
26*61046927SAndroid Build Coastguard Worker */
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #include "pan_texture.h"
29*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
30*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 5
33*61046927SAndroid Build Coastguard Worker /*
34*61046927SAndroid Build Coastguard Worker * Arm Scalable Texture Compression (ASTC) corresponds to just a few formats.
35*61046927SAndroid Build Coastguard Worker * The block dimension is not part of the format. Instead, it is encoded as a
36*61046927SAndroid Build Coastguard Worker * 6-bit tag on the payload pointer. Map the block size for a single dimension.
37*61046927SAndroid Build Coastguard Worker */
38*61046927SAndroid Build Coastguard Worker static inline enum mali_astc_2d_dimension
panfrost_astc_dim_2d(unsigned dim)39*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_2d(unsigned dim)
40*61046927SAndroid Build Coastguard Worker {
41*61046927SAndroid Build Coastguard Worker switch (dim) {
42*61046927SAndroid Build Coastguard Worker case 4:
43*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_4;
44*61046927SAndroid Build Coastguard Worker case 5:
45*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_5;
46*61046927SAndroid Build Coastguard Worker case 6:
47*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_6;
48*61046927SAndroid Build Coastguard Worker case 8:
49*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_8;
50*61046927SAndroid Build Coastguard Worker case 10:
51*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_10;
52*61046927SAndroid Build Coastguard Worker case 12:
53*61046927SAndroid Build Coastguard Worker return MALI_ASTC_2D_DIMENSION_12;
54*61046927SAndroid Build Coastguard Worker default:
55*61046927SAndroid Build Coastguard Worker unreachable("Invalid ASTC dimension");
56*61046927SAndroid Build Coastguard Worker }
57*61046927SAndroid Build Coastguard Worker }
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Worker static inline enum mali_astc_3d_dimension
panfrost_astc_dim_3d(unsigned dim)60*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_3d(unsigned dim)
61*61046927SAndroid Build Coastguard Worker {
62*61046927SAndroid Build Coastguard Worker switch (dim) {
63*61046927SAndroid Build Coastguard Worker case 3:
64*61046927SAndroid Build Coastguard Worker return MALI_ASTC_3D_DIMENSION_3;
65*61046927SAndroid Build Coastguard Worker case 4:
66*61046927SAndroid Build Coastguard Worker return MALI_ASTC_3D_DIMENSION_4;
67*61046927SAndroid Build Coastguard Worker case 5:
68*61046927SAndroid Build Coastguard Worker return MALI_ASTC_3D_DIMENSION_5;
69*61046927SAndroid Build Coastguard Worker case 6:
70*61046927SAndroid Build Coastguard Worker return MALI_ASTC_3D_DIMENSION_6;
71*61046927SAndroid Build Coastguard Worker default:
72*61046927SAndroid Build Coastguard Worker unreachable("Invalid ASTC dimension");
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker #endif
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker /* Texture addresses are tagged with information about compressed formats.
78*61046927SAndroid Build Coastguard Worker * AFBC uses a bit for whether the colorspace transform is enabled (RGB and
79*61046927SAndroid Build Coastguard Worker * RGBA only).
80*61046927SAndroid Build Coastguard Worker * For ASTC, this is a "stretch factor" encoding the block size. */
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker static unsigned
panfrost_compression_tag(const struct util_format_description * desc,enum mali_texture_dimension dim,uint64_t modifier)83*61046927SAndroid Build Coastguard Worker panfrost_compression_tag(const struct util_format_description *desc,
84*61046927SAndroid Build Coastguard Worker enum mali_texture_dimension dim, uint64_t modifier)
85*61046927SAndroid Build Coastguard Worker {
86*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 5 && PAN_ARCH <= 8
87*61046927SAndroid Build Coastguard Worker if (drm_is_afbc(modifier)) {
88*61046927SAndroid Build Coastguard Worker unsigned flags =
89*61046927SAndroid Build Coastguard Worker (modifier & AFBC_FORMAT_MOD_YTR) ? MALI_AFBC_SURFACE_FLAG_YTR : 0;
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
92*61046927SAndroid Build Coastguard Worker /* Prefetch enable */
93*61046927SAndroid Build Coastguard Worker flags |= MALI_AFBC_SURFACE_FLAG_PREFETCH;
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker if (panfrost_afbc_is_wide(modifier))
96*61046927SAndroid Build Coastguard Worker flags |= MALI_AFBC_SURFACE_FLAG_WIDE_BLOCK;
97*61046927SAndroid Build Coastguard Worker #endif
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 7
100*61046927SAndroid Build Coastguard Worker /* Tiled headers */
101*61046927SAndroid Build Coastguard Worker if (modifier & AFBC_FORMAT_MOD_TILED)
102*61046927SAndroid Build Coastguard Worker flags |= MALI_AFBC_SURFACE_FLAG_TILED_HEADER;
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker /* Used to make sure AFBC headers don't point outside the AFBC
105*61046927SAndroid Build Coastguard Worker * body. HW is using the AFBC surface stride to do this check,
106*61046927SAndroid Build Coastguard Worker * which doesn't work for 3D textures because the surface
107*61046927SAndroid Build Coastguard Worker * stride does not cover the body. Only supported on v7+.
108*61046927SAndroid Build Coastguard Worker */
109*61046927SAndroid Build Coastguard Worker if (dim != MALI_TEXTURE_DIMENSION_3D)
110*61046927SAndroid Build Coastguard Worker flags |= MALI_AFBC_SURFACE_FLAG_CHECK_PAYLOAD_RANGE;
111*61046927SAndroid Build Coastguard Worker #endif
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker return flags;
114*61046927SAndroid Build Coastguard Worker } else if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
115*61046927SAndroid Build Coastguard Worker if (desc->block.depth > 1) {
116*61046927SAndroid Build Coastguard Worker return (panfrost_astc_dim_3d(desc->block.depth) << 4) |
117*61046927SAndroid Build Coastguard Worker (panfrost_astc_dim_3d(desc->block.height) << 2) |
118*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_3d(desc->block.width);
119*61046927SAndroid Build Coastguard Worker } else {
120*61046927SAndroid Build Coastguard Worker return (panfrost_astc_dim_2d(desc->block.height) << 3) |
121*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_2d(desc->block.width);
122*61046927SAndroid Build Coastguard Worker }
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker #endif
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker /* Tags are not otherwise used */
127*61046927SAndroid Build Coastguard Worker return 0;
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker /* Following the texture descriptor is a number of descriptors. How many? */
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker static unsigned
panfrost_texture_num_elements(const struct pan_image_view * iview)133*61046927SAndroid Build Coastguard Worker panfrost_texture_num_elements(const struct pan_image_view *iview)
134*61046927SAndroid Build Coastguard Worker {
135*61046927SAndroid Build Coastguard Worker unsigned levels = 1 + iview->last_level - iview->first_level;
136*61046927SAndroid Build Coastguard Worker unsigned layers = 1 + iview->last_layer - iview->first_layer;
137*61046927SAndroid Build Coastguard Worker unsigned nr_samples = pan_image_view_get_nr_samples(iview);
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker return levels * layers * MAX2(nr_samples, 1);
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker /* Conservative estimate of the size of the texture payload a priori.
143*61046927SAndroid Build Coastguard Worker * Average case, size equal to the actual size. Worst case, off by 2x (if
144*61046927SAndroid Build Coastguard Worker * a manual stride is not needed on a linear texture). Returned value
145*61046927SAndroid Build Coastguard Worker * must be greater than or equal to the actual size, so it's safe to use
146*61046927SAndroid Build Coastguard Worker * as an allocation amount */
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker unsigned
GENX(panfrost_estimate_texture_payload_size)149*61046927SAndroid Build Coastguard Worker GENX(panfrost_estimate_texture_payload_size)(const struct pan_image_view *iview)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker size_t element_size;
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
154*61046927SAndroid Build Coastguard Worker element_size = pan_size(PLANE);
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker /* 2-plane and 3-plane YUV use two plane descriptors. */
157*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(iview->format) && iview->planes[1] != NULL)
158*61046927SAndroid Build Coastguard Worker element_size *= 2;
159*61046927SAndroid Build Coastguard Worker #elif PAN_ARCH == 7
160*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(iview->format))
161*61046927SAndroid Build Coastguard Worker element_size = pan_size(MULTIPLANAR_SURFACE);
162*61046927SAndroid Build Coastguard Worker else
163*61046927SAndroid Build Coastguard Worker element_size = pan_size(SURFACE_WITH_STRIDE);
164*61046927SAndroid Build Coastguard Worker #else
165*61046927SAndroid Build Coastguard Worker /* Assume worst case. Overestimates on Midgard, but that's ok. */
166*61046927SAndroid Build Coastguard Worker element_size = pan_size(SURFACE_WITH_STRIDE);
167*61046927SAndroid Build Coastguard Worker #endif
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker unsigned elements = panfrost_texture_num_elements(iview);
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker return element_size * elements;
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker static void
panfrost_get_surface_strides(const struct pan_image_layout * layout,unsigned l,int32_t * row_stride,int32_t * surf_stride)175*61046927SAndroid Build Coastguard Worker panfrost_get_surface_strides(const struct pan_image_layout *layout, unsigned l,
176*61046927SAndroid Build Coastguard Worker int32_t *row_stride, int32_t *surf_stride)
177*61046927SAndroid Build Coastguard Worker {
178*61046927SAndroid Build Coastguard Worker const struct pan_image_slice_layout *slice = &layout->slices[l];
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker if (drm_is_afbc(layout->modifier)) {
181*61046927SAndroid Build Coastguard Worker /* Pre v7 don't have a row stride field. This field is
182*61046927SAndroid Build Coastguard Worker * repurposed as a Y offset which we don't use */
183*61046927SAndroid Build Coastguard Worker *row_stride = PAN_ARCH < 7 ? 0 : slice->row_stride;
184*61046927SAndroid Build Coastguard Worker *surf_stride = slice->afbc.surface_stride;
185*61046927SAndroid Build Coastguard Worker } else {
186*61046927SAndroid Build Coastguard Worker *row_stride = slice->row_stride;
187*61046927SAndroid Build Coastguard Worker *surf_stride = slice->surface_stride;
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker }
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker static mali_ptr
panfrost_get_surface_pointer(const struct pan_image_layout * layout,enum mali_texture_dimension dim,mali_ptr base,unsigned l,unsigned i,unsigned s)192*61046927SAndroid Build Coastguard Worker panfrost_get_surface_pointer(const struct pan_image_layout *layout,
193*61046927SAndroid Build Coastguard Worker enum mali_texture_dimension dim, mali_ptr base,
194*61046927SAndroid Build Coastguard Worker unsigned l, unsigned i, unsigned s)
195*61046927SAndroid Build Coastguard Worker {
196*61046927SAndroid Build Coastguard Worker unsigned offset;
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker if (layout->dim == MALI_TEXTURE_DIMENSION_3D) {
199*61046927SAndroid Build Coastguard Worker assert(!s);
200*61046927SAndroid Build Coastguard Worker offset =
201*61046927SAndroid Build Coastguard Worker layout->slices[l].offset + i * panfrost_get_layer_stride(layout, l);
202*61046927SAndroid Build Coastguard Worker } else {
203*61046927SAndroid Build Coastguard Worker offset = panfrost_texture_offset(layout, l, i, s);
204*61046927SAndroid Build Coastguard Worker }
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker return base + offset;
207*61046927SAndroid Build Coastguard Worker }
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
210*61046927SAndroid Build Coastguard Worker static void
panfrost_emit_surface_with_stride(mali_ptr plane,int32_t row_stride,int32_t surface_stride,void ** payload)211*61046927SAndroid Build Coastguard Worker panfrost_emit_surface_with_stride(mali_ptr plane, int32_t row_stride,
212*61046927SAndroid Build Coastguard Worker int32_t surface_stride, void **payload)
213*61046927SAndroid Build Coastguard Worker {
214*61046927SAndroid Build Coastguard Worker pan_pack(*payload, SURFACE_WITH_STRIDE, cfg) {
215*61046927SAndroid Build Coastguard Worker cfg.pointer = plane;
216*61046927SAndroid Build Coastguard Worker cfg.row_stride = row_stride;
217*61046927SAndroid Build Coastguard Worker cfg.surface_stride = surface_stride;
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker *payload += pan_size(SURFACE_WITH_STRIDE);
220*61046927SAndroid Build Coastguard Worker }
221*61046927SAndroid Build Coastguard Worker #endif
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker #if PAN_ARCH == 7
224*61046927SAndroid Build Coastguard Worker static void
panfrost_emit_multiplanar_surface(mali_ptr planes[MAX_IMAGE_PLANES],int32_t row_strides[MAX_IMAGE_PLANES],void ** payload)225*61046927SAndroid Build Coastguard Worker panfrost_emit_multiplanar_surface(mali_ptr planes[MAX_IMAGE_PLANES],
226*61046927SAndroid Build Coastguard Worker int32_t row_strides[MAX_IMAGE_PLANES],
227*61046927SAndroid Build Coastguard Worker void **payload)
228*61046927SAndroid Build Coastguard Worker {
229*61046927SAndroid Build Coastguard Worker assert(row_strides[2] == 0 || row_strides[1] == row_strides[2]);
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker pan_pack(*payload, MULTIPLANAR_SURFACE, cfg) {
232*61046927SAndroid Build Coastguard Worker cfg.plane_0_pointer = planes[0];
233*61046927SAndroid Build Coastguard Worker cfg.plane_0_row_stride = row_strides[0];
234*61046927SAndroid Build Coastguard Worker cfg.plane_1_2_row_stride = row_strides[1];
235*61046927SAndroid Build Coastguard Worker cfg.plane_1_pointer = planes[1];
236*61046927SAndroid Build Coastguard Worker cfg.plane_2_pointer = planes[2];
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker *payload += pan_size(MULTIPLANAR_SURFACE);
239*61046927SAndroid Build Coastguard Worker }
240*61046927SAndroid Build Coastguard Worker #endif
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
243*61046927SAndroid Build Coastguard Worker
244*61046927SAndroid Build Coastguard Worker /* clang-format off */
245*61046927SAndroid Build Coastguard Worker #define CLUMP_FMT(pipe, mali) [PIPE_FORMAT_ ## pipe] = MALI_CLUMP_FORMAT_ ## mali
246*61046927SAndroid Build Coastguard Worker static enum mali_clump_format special_clump_formats[PIPE_FORMAT_COUNT] = {
247*61046927SAndroid Build Coastguard Worker CLUMP_FMT(X32_S8X24_UINT, X32S8X24),
248*61046927SAndroid Build Coastguard Worker CLUMP_FMT(X24S8_UINT, X24S8),
249*61046927SAndroid Build Coastguard Worker CLUMP_FMT(S8X24_UINT, S8X24),
250*61046927SAndroid Build Coastguard Worker CLUMP_FMT(S8_UINT, S8),
251*61046927SAndroid Build Coastguard Worker CLUMP_FMT(L4A4_UNORM, L4A4),
252*61046927SAndroid Build Coastguard Worker CLUMP_FMT(L8A8_UNORM, L8A8),
253*61046927SAndroid Build Coastguard Worker CLUMP_FMT(L8A8_UINT, L8A8),
254*61046927SAndroid Build Coastguard Worker CLUMP_FMT(L8A8_SINT, L8A8),
255*61046927SAndroid Build Coastguard Worker CLUMP_FMT(A8_UNORM, A8),
256*61046927SAndroid Build Coastguard Worker CLUMP_FMT(A8_UINT, A8),
257*61046927SAndroid Build Coastguard Worker CLUMP_FMT(A8_SINT, A8),
258*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC1_RGB8, ETC2_RGB8),
259*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_RGB8, ETC2_RGB8),
260*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_SRGB8, ETC2_RGB8),
261*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_RGB8A1, ETC2_RGB8A1),
262*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_SRGB8A1, ETC2_RGB8A1),
263*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_RGBA8, ETC2_RGBA8),
264*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_SRGBA8, ETC2_RGBA8),
265*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_R11_UNORM, ETC2_R11_UNORM),
266*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_R11_SNORM, ETC2_R11_SNORM),
267*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_RG11_UNORM, ETC2_RG11_UNORM),
268*61046927SAndroid Build Coastguard Worker CLUMP_FMT(ETC2_RG11_SNORM, ETC2_RG11_SNORM),
269*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT1_RGB, BC1_UNORM),
270*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT1_RGBA, BC1_UNORM),
271*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT1_SRGB, BC1_UNORM),
272*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT1_SRGBA, BC1_UNORM),
273*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT3_RGBA, BC2_UNORM),
274*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT3_SRGBA, BC2_UNORM),
275*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT5_RGBA, BC3_UNORM),
276*61046927SAndroid Build Coastguard Worker CLUMP_FMT(DXT5_SRGBA, BC3_UNORM),
277*61046927SAndroid Build Coastguard Worker CLUMP_FMT(RGTC1_UNORM, BC4_UNORM),
278*61046927SAndroid Build Coastguard Worker CLUMP_FMT(RGTC1_SNORM, BC4_SNORM),
279*61046927SAndroid Build Coastguard Worker CLUMP_FMT(RGTC2_UNORM, BC5_UNORM),
280*61046927SAndroid Build Coastguard Worker CLUMP_FMT(RGTC2_SNORM, BC5_SNORM),
281*61046927SAndroid Build Coastguard Worker CLUMP_FMT(BPTC_RGB_FLOAT, BC6H_SF16),
282*61046927SAndroid Build Coastguard Worker CLUMP_FMT(BPTC_RGB_UFLOAT, BC6H_UF16),
283*61046927SAndroid Build Coastguard Worker CLUMP_FMT(BPTC_RGBA_UNORM, BC7_UNORM),
284*61046927SAndroid Build Coastguard Worker CLUMP_FMT(BPTC_SRGBA, BC7_UNORM),
285*61046927SAndroid Build Coastguard Worker };
286*61046927SAndroid Build Coastguard Worker #undef CLUMP_FMT
287*61046927SAndroid Build Coastguard Worker /* clang-format on */
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker static enum mali_clump_format
panfrost_clump_format(enum pipe_format format)290*61046927SAndroid Build Coastguard Worker panfrost_clump_format(enum pipe_format format)
291*61046927SAndroid Build Coastguard Worker {
292*61046927SAndroid Build Coastguard Worker /* First, try a special clump format. Note that the 0 encoding is for a
293*61046927SAndroid Build Coastguard Worker * raw clump format, which will never be in the special table.
294*61046927SAndroid Build Coastguard Worker */
295*61046927SAndroid Build Coastguard Worker if (special_clump_formats[format])
296*61046927SAndroid Build Coastguard Worker return special_clump_formats[format];
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker /* Else, it's a raw format. Raw formats must not be compressed. */
299*61046927SAndroid Build Coastguard Worker assert(!util_format_is_compressed(format));
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker /* YUV-sampling has special cases */
302*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(format)) {
303*61046927SAndroid Build Coastguard Worker switch (format) {
304*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8G8_R8B8_UNORM:
305*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_G8R8_B8R8_UNORM:
306*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8B8_R8G8_UNORM:
307*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_B8R8_G8R8_UNORM:
308*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_Y8_UV8_422;
309*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8_G8B8_420_UNORM:
310*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8_B8G8_420_UNORM:
311*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8_G8_B8_420_UNORM:
312*61046927SAndroid Build Coastguard Worker case PIPE_FORMAT_R8_B8_G8_420_UNORM:
313*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_Y8_UV8_420;
314*61046927SAndroid Build Coastguard Worker default:
315*61046927SAndroid Build Coastguard Worker unreachable("unhandled clump format");
316*61046927SAndroid Build Coastguard Worker }
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker /* Select the appropriate raw format. */
320*61046927SAndroid Build Coastguard Worker switch (util_format_get_blocksize(format)) {
321*61046927SAndroid Build Coastguard Worker case 1:
322*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW8;
323*61046927SAndroid Build Coastguard Worker case 2:
324*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW16;
325*61046927SAndroid Build Coastguard Worker case 3:
326*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW24;
327*61046927SAndroid Build Coastguard Worker case 4:
328*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW32;
329*61046927SAndroid Build Coastguard Worker case 6:
330*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW48;
331*61046927SAndroid Build Coastguard Worker case 8:
332*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW64;
333*61046927SAndroid Build Coastguard Worker case 12:
334*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW96;
335*61046927SAndroid Build Coastguard Worker case 16:
336*61046927SAndroid Build Coastguard Worker return MALI_CLUMP_FORMAT_RAW128;
337*61046927SAndroid Build Coastguard Worker default:
338*61046927SAndroid Build Coastguard Worker unreachable("Invalid bpp");
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker }
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker static enum mali_afbc_superblock_size
translate_superblock_size(uint64_t modifier)343*61046927SAndroid Build Coastguard Worker translate_superblock_size(uint64_t modifier)
344*61046927SAndroid Build Coastguard Worker {
345*61046927SAndroid Build Coastguard Worker assert(drm_is_afbc(modifier));
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
348*61046927SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
349*61046927SAndroid Build Coastguard Worker return MALI_AFBC_SUPERBLOCK_SIZE_16X16;
350*61046927SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
351*61046927SAndroid Build Coastguard Worker return MALI_AFBC_SUPERBLOCK_SIZE_32X8;
352*61046927SAndroid Build Coastguard Worker case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
353*61046927SAndroid Build Coastguard Worker return MALI_AFBC_SUPERBLOCK_SIZE_64X4;
354*61046927SAndroid Build Coastguard Worker default:
355*61046927SAndroid Build Coastguard Worker unreachable("Invalid superblock size");
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker }
358*61046927SAndroid Build Coastguard Worker
359*61046927SAndroid Build Coastguard Worker static void
panfrost_emit_plane(const struct pan_image_view * iview,int index,const struct pan_image_layout * layout,enum pipe_format format,mali_ptr pointer,unsigned level,int32_t row_stride,int32_t surface_stride,mali_ptr plane2_ptr,void ** payload)360*61046927SAndroid Build Coastguard Worker panfrost_emit_plane(const struct pan_image_view *iview, int index,
361*61046927SAndroid Build Coastguard Worker const struct pan_image_layout *layout,
362*61046927SAndroid Build Coastguard Worker enum pipe_format format, mali_ptr pointer, unsigned level,
363*61046927SAndroid Build Coastguard Worker int32_t row_stride, int32_t surface_stride,
364*61046927SAndroid Build Coastguard Worker mali_ptr plane2_ptr, void **payload)
365*61046927SAndroid Build Coastguard Worker {
366*61046927SAndroid Build Coastguard Worker const struct util_format_description *desc =
367*61046927SAndroid Build Coastguard Worker util_format_description(format);
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker assert(row_stride >= 0 && surface_stride >= 0 && "negative stride");
370*61046927SAndroid Build Coastguard Worker
371*61046927SAndroid Build Coastguard Worker bool afbc = drm_is_afbc(layout->modifier);
372*61046927SAndroid Build Coastguard Worker bool afrc = drm_is_afrc(layout->modifier);
373*61046927SAndroid Build Coastguard Worker // TODO: this isn't technically guaranteed to be YUV, but it is in practice.
374*61046927SAndroid Build Coastguard Worker bool is_3_planar_yuv = desc->layout == UTIL_FORMAT_LAYOUT_PLANAR3;
375*61046927SAndroid Build Coastguard Worker
376*61046927SAndroid Build Coastguard Worker pan_pack(*payload, PLANE, cfg) {
377*61046927SAndroid Build Coastguard Worker cfg.pointer = pointer;
378*61046927SAndroid Build Coastguard Worker cfg.row_stride = row_stride;
379*61046927SAndroid Build Coastguard Worker cfg.size = layout->data_size - layout->slices[level].offset;
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker if (is_3_planar_yuv) {
382*61046927SAndroid Build Coastguard Worker cfg.two_plane_yuv_chroma.secondary_pointer = plane2_ptr;
383*61046927SAndroid Build Coastguard Worker } else if (!panfrost_format_is_yuv(layout->format)) {
384*61046927SAndroid Build Coastguard Worker cfg.slice_stride = layout->nr_samples
385*61046927SAndroid Build Coastguard Worker ? surface_stride
386*61046927SAndroid Build Coastguard Worker : panfrost_get_layer_stride(layout, level);
387*61046927SAndroid Build Coastguard Worker }
388*61046927SAndroid Build Coastguard Worker
389*61046927SAndroid Build Coastguard Worker if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC) {
390*61046927SAndroid Build Coastguard Worker assert(!afbc);
391*61046927SAndroid Build Coastguard Worker assert(!afrc);
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker if (desc->block.depth > 1) {
394*61046927SAndroid Build Coastguard Worker cfg.plane_type = MALI_PLANE_TYPE_ASTC_3D;
395*61046927SAndroid Build Coastguard Worker cfg.astc._3d.block_width = panfrost_astc_dim_3d(desc->block.width);
396*61046927SAndroid Build Coastguard Worker cfg.astc._3d.block_height =
397*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_3d(desc->block.height);
398*61046927SAndroid Build Coastguard Worker cfg.astc._3d.block_depth = panfrost_astc_dim_3d(desc->block.depth);
399*61046927SAndroid Build Coastguard Worker } else {
400*61046927SAndroid Build Coastguard Worker cfg.plane_type = MALI_PLANE_TYPE_ASTC_2D;
401*61046927SAndroid Build Coastguard Worker cfg.astc._2d.block_width = panfrost_astc_dim_2d(desc->block.width);
402*61046927SAndroid Build Coastguard Worker cfg.astc._2d.block_height =
403*61046927SAndroid Build Coastguard Worker panfrost_astc_dim_2d(desc->block.height);
404*61046927SAndroid Build Coastguard Worker }
405*61046927SAndroid Build Coastguard Worker
406*61046927SAndroid Build Coastguard Worker bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker /* Mesa does not advertise _HDR formats yet */
409*61046927SAndroid Build Coastguard Worker cfg.astc.decode_hdr = false;
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker /* sRGB formats decode to RGBA8 sRGB, which is narrow.
412*61046927SAndroid Build Coastguard Worker *
413*61046927SAndroid Build Coastguard Worker * Non-sRGB formats decode to RGBA16F which is wide except if decode
414*61046927SAndroid Build Coastguard Worker * precision is set to GL_RGBA8 for that texture.
415*61046927SAndroid Build Coastguard Worker */
416*61046927SAndroid Build Coastguard Worker cfg.astc.decode_wide = !srgb && !iview->astc.narrow;
417*61046927SAndroid Build Coastguard Worker } else if (afbc) {
418*61046927SAndroid Build Coastguard Worker cfg.plane_type = MALI_PLANE_TYPE_AFBC;
419*61046927SAndroid Build Coastguard Worker cfg.afbc.superblock_size = translate_superblock_size(layout->modifier);
420*61046927SAndroid Build Coastguard Worker cfg.afbc.ytr = (layout->modifier & AFBC_FORMAT_MOD_YTR);
421*61046927SAndroid Build Coastguard Worker cfg.afbc.tiled_header = (layout->modifier & AFBC_FORMAT_MOD_TILED);
422*61046927SAndroid Build Coastguard Worker cfg.afbc.prefetch = true;
423*61046927SAndroid Build Coastguard Worker cfg.afbc.compression_mode = GENX(pan_afbc_compression_mode)(format);
424*61046927SAndroid Build Coastguard Worker cfg.afbc.header_stride = layout->slices[level].afbc.header_size;
425*61046927SAndroid Build Coastguard Worker } else if (afrc) {
426*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 10
427*61046927SAndroid Build Coastguard Worker struct pan_afrc_format_info finfo =
428*61046927SAndroid Build Coastguard Worker panfrost_afrc_get_format_info(format);
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker cfg.plane_type = MALI_PLANE_TYPE_AFRC;
431*61046927SAndroid Build Coastguard Worker cfg.afrc.block_size =
432*61046927SAndroid Build Coastguard Worker GENX(pan_afrc_block_size)(layout->modifier, index);
433*61046927SAndroid Build Coastguard Worker cfg.afrc.format =
434*61046927SAndroid Build Coastguard Worker GENX(pan_afrc_format)(finfo, layout->modifier, index);
435*61046927SAndroid Build Coastguard Worker #endif
436*61046927SAndroid Build Coastguard Worker } else {
437*61046927SAndroid Build Coastguard Worker cfg.plane_type = is_3_planar_yuv ? MALI_PLANE_TYPE_CHROMA_2P
438*61046927SAndroid Build Coastguard Worker : MALI_PLANE_TYPE_GENERIC;
439*61046927SAndroid Build Coastguard Worker cfg.clump_format = panfrost_clump_format(format);
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker if (!afbc && !afrc) {
443*61046927SAndroid Build Coastguard Worker if (layout->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED)
444*61046927SAndroid Build Coastguard Worker cfg.clump_ordering = MALI_CLUMP_ORDERING_TILED_U_INTERLEAVED;
445*61046927SAndroid Build Coastguard Worker else
446*61046927SAndroid Build Coastguard Worker cfg.clump_ordering = MALI_CLUMP_ORDERING_LINEAR;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker *payload += pan_size(PLANE);
450*61046927SAndroid Build Coastguard Worker }
451*61046927SAndroid Build Coastguard Worker #endif
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker static void
panfrost_emit_surface(const struct pan_image_view * iview,unsigned level,unsigned index,unsigned sample,enum pipe_format format,void ** payload)454*61046927SAndroid Build Coastguard Worker panfrost_emit_surface(const struct pan_image_view *iview, unsigned level,
455*61046927SAndroid Build Coastguard Worker unsigned index, unsigned sample,
456*61046927SAndroid Build Coastguard Worker enum pipe_format format, void **payload)
457*61046927SAndroid Build Coastguard Worker {
458*61046927SAndroid Build Coastguard Worker ASSERTED const struct util_format_description *desc =
459*61046927SAndroid Build Coastguard Worker util_format_description(format);
460*61046927SAndroid Build Coastguard Worker
461*61046927SAndroid Build Coastguard Worker const struct pan_image_layout *layouts[MAX_IMAGE_PLANES] = {0};
462*61046927SAndroid Build Coastguard Worker mali_ptr plane_ptrs[MAX_IMAGE_PLANES] = {0};
463*61046927SAndroid Build Coastguard Worker int32_t row_strides[MAX_IMAGE_PLANES] = {0};
464*61046927SAndroid Build Coastguard Worker int32_t surface_strides[MAX_IMAGE_PLANES] = {0};
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MAX_IMAGE_PLANES; i++) {
467*61046927SAndroid Build Coastguard Worker const struct pan_image *base_image = pan_image_view_get_plane(iview, i);
468*61046927SAndroid Build Coastguard Worker
469*61046927SAndroid Build Coastguard Worker if (!base_image) {
470*61046927SAndroid Build Coastguard Worker /* Every texture should have at least one plane. */
471*61046927SAndroid Build Coastguard Worker assert(i > 0);
472*61046927SAndroid Build Coastguard Worker break;
473*61046927SAndroid Build Coastguard Worker }
474*61046927SAndroid Build Coastguard Worker
475*61046927SAndroid Build Coastguard Worker mali_ptr base = base_image->data.base + base_image->data.offset;
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker if (iview->buf.size) {
478*61046927SAndroid Build Coastguard Worker assert(iview->dim == MALI_TEXTURE_DIMENSION_1D);
479*61046927SAndroid Build Coastguard Worker base += iview->buf.offset;
480*61046927SAndroid Build Coastguard Worker }
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker layouts[i] = &pan_image_view_get_plane(iview, i)->layout;
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker /* v4 does not support compression */
485*61046927SAndroid Build Coastguard Worker assert(PAN_ARCH >= 5 || !drm_is_afbc(layouts[i]->modifier));
486*61046927SAndroid Build Coastguard Worker assert(PAN_ARCH >= 5 || desc->layout != UTIL_FORMAT_LAYOUT_ASTC);
487*61046927SAndroid Build Coastguard Worker
488*61046927SAndroid Build Coastguard Worker /* panfrost_compression_tag() wants the dimension of the resource, not the
489*61046927SAndroid Build Coastguard Worker * one of the image view (those might differ).
490*61046927SAndroid Build Coastguard Worker */
491*61046927SAndroid Build Coastguard Worker unsigned tag =
492*61046927SAndroid Build Coastguard Worker panfrost_compression_tag(desc, layouts[i]->dim, layouts[i]->modifier);
493*61046927SAndroid Build Coastguard Worker
494*61046927SAndroid Build Coastguard Worker plane_ptrs[i] = panfrost_get_surface_pointer(
495*61046927SAndroid Build Coastguard Worker layouts[i], iview->dim, base | tag, level, index, sample);
496*61046927SAndroid Build Coastguard Worker panfrost_get_surface_strides(layouts[i], level, &row_strides[i],
497*61046927SAndroid Build Coastguard Worker &surface_strides[i]);
498*61046927SAndroid Build Coastguard Worker }
499*61046927SAndroid Build Coastguard Worker
500*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
501*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(format)) {
502*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MAX_IMAGE_PLANES; i++) {
503*61046927SAndroid Build Coastguard Worker /* 3-plane YUV is submitted using two PLANE descriptors, where the
504*61046927SAndroid Build Coastguard Worker * second one is of type CHROMA_2P */
505*61046927SAndroid Build Coastguard Worker if (i > 1)
506*61046927SAndroid Build Coastguard Worker break;
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker if (plane_ptrs[i] == 0)
509*61046927SAndroid Build Coastguard Worker break;
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker /* 3-plane YUV requires equal stride for both chroma planes */
512*61046927SAndroid Build Coastguard Worker assert(row_strides[2] == 0 || row_strides[1] == row_strides[2]);
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker panfrost_emit_plane(iview, i, layouts[i], format, plane_ptrs[i], level,
515*61046927SAndroid Build Coastguard Worker row_strides[i], surface_strides[i], plane_ptrs[2],
516*61046927SAndroid Build Coastguard Worker payload);
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker } else {
519*61046927SAndroid Build Coastguard Worker panfrost_emit_plane(iview, 0, layouts[0], format, plane_ptrs[0], level,
520*61046927SAndroid Build Coastguard Worker row_strides[0], surface_strides[0], 0, payload);
521*61046927SAndroid Build Coastguard Worker }
522*61046927SAndroid Build Coastguard Worker return;
523*61046927SAndroid Build Coastguard Worker #endif
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
526*61046927SAndroid Build Coastguard Worker #if PAN_ARCH == 7
527*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(format)) {
528*61046927SAndroid Build Coastguard Worker panfrost_emit_multiplanar_surface(plane_ptrs, row_strides, payload);
529*61046927SAndroid Build Coastguard Worker return;
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker #endif
532*61046927SAndroid Build Coastguard Worker panfrost_emit_surface_with_stride(plane_ptrs[0], row_strides[0],
533*61046927SAndroid Build Coastguard Worker surface_strides[0], payload);
534*61046927SAndroid Build Coastguard Worker #endif
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker static void
panfrost_emit_texture_payload(const struct pan_image_view * iview,enum pipe_format format,void * payload)538*61046927SAndroid Build Coastguard Worker panfrost_emit_texture_payload(const struct pan_image_view *iview,
539*61046927SAndroid Build Coastguard Worker enum pipe_format format, void *payload)
540*61046927SAndroid Build Coastguard Worker {
541*61046927SAndroid Build Coastguard Worker unsigned nr_samples =
542*61046927SAndroid Build Coastguard Worker PAN_ARCH <= 7 ? pan_image_view_get_nr_samples(iview) : 1;
543*61046927SAndroid Build Coastguard Worker
544*61046927SAndroid Build Coastguard Worker /* Inject the addresses in, interleaving array indices, mip levels,
545*61046927SAndroid Build Coastguard Worker * cube faces, and strides in that order. On Bifrost and older, each
546*61046927SAndroid Build Coastguard Worker * sample had its own surface descriptor; on Valhall, they are fused
547*61046927SAndroid Build Coastguard Worker * into a single plane descriptor.
548*61046927SAndroid Build Coastguard Worker */
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 7
551*61046927SAndroid Build Coastguard Worker /* V7 and later treats faces as extra layers */
552*61046927SAndroid Build Coastguard Worker for (int layer = iview->first_layer; layer <= iview->last_layer; ++layer) {
553*61046927SAndroid Build Coastguard Worker for (int sample = 0; sample < nr_samples; ++sample) {
554*61046927SAndroid Build Coastguard Worker for (int level = iview->first_level; level <= iview->last_level; ++level) {
555*61046927SAndroid Build Coastguard Worker panfrost_emit_surface(iview, level, layer, sample,
556*61046927SAndroid Build Coastguard Worker format, &payload);
557*61046927SAndroid Build Coastguard Worker }
558*61046927SAndroid Build Coastguard Worker }
559*61046927SAndroid Build Coastguard Worker }
560*61046927SAndroid Build Coastguard Worker #else
561*61046927SAndroid Build Coastguard Worker unsigned first_layer = iview->first_layer, last_layer = iview->last_layer;
562*61046927SAndroid Build Coastguard Worker unsigned face_count = 1;
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
565*61046927SAndroid Build Coastguard Worker first_layer /= 6;
566*61046927SAndroid Build Coastguard Worker last_layer /= 6;
567*61046927SAndroid Build Coastguard Worker face_count = 6;
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker /* V6 and earlier has a different memory-layout */
571*61046927SAndroid Build Coastguard Worker for (int layer = first_layer; layer <= last_layer; ++layer) {
572*61046927SAndroid Build Coastguard Worker for (int level = iview->first_level; level <= iview->last_level; ++level) {
573*61046927SAndroid Build Coastguard Worker /* order of face and sample doesn't matter; we can only have multiple
574*61046927SAndroid Build Coastguard Worker * of one or the other (no support for multisampled cubemaps)
575*61046927SAndroid Build Coastguard Worker */
576*61046927SAndroid Build Coastguard Worker for (int face = 0; face < face_count; ++face) {
577*61046927SAndroid Build Coastguard Worker for (int sample = 0; sample < nr_samples; ++sample) {
578*61046927SAndroid Build Coastguard Worker panfrost_emit_surface(iview, level, (face_count * layer) + face,
579*61046927SAndroid Build Coastguard Worker sample, format, &payload);
580*61046927SAndroid Build Coastguard Worker }
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker #endif
585*61046927SAndroid Build Coastguard Worker }
586*61046927SAndroid Build Coastguard Worker
587*61046927SAndroid Build Coastguard Worker #if PAN_ARCH <= 7
588*61046927SAndroid Build Coastguard Worker /* Map modifiers to mali_texture_layout for packing in a texture descriptor */
589*61046927SAndroid Build Coastguard Worker
590*61046927SAndroid Build Coastguard Worker static enum mali_texture_layout
panfrost_modifier_to_layout(uint64_t modifier)591*61046927SAndroid Build Coastguard Worker panfrost_modifier_to_layout(uint64_t modifier)
592*61046927SAndroid Build Coastguard Worker {
593*61046927SAndroid Build Coastguard Worker if (drm_is_afbc(modifier))
594*61046927SAndroid Build Coastguard Worker return MALI_TEXTURE_LAYOUT_AFBC;
595*61046927SAndroid Build Coastguard Worker else if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED)
596*61046927SAndroid Build Coastguard Worker return MALI_TEXTURE_LAYOUT_TILED;
597*61046927SAndroid Build Coastguard Worker else if (modifier == DRM_FORMAT_MOD_LINEAR)
598*61046927SAndroid Build Coastguard Worker return MALI_TEXTURE_LAYOUT_LINEAR;
599*61046927SAndroid Build Coastguard Worker else
600*61046927SAndroid Build Coastguard Worker unreachable("Invalid modifer");
601*61046927SAndroid Build Coastguard Worker }
602*61046927SAndroid Build Coastguard Worker #endif
603*61046927SAndroid Build Coastguard Worker
604*61046927SAndroid Build Coastguard Worker /*
605*61046927SAndroid Build Coastguard Worker * Generates a texture descriptor. Ideally, descriptors are immutable after the
606*61046927SAndroid Build Coastguard Worker * texture is created, so we can keep these hanging around in GPU memory in a
607*61046927SAndroid Build Coastguard Worker * dedicated BO and not have to worry. In practice there are some minor gotchas
608*61046927SAndroid Build Coastguard Worker * with this (the driver sometimes will change the format of a texture on the
609*61046927SAndroid Build Coastguard Worker * fly for compression) but it's fast enough to just regenerate the descriptor
610*61046927SAndroid Build Coastguard Worker * in those cases, rather than monkeypatching at drawtime. A texture descriptor
611*61046927SAndroid Build Coastguard Worker * consists of a 32-byte header followed by pointers.
612*61046927SAndroid Build Coastguard Worker */
613*61046927SAndroid Build Coastguard Worker void
GENX(panfrost_new_texture)614*61046927SAndroid Build Coastguard Worker GENX(panfrost_new_texture)(const struct pan_image_view *iview, void *out,
615*61046927SAndroid Build Coastguard Worker const struct panfrost_ptr *payload)
616*61046927SAndroid Build Coastguard Worker {
617*61046927SAndroid Build Coastguard Worker const struct pan_image *base_image = pan_image_view_get_plane(iview, 0);
618*61046927SAndroid Build Coastguard Worker const struct pan_image_layout *layout = &base_image->layout;
619*61046927SAndroid Build Coastguard Worker enum pipe_format format = iview->format;
620*61046927SAndroid Build Coastguard Worker const struct util_format_description *desc = util_format_description(format);
621*61046927SAndroid Build Coastguard Worker uint32_t mali_format = GENX(panfrost_format_from_pipe_format)(format)->hw;
622*61046927SAndroid Build Coastguard Worker unsigned char swizzle[4];
623*61046927SAndroid Build Coastguard Worker
624*61046927SAndroid Build Coastguard Worker if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
625*61046927SAndroid Build Coastguard Worker desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
626*61046927SAndroid Build Coastguard Worker mali_format = MALI_PACK_FMT(RGBA8_UNORM, RGBA, L);
627*61046927SAndroid Build Coastguard Worker }
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker if (PAN_ARCH >= 7 && util_format_is_depth_or_stencil(format)) {
630*61046927SAndroid Build Coastguard Worker /* v7+ doesn't have an _RRRR component order, combine the
631*61046927SAndroid Build Coastguard Worker * user swizzle with a .XXXX swizzle to emulate that.
632*61046927SAndroid Build Coastguard Worker */
633*61046927SAndroid Build Coastguard Worker static const unsigned char replicate_x[4] = {
634*61046927SAndroid Build Coastguard Worker PIPE_SWIZZLE_X,
635*61046927SAndroid Build Coastguard Worker PIPE_SWIZZLE_X,
636*61046927SAndroid Build Coastguard Worker PIPE_SWIZZLE_X,
637*61046927SAndroid Build Coastguard Worker PIPE_SWIZZLE_X,
638*61046927SAndroid Build Coastguard Worker };
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker util_format_compose_swizzles(replicate_x, iview->swizzle, swizzle);
641*61046927SAndroid Build Coastguard Worker } else if ((PAN_ARCH == 7 || PAN_ARCH == 10) &&
642*61046927SAndroid Build Coastguard Worker !panfrost_format_is_yuv(format)) {
643*61046927SAndroid Build Coastguard Worker #if PAN_ARCH == 7 || PAN_ARCH >= 10
644*61046927SAndroid Build Coastguard Worker /* v7 (only) restricts component orders when AFBC is in use.
645*61046927SAndroid Build Coastguard Worker * Rather than restrict AFBC, we use an allowed component order
646*61046927SAndroid Build Coastguard Worker * with an invertible swizzle composed.
647*61046927SAndroid Build Coastguard Worker * v10 has the same restriction, but on AFRC formats.
648*61046927SAndroid Build Coastguard Worker */
649*61046927SAndroid Build Coastguard Worker enum mali_rgb_component_order orig = mali_format & BITFIELD_MASK(12);
650*61046927SAndroid Build Coastguard Worker struct pan_decomposed_swizzle decomposed =
651*61046927SAndroid Build Coastguard Worker GENX(pan_decompose_swizzle)(orig);
652*61046927SAndroid Build Coastguard Worker
653*61046927SAndroid Build Coastguard Worker /* Apply the new component order */
654*61046927SAndroid Build Coastguard Worker mali_format = (mali_format & ~orig) | decomposed.pre;
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker /* Compose the new swizzle */
657*61046927SAndroid Build Coastguard Worker util_format_compose_swizzles(decomposed.post, iview->swizzle, swizzle);
658*61046927SAndroid Build Coastguard Worker #endif
659*61046927SAndroid Build Coastguard Worker } else {
660*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(swizzle) == sizeof(iview->swizzle));
661*61046927SAndroid Build Coastguard Worker memcpy(swizzle, iview->swizzle, sizeof(swizzle));
662*61046927SAndroid Build Coastguard Worker }
663*61046927SAndroid Build Coastguard Worker
664*61046927SAndroid Build Coastguard Worker panfrost_emit_texture_payload(iview, format, payload->cpu);
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker unsigned array_size = iview->last_layer - iview->first_layer + 1;
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker /* If this is a cubemap, we expect the number of layers to be a multiple
669*61046927SAndroid Build Coastguard Worker * of 6.
670*61046927SAndroid Build Coastguard Worker */
671*61046927SAndroid Build Coastguard Worker if (iview->dim == MALI_TEXTURE_DIMENSION_CUBE) {
672*61046927SAndroid Build Coastguard Worker assert(array_size % 6 == 0);
673*61046927SAndroid Build Coastguard Worker array_size /= 6;
674*61046927SAndroid Build Coastguard Worker }
675*61046927SAndroid Build Coastguard Worker
676*61046927SAndroid Build Coastguard Worker /* Multiplanar YUV textures require 2 surface descriptors. */
677*61046927SAndroid Build Coastguard Worker if (panfrost_format_is_yuv(iview->format) && PAN_ARCH >= 9 &&
678*61046927SAndroid Build Coastguard Worker pan_image_view_get_plane(iview, 1) != NULL)
679*61046927SAndroid Build Coastguard Worker array_size *= 2;
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker unsigned width, height, depth;
682*61046927SAndroid Build Coastguard Worker
683*61046927SAndroid Build Coastguard Worker if (iview->buf.size) {
684*61046927SAndroid Build Coastguard Worker assert(iview->dim == MALI_TEXTURE_DIMENSION_1D);
685*61046927SAndroid Build Coastguard Worker assert(!iview->first_level && !iview->last_level);
686*61046927SAndroid Build Coastguard Worker assert(!iview->first_layer && !iview->last_layer);
687*61046927SAndroid Build Coastguard Worker assert(layout->nr_samples == 1);
688*61046927SAndroid Build Coastguard Worker assert(layout->height == 1 && layout->depth == 1);
689*61046927SAndroid Build Coastguard Worker assert(iview->buf.offset + iview->buf.size <= layout->width);
690*61046927SAndroid Build Coastguard Worker width = iview->buf.size;
691*61046927SAndroid Build Coastguard Worker height = 1;
692*61046927SAndroid Build Coastguard Worker depth = 1;
693*61046927SAndroid Build Coastguard Worker } else {
694*61046927SAndroid Build Coastguard Worker width = u_minify(layout->width, iview->first_level);
695*61046927SAndroid Build Coastguard Worker height = u_minify(layout->height, iview->first_level);
696*61046927SAndroid Build Coastguard Worker depth = u_minify(layout->depth, iview->first_level);
697*61046927SAndroid Build Coastguard Worker if (util_format_is_compressed(layout->format) &&
698*61046927SAndroid Build Coastguard Worker !util_format_is_compressed(format)) {
699*61046927SAndroid Build Coastguard Worker width =
700*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(width, util_format_get_blockwidth(layout->format));
701*61046927SAndroid Build Coastguard Worker height =
702*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(height, util_format_get_blockheight(layout->format));
703*61046927SAndroid Build Coastguard Worker depth =
704*61046927SAndroid Build Coastguard Worker DIV_ROUND_UP(depth, util_format_get_blockdepth(layout->format));
705*61046927SAndroid Build Coastguard Worker assert(util_format_get_blockwidth(format) == 1);
706*61046927SAndroid Build Coastguard Worker assert(util_format_get_blockheight(format) == 1);
707*61046927SAndroid Build Coastguard Worker assert(util_format_get_blockheight(format) == 1);
708*61046927SAndroid Build Coastguard Worker assert(iview->last_level == iview->first_level);
709*61046927SAndroid Build Coastguard Worker }
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker
712*61046927SAndroid Build Coastguard Worker pan_pack(out, TEXTURE, cfg) {
713*61046927SAndroid Build Coastguard Worker cfg.dimension = iview->dim;
714*61046927SAndroid Build Coastguard Worker cfg.format = mali_format;
715*61046927SAndroid Build Coastguard Worker cfg.width = width;
716*61046927SAndroid Build Coastguard Worker cfg.height = height;
717*61046927SAndroid Build Coastguard Worker if (iview->dim == MALI_TEXTURE_DIMENSION_3D)
718*61046927SAndroid Build Coastguard Worker cfg.depth = depth;
719*61046927SAndroid Build Coastguard Worker else
720*61046927SAndroid Build Coastguard Worker cfg.sample_count = layout->nr_samples;
721*61046927SAndroid Build Coastguard Worker cfg.swizzle = panfrost_translate_swizzle_4(swizzle);
722*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
723*61046927SAndroid Build Coastguard Worker cfg.texel_interleave = (layout->modifier != DRM_FORMAT_MOD_LINEAR) ||
724*61046927SAndroid Build Coastguard Worker util_format_is_compressed(format);
725*61046927SAndroid Build Coastguard Worker #else
726*61046927SAndroid Build Coastguard Worker cfg.texel_ordering = panfrost_modifier_to_layout(layout->modifier);
727*61046927SAndroid Build Coastguard Worker #endif
728*61046927SAndroid Build Coastguard Worker cfg.levels = iview->last_level - iview->first_level + 1;
729*61046927SAndroid Build Coastguard Worker cfg.array_size = array_size;
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 6
732*61046927SAndroid Build Coastguard Worker cfg.surfaces = payload->gpu;
733*61046927SAndroid Build Coastguard Worker
734*61046927SAndroid Build Coastguard Worker /* We specify API-level LOD clamps in the sampler descriptor
735*61046927SAndroid Build Coastguard Worker * and use these clamps simply for bounds checking.
736*61046927SAndroid Build Coastguard Worker */
737*61046927SAndroid Build Coastguard Worker cfg.minimum_lod = 0;
738*61046927SAndroid Build Coastguard Worker cfg.maximum_lod = cfg.levels - 1;
739*61046927SAndroid Build Coastguard Worker #endif
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker }
742*61046927SAndroid Build Coastguard Worker
743*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 9
744*61046927SAndroid Build Coastguard Worker enum mali_afbc_compression_mode
GENX(pan_afbc_compression_mode)745*61046927SAndroid Build Coastguard Worker GENX(pan_afbc_compression_mode)(enum pipe_format format)
746*61046927SAndroid Build Coastguard Worker {
747*61046927SAndroid Build Coastguard Worker /* There's a special case for texturing the stencil part from a combined
748*61046927SAndroid Build Coastguard Worker * depth/stencil texture, handle it separately.
749*61046927SAndroid Build Coastguard Worker */
750*61046927SAndroid Build Coastguard Worker if (format == PIPE_FORMAT_X24S8_UINT)
751*61046927SAndroid Build Coastguard Worker return MALI_AFBC_COMPRESSION_MODE_X24S8;
752*61046927SAndroid Build Coastguard Worker
753*61046927SAndroid Build Coastguard Worker /* Otherwise, map canonical formats to the hardware enum. This only
754*61046927SAndroid Build Coastguard Worker * needs to handle the subset of formats returned by
755*61046927SAndroid Build Coastguard Worker * panfrost_afbc_format.
756*61046927SAndroid Build Coastguard Worker */
757*61046927SAndroid Build Coastguard Worker /* clang-format off */
758*61046927SAndroid Build Coastguard Worker switch (panfrost_afbc_format(PAN_ARCH, format)) {
759*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R8: return MALI_AFBC_COMPRESSION_MODE_R8;
760*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R8G8: return MALI_AFBC_COMPRESSION_MODE_R8G8;
761*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R5G6B5: return MALI_AFBC_COMPRESSION_MODE_R5G6B5;
762*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R4G4B4A4: return MALI_AFBC_COMPRESSION_MODE_R4G4B4A4;
763*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R5G5B5A1: return MALI_AFBC_COMPRESSION_MODE_R5G5B5A1;
764*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R8G8B8: return MALI_AFBC_COMPRESSION_MODE_R8G8B8;
765*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R8G8B8A8: return MALI_AFBC_COMPRESSION_MODE_R8G8B8A8;
766*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R10G10B10A2: return MALI_AFBC_COMPRESSION_MODE_R10G10B10A2;
767*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_R11G11B10: return MALI_AFBC_COMPRESSION_MODE_R11G11B10;
768*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_S8: return MALI_AFBC_COMPRESSION_MODE_S8;
769*61046927SAndroid Build Coastguard Worker case PAN_AFBC_MODE_INVALID: unreachable("Invalid AFBC format");
770*61046927SAndroid Build Coastguard Worker }
771*61046927SAndroid Build Coastguard Worker /* clang-format on */
772*61046927SAndroid Build Coastguard Worker
773*61046927SAndroid Build Coastguard Worker unreachable("all AFBC formats handled");
774*61046927SAndroid Build Coastguard Worker }
775*61046927SAndroid Build Coastguard Worker #endif
776*61046927SAndroid Build Coastguard Worker
777*61046927SAndroid Build Coastguard Worker #if PAN_ARCH >= 10
778*61046927SAndroid Build Coastguard Worker enum mali_afrc_format
GENX(pan_afrc_format)779*61046927SAndroid Build Coastguard Worker GENX(pan_afrc_format)(struct pan_afrc_format_info info, uint64_t modifier,
780*61046927SAndroid Build Coastguard Worker unsigned plane)
781*61046927SAndroid Build Coastguard Worker {
782*61046927SAndroid Build Coastguard Worker bool scan = panfrost_afrc_is_scan(modifier);
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker assert(info.bpc == 8 || info.bpc == 10);
785*61046927SAndroid Build Coastguard Worker assert(info.num_comps > 0 && info.num_comps <= 4);
786*61046927SAndroid Build Coastguard Worker
787*61046927SAndroid Build Coastguard Worker switch (info.ichange_fmt) {
788*61046927SAndroid Build Coastguard Worker case PAN_AFRC_ICHANGE_FORMAT_RAW:
789*61046927SAndroid Build Coastguard Worker assert(plane == 0);
790*61046927SAndroid Build Coastguard Worker
791*61046927SAndroid Build Coastguard Worker if (info.bpc == 8)
792*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8_SCAN : MALI_AFRC_FORMAT_R8_ROT) +
793*61046927SAndroid Build Coastguard Worker (info.num_comps - 1);
794*61046927SAndroid Build Coastguard Worker
795*61046927SAndroid Build Coastguard Worker assert(info.num_comps == 4);
796*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10G10B10A10_SCAN
797*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10G10B10A10_ROT);
798*61046927SAndroid Build Coastguard Worker
799*61046927SAndroid Build Coastguard Worker case PAN_AFRC_ICHANGE_FORMAT_YUV444:
800*61046927SAndroid Build Coastguard Worker if (info.bpc == 8) {
801*61046927SAndroid Build Coastguard Worker if (plane == 0 || info.num_planes == 3)
802*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8_444_SCAN
803*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8_444_ROT);
804*61046927SAndroid Build Coastguard Worker
805*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8G8_444_SCAN
806*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8G8_444_ROT);
807*61046927SAndroid Build Coastguard Worker }
808*61046927SAndroid Build Coastguard Worker
809*61046927SAndroid Build Coastguard Worker assert(info.num_planes == 3);
810*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10_444_SCAN
811*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10_444_ROT);
812*61046927SAndroid Build Coastguard Worker
813*61046927SAndroid Build Coastguard Worker case PAN_AFRC_ICHANGE_FORMAT_YUV422:
814*61046927SAndroid Build Coastguard Worker if (info.bpc == 8) {
815*61046927SAndroid Build Coastguard Worker if (plane == 0 || info.num_planes == 3)
816*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8_422_SCAN
817*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8_422_ROT);
818*61046927SAndroid Build Coastguard Worker
819*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8G8_422_SCAN
820*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8G8_422_ROT);
821*61046927SAndroid Build Coastguard Worker }
822*61046927SAndroid Build Coastguard Worker
823*61046927SAndroid Build Coastguard Worker if (plane == 0 || info.num_planes == 3)
824*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10_422_SCAN
825*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10_422_ROT);
826*61046927SAndroid Build Coastguard Worker
827*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10G10_422_SCAN
828*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10G10_422_ROT);
829*61046927SAndroid Build Coastguard Worker
830*61046927SAndroid Build Coastguard Worker case PAN_AFRC_ICHANGE_FORMAT_YUV420:
831*61046927SAndroid Build Coastguard Worker if (info.bpc == 8) {
832*61046927SAndroid Build Coastguard Worker if (plane == 0 || info.num_planes == 3)
833*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8_420_SCAN
834*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8_420_ROT);
835*61046927SAndroid Build Coastguard Worker
836*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R8G8_420_SCAN
837*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R8G8_420_ROT);
838*61046927SAndroid Build Coastguard Worker }
839*61046927SAndroid Build Coastguard Worker
840*61046927SAndroid Build Coastguard Worker if (plane == 0 || info.num_planes == 3)
841*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10_420_SCAN
842*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10_420_ROT);
843*61046927SAndroid Build Coastguard Worker
844*61046927SAndroid Build Coastguard Worker return (scan ? MALI_AFRC_FORMAT_R10G10_420_SCAN
845*61046927SAndroid Build Coastguard Worker : MALI_AFRC_FORMAT_R10G10_420_ROT);
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker default:
848*61046927SAndroid Build Coastguard Worker return MALI_AFRC_FORMAT_INVALID;
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker }
851*61046927SAndroid Build Coastguard Worker
852*61046927SAndroid Build Coastguard Worker enum mali_afrc_block_size
GENX(pan_afrc_block_size)853*61046927SAndroid Build Coastguard Worker GENX(pan_afrc_block_size)(uint64_t modifier, unsigned index)
854*61046927SAndroid Build Coastguard Worker {
855*61046927SAndroid Build Coastguard Worker /* Clump size flag for planes 1 and 2 is shifted by 4 bits */
856*61046927SAndroid Build Coastguard Worker unsigned shift = index == 0 ? 0 : 4;
857*61046927SAndroid Build Coastguard Worker uint64_t flag = (modifier >> shift) & AFRC_FORMAT_MOD_CU_SIZE_MASK;
858*61046927SAndroid Build Coastguard Worker
859*61046927SAndroid Build Coastguard Worker /* clang-format off */
860*61046927SAndroid Build Coastguard Worker switch (flag) {
861*61046927SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_16: return MALI_AFRC_BLOCK_SIZE_16;
862*61046927SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_24: return MALI_AFRC_BLOCK_SIZE_24;
863*61046927SAndroid Build Coastguard Worker case AFRC_FORMAT_MOD_CU_SIZE_32: return MALI_AFRC_BLOCK_SIZE_32;
864*61046927SAndroid Build Coastguard Worker default: unreachable("invalid code unit size");
865*61046927SAndroid Build Coastguard Worker }
866*61046927SAndroid Build Coastguard Worker /* clang-format on */
867*61046927SAndroid Build Coastguard Worker }
868*61046927SAndroid Build Coastguard Worker #endif
869