blob: c65c60bf7e44af1e006136dd697d207dd89d7580 [file] [log] [blame]
Alyssa Rosenzweig5ddf7ad2020-02-18 12:07:47 -05001/*
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#include "util/macros.h"
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -050029#include "util/u_math.h"
Alyssa Rosenzweig5ddf7ad2020-02-18 12:07:47 -050030#include "pan_texture.h"
Boris Brezillonfefb3e92020-09-23 11:08:02 +020031#include "panfrost-quirks.h"
Alyssa Rosenzweig5ddf7ad2020-02-18 12:07:47 -050032
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -050033/* Generates a texture descriptor. Ideally, descriptors are immutable after the
34 * texture is created, so we can keep these hanging around in GPU memory in a
35 * dedicated BO and not have to worry. In practice there are some minor gotchas
36 * with this (the driver sometimes will change the format of a texture on the
37 * fly for compression) but it's fast enough to just regenerate the descriptor
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -040038 * in those cases, rather than monkeypatching at drawtime. A texture descriptor
39 * consists of a 32-byte header followed by pointers.
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -050040 */
41
Alyssa Rosenzweig348d3742020-07-20 18:03:56 -040042/* List of supported modifiers, in descending order of preference. AFBC is
43 * faster than u-interleaved tiling which is faster than linear. Within AFBC,
44 * enabling the YUV-like transform is typically a win where possible. */
45
46uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT] = {
47 DRM_FORMAT_MOD_ARM_AFBC(
48 AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
49 AFBC_FORMAT_MOD_SPARSE |
50 AFBC_FORMAT_MOD_YTR),
51
52 DRM_FORMAT_MOD_ARM_AFBC(
53 AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
54 AFBC_FORMAT_MOD_SPARSE),
55
56 DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
57 DRM_FORMAT_MOD_LINEAR
58};
59
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -040060/* Map modifiers to mali_texture_layout for packing in a texture descriptor */
61
62static enum mali_texture_layout
63panfrost_modifier_to_layout(uint64_t modifier)
64{
65 if (drm_is_afbc(modifier))
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -040066 return MALI_TEXTURE_LAYOUT_AFBC;
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -040067 else if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED)
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -040068 return MALI_TEXTURE_LAYOUT_TILED;
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -040069 else if (modifier == DRM_FORMAT_MOD_LINEAR)
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -040070 return MALI_TEXTURE_LAYOUT_LINEAR;
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -040071 else
72 unreachable("Invalid modifer");
73}
74
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -050075/* Check if we need to set a custom stride by computing the "expected"
76 * stride and comparing it to what the user actually wants. Only applies
77 * to linear textures, since tiled/compressed textures have strict
78 * alignment requirements for their strides as it is */
79
80static bool
81panfrost_needs_explicit_stride(
82 struct panfrost_slice *slices,
83 uint16_t width,
84 unsigned first_level, unsigned last_level,
85 unsigned bytes_per_pixel)
86{
87 for (unsigned l = first_level; l <= last_level; ++l) {
88 unsigned actual = slices[l].stride;
89 unsigned expected = u_minify(width, l) * bytes_per_pixel;
90
91 if (actual != expected)
92 return true;
93 }
94
95 return false;
96}
97
98/* A Scalable Texture Compression (ASTC) corresponds to just a few texture type
99 * in the hardware, but in fact can be parametrized to have various widths and
100 * heights for the so-called "stretch factor". It turns out these parameters
101 * are stuffed in the bottom bits of the payload pointers. This functions
102 * computes these magic stuffing constants based on the ASTC format in use. The
103 * constant in a given dimension is 3-bits, and two are stored side-by-side for
104 * each active dimension.
105 */
106
107static unsigned
108panfrost_astc_stretch(unsigned dim)
109{
110 assert(dim >= 4 && dim <= 12);
111 return MIN2(dim, 11) - 4;
112}
113
Icecream9599446c92020-06-02 14:14:12 +1200114/* Texture addresses are tagged with information about compressed formats.
115 * AFBC uses a bit for whether the colorspace transform is enabled (RGB and
116 * RGBA only).
117 * For ASTC, this is a "stretch factor" encoding the block size. */
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500118
119static unsigned
120panfrost_compression_tag(
121 const struct util_format_description *desc,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400122 enum mali_format format, uint64_t modifier)
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500123{
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400124 if (drm_is_afbc(modifier))
125 return (modifier & AFBC_FORMAT_MOD_YTR) ? 1 : 0;
Alyssa Rosenzweigd5a9cd12020-07-10 10:17:44 -0400126 else if (format == MALI_ASTC_2D_LDR || format == MALI_ASTC_2D_HDR)
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500127 return (panfrost_astc_stretch(desc->block.height) << 3) |
128 panfrost_astc_stretch(desc->block.width);
129 else
130 return 0;
131}
132
133
134/* Cubemaps have 6 faces as "layers" in between each actual layer. We
135 * need to fix this up. TODO: logic wrong in the asserted out cases ...
136 * can they happen, perhaps from cubemap arrays? */
137
138static void
139panfrost_adjust_cube_dimensions(
140 unsigned *first_face, unsigned *last_face,
141 unsigned *first_layer, unsigned *last_layer)
142{
143 *first_face = *first_layer % 6;
144 *last_face = *last_layer % 6;
145 *first_layer /= 6;
146 *last_layer /= 6;
147
148 assert((*first_layer == *last_layer) || (*first_face == 0 && *last_face == 5));
149}
150
151/* Following the texture descriptor is a number of pointers. How many? */
152
153static unsigned
154panfrost_texture_num_elements(
155 unsigned first_level, unsigned last_level,
156 unsigned first_layer, unsigned last_layer,
Alyssa Rosenzweig60888912020-07-15 11:39:08 -0400157 unsigned nr_samples,
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500158 bool is_cube, bool manual_stride)
159{
160 unsigned first_face = 0, last_face = 0;
161
162 if (is_cube) {
163 panfrost_adjust_cube_dimensions(&first_face, &last_face,
164 &first_layer, &last_layer);
165 }
166
167 unsigned levels = 1 + last_level - first_level;
168 unsigned layers = 1 + last_layer - first_layer;
169 unsigned faces = 1 + last_face - first_face;
Alyssa Rosenzweig60888912020-07-15 11:39:08 -0400170 unsigned num_elements = levels * layers * faces * MAX2(nr_samples, 1);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500171
172 if (manual_stride)
173 num_elements *= 2;
174
175 return num_elements;
176}
177
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400178/* Conservative estimate of the size of the texture payload a priori.
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500179 * Average case, size equal to the actual size. Worst case, off by 2x (if
180 * a manual stride is not needed on a linear texture). Returned value
181 * must be greater than or equal to the actual size, so it's safe to use
182 * as an allocation amount */
183
184unsigned
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400185panfrost_estimate_texture_payload_size(
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500186 unsigned first_level, unsigned last_level,
187 unsigned first_layer, unsigned last_layer,
Alyssa Rosenzweig60888912020-07-15 11:39:08 -0400188 unsigned nr_samples,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400189 enum mali_texture_dimension dim, uint64_t modifier)
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500190{
191 /* Assume worst case */
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400192 unsigned manual_stride = (modifier == DRM_FORMAT_MOD_LINEAR);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500193
194 unsigned elements = panfrost_texture_num_elements(
195 first_level, last_level,
196 first_layer, last_layer,
Alyssa Rosenzweig60888912020-07-15 11:39:08 -0400197 nr_samples,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400198 dim == MALI_TEXTURE_DIMENSION_CUBE, manual_stride);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500199
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400200 return sizeof(mali_ptr) * elements;
201}
202
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400203/* Bifrost requires a tile stride for tiled textures. This stride is computed
204 * as (16 * bpp * width) assuming there is at least one tile (width >= 16).
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400205 * Otherwise if height <= 16, the blob puts zero. Interactions with AFBC are
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400206 * currently unknown.
207 */
208
209static unsigned
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400210panfrost_nonlinear_stride(uint64_t modifier,
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400211 unsigned bytes_per_pixel,
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400212 unsigned width,
213 unsigned height)
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400214{
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400215 if (modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400216 return (height <= 16) ? 0 : (16 * bytes_per_pixel * ALIGN_POT(width, 16));
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400217 } else {
218 unreachable("TODO: AFBC on Bifrost");
219 }
220}
221
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400222static void
223panfrost_emit_texture_payload(
224 mali_ptr *payload,
225 const struct util_format_description *desc,
226 enum mali_format mali_format,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400227 enum mali_texture_dimension dim,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400228 uint64_t modifier,
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400229 unsigned width, unsigned height,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400230 unsigned first_level, unsigned last_level,
231 unsigned first_layer, unsigned last_layer,
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400232 unsigned nr_samples,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400233 unsigned cube_stride,
234 bool manual_stride,
235 mali_ptr base,
236 struct panfrost_slice *slices)
237{
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400238 base |= panfrost_compression_tag(desc, mali_format, modifier);
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400239
240 /* Inject the addresses in, interleaving array indices, mip levels,
241 * cube faces, and strides in that order */
242
243 unsigned first_face = 0, last_face = 0, face_mult = 1;
244
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400245 if (dim == MALI_TEXTURE_DIMENSION_CUBE) {
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400246 face_mult = 6;
247 panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer);
248 }
249
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400250 nr_samples = MAX2(nr_samples, 1);
251
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400252 unsigned idx = 0;
253
254 for (unsigned w = first_layer; w <= last_layer; ++w) {
255 for (unsigned l = first_level; l <= last_level; ++l) {
256 for (unsigned f = first_face; f <= last_face; ++f) {
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400257 for (unsigned s = 0; s < nr_samples; ++s) {
258 payload[idx++] = base + panfrost_texture_offset(
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400259 slices, dim == MALI_TEXTURE_DIMENSION_3D,
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400260 cube_stride, l, w * face_mult + f, s);
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400261
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400262 if (manual_stride) {
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400263 payload[idx++] = (modifier == DRM_FORMAT_MOD_LINEAR) ?
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400264 slices[l].stride :
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400265 panfrost_nonlinear_stride(modifier,
Alyssa Rosenzweig937d3682020-06-30 16:43:47 -0400266 MAX2(desc->block.bits / 8, 1),
267 u_minify(width, l),
268 u_minify(height, l));
269 }
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400270 }
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400271 }
272 }
273 }
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500274}
275
Alyssa Rosenzweig816af262020-07-08 16:37:00 -0400276#define MALI_SWIZZLE_R001 \
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400277 (MALI_CHANNEL_R << 0) | \
278 (MALI_CHANNEL_0 << 3) | \
279 (MALI_CHANNEL_0 << 6) | \
280 (MALI_CHANNEL_1 << 9)
Alyssa Rosenzweig816af262020-07-08 16:37:00 -0400281
Alyssa Rosenzweig4c891482020-07-03 13:01:16 -0400282#define MALI_SWIZZLE_A001 \
Alyssa Rosenzweigcdc32762020-08-12 16:46:07 -0400283 (MALI_CHANNEL_A << 0) | \
284 (MALI_CHANNEL_0 << 3) | \
285 (MALI_CHANNEL_0 << 6) | \
286 (MALI_CHANNEL_1 << 9)
Alyssa Rosenzweig4c891482020-07-03 13:01:16 -0400287
Alyssa Rosenzweig816af262020-07-08 16:37:00 -0400288
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500289void
290panfrost_new_texture(
291 void *out,
292 uint16_t width, uint16_t height,
293 uint16_t depth, uint16_t array_size,
294 enum pipe_format format,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400295 enum mali_texture_dimension dim,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400296 uint64_t modifier,
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500297 unsigned first_level, unsigned last_level,
298 unsigned first_layer, unsigned last_layer,
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400299 unsigned nr_samples,
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500300 unsigned cube_stride,
301 unsigned swizzle,
302 mali_ptr base,
303 struct panfrost_slice *slices)
304{
305 const struct util_format_description *desc =
306 util_format_description(format);
307
308 unsigned bytes_per_pixel = util_format_get_blocksize(format);
309
Alyssa Rosenzweig861e7dc2020-05-15 18:43:41 -0400310 enum mali_format mali_format = panfrost_pipe_format_table[desc->format].hw;
311 assert(mali_format);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500312
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400313 bool manual_stride = (modifier == DRM_FORMAT_MOD_LINEAR)
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500314 && panfrost_needs_explicit_stride(slices, width,
315 first_level, last_level, bytes_per_pixel);
316
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400317 unsigned format_swizzle = (format == PIPE_FORMAT_X24S8_UINT) ?
Alyssa Rosenzweig4c891482020-07-03 13:01:16 -0400318 MALI_SWIZZLE_A001 :
Alyssa Rosenzweig816af262020-07-08 16:37:00 -0400319 (format == PIPE_FORMAT_S8_UINT) ?
320 MALI_SWIZZLE_R001 :
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400321 panfrost_translate_swizzle_4(desc->swizzle);
322
323 bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
324
325 pan_pack(out, MIDGARD_TEXTURE, cfg) {
326 cfg.width = u_minify(width, first_level);
327 cfg.height = u_minify(height, first_level);
328 cfg.depth = u_minify(depth, first_level);
329 cfg.array_size = array_size;
330 cfg.format = format_swizzle | (mali_format << 12) | (srgb << 20);
331 cfg.dimension = dim;
332 cfg.texel_ordering = panfrost_modifier_to_layout(modifier);
333 cfg.manual_stride = manual_stride;
334 cfg.levels = last_level - first_level;
335 cfg.swizzle = swizzle;
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500336 };
337
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400338 panfrost_emit_texture_payload(
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400339 (mali_ptr *) (out + MALI_MIDGARD_TEXTURE_LENGTH),
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400340 desc,
341 mali_format,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400342 dim,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400343 modifier,
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400344 width, height,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400345 first_level, last_level,
346 first_layer, last_layer,
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400347 nr_samples,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400348 cube_stride,
349 manual_stride,
350 base,
351 slices);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500352}
353
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200354void
355panfrost_new_texture_bifrost(
Boris Brezillonfefb3e92020-09-23 11:08:02 +0200356 const struct panfrost_device *dev,
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400357 struct mali_bifrost_texture_packed *out,
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200358 uint16_t width, uint16_t height,
359 uint16_t depth, uint16_t array_size,
360 enum pipe_format format,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400361 enum mali_texture_dimension dim,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400362 uint64_t modifier,
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200363 unsigned first_level, unsigned last_level,
364 unsigned first_layer, unsigned last_layer,
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400365 unsigned nr_samples,
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200366 unsigned cube_stride,
367 unsigned swizzle,
368 mali_ptr base,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400369 struct panfrost_slice *slices,
370 struct panfrost_bo *payload)
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200371{
372 const struct util_format_description *desc =
373 util_format_description(format);
374
Alyssa Rosenzweig861e7dc2020-05-15 18:43:41 -0400375 enum mali_format mali_format = panfrost_pipe_format_table[desc->format].hw;
376 assert(mali_format);
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200377
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400378 panfrost_emit_texture_payload(
379 (mali_ptr *) payload->cpu,
380 desc,
381 mali_format,
Alyssa Rosenzweigf008a632020-08-11 17:27:36 -0400382 dim,
Alyssa Rosenzweig965537df2020-07-22 10:23:50 -0400383 modifier,
Alyssa Rosenzweig92553b62020-06-15 12:42:40 -0400384 width, height,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400385 first_level, last_level,
386 first_layer, last_layer,
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400387 nr_samples,
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400388 cube_stride,
Alyssa Rosenzweigbde19c02020-04-30 18:48:53 -0400389 true, /* Stride explicit on Bifrost */
Alyssa Rosenzweiga3d29362020-04-21 16:08:07 -0400390 base,
391 slices);
392
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400393 bool srgb = (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB);
394
395 pan_pack(out, BIFROST_TEXTURE, cfg) {
396 cfg.dimension = dim;
397 cfg.format = (mali_format << 12) | (srgb << 20);
Boris Brezillonfefb3e92020-09-23 11:08:02 +0200398 if (dev->quirks & HAS_SWIZZLES)
399 cfg.format |= panfrost_get_default_swizzle(desc->nr_channels);
400
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400401 cfg.width = u_minify(width, first_level);
402 cfg.height = u_minify(height, first_level);
403 cfg.swizzle = swizzle;
404 cfg.texel_ordering = panfrost_modifier_to_layout(modifier);
405 cfg.levels = last_level - first_level;
406 cfg.surfaces = payload->gpu;
407
Alyssa Rosenzweig239e4e82020-10-06 21:46:56 -0400408 /* We specify API-level LOD clamps in the sampler descriptor
409 * and use these clamps simply for bounds checking */
410 cfg.minimum_lod = FIXED_16(0, false);
411 cfg.maximum_lod = FIXED_16(cfg.levels, false);
Alyssa Rosenzweigad0b32c2020-08-06 18:12:28 -0400412 }
Tomeu Vizosoe41894b2020-04-17 14:23:49 +0200413}
414
Alyssa Rosenzweig5ddf7ad2020-02-18 12:07:47 -0500415/* Computes sizes for checksumming, which is 8 bytes per 16x16 tile.
416 * Checksumming is believed to be a CRC variant (CRC64 based on the size?).
417 * This feature is also known as "transaction elimination". */
418
419#define CHECKSUM_TILE_WIDTH 16
420#define CHECKSUM_TILE_HEIGHT 16
421#define CHECKSUM_BYTES_PER_TILE 8
422
423unsigned
424panfrost_compute_checksum_size(
425 struct panfrost_slice *slice,
426 unsigned width,
427 unsigned height)
428{
429 unsigned aligned_width = ALIGN_POT(width, CHECKSUM_TILE_WIDTH);
430 unsigned aligned_height = ALIGN_POT(height, CHECKSUM_TILE_HEIGHT);
431
432 unsigned tile_count_x = aligned_width / CHECKSUM_TILE_WIDTH;
433 unsigned tile_count_y = aligned_height / CHECKSUM_TILE_HEIGHT;
434
435 slice->checksum_stride = tile_count_x * CHECKSUM_BYTES_PER_TILE;
436
437 return slice->checksum_stride * tile_count_y;
438}
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500439
440unsigned
441panfrost_get_layer_stride(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level)
442{
443 return is_3d ? slices[level].size0 : cube_stride;
444}
445
446/* Computes the offset into a texture at a particular level/face. Add to
447 * the base address of a texture to get the address to that level/face */
448
449unsigned
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400450panfrost_texture_offset(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level, unsigned face, unsigned sample)
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500451{
452 unsigned layer_stride = panfrost_get_layer_stride(slices, is_3d, cube_stride, level);
Alyssa Rosenzweig41c06de2020-06-30 16:43:32 -0400453 return slices[level].offset + (face * layer_stride) + (sample * slices[level].size0);
Alyssa Rosenzweigb9295652020-02-18 14:20:16 -0500454}