xref: /aosp_15_r20/external/mesa3d/src/freedreno/fdl/fd6_view.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker  * Copyright © 2021 Valve Corporation
5*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Authors:
8*61046927SAndroid Build Coastguard Worker  *    Rob Clark <[email protected]>
9*61046927SAndroid Build Coastguard Worker  */
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "freedreno_layout.h"
12*61046927SAndroid Build Coastguard Worker #include "fd6_format_table.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker static enum a6xx_tex_type
fdl6_tex_type(enum fdl_view_type type,bool storage)15*61046927SAndroid Build Coastguard Worker fdl6_tex_type(enum fdl_view_type type, bool storage)
16*61046927SAndroid Build Coastguard Worker {
17*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned) FDL_VIEW_TYPE_1D == (unsigned) A6XX_TEX_1D);
18*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned) FDL_VIEW_TYPE_2D == (unsigned) A6XX_TEX_2D);
19*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned) FDL_VIEW_TYPE_CUBE == (unsigned) A6XX_TEX_CUBE);
20*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned) FDL_VIEW_TYPE_3D == (unsigned) A6XX_TEX_3D);
21*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT((unsigned) FDL_VIEW_TYPE_BUFFER == (unsigned) A6XX_TEX_BUFFER);
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker    return (storage && type == FDL_VIEW_TYPE_CUBE) ?
24*61046927SAndroid Build Coastguard Worker       A6XX_TEX_2D : (enum a6xx_tex_type) type;
25*61046927SAndroid Build Coastguard Worker }
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker void
fdl6_format_swiz(enum pipe_format format,bool has_z24uint_s8uint,unsigned char * format_swiz)28*61046927SAndroid Build Coastguard Worker fdl6_format_swiz(enum pipe_format format, bool has_z24uint_s8uint,
29*61046927SAndroid Build Coastguard Worker                  unsigned char *format_swiz)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker    format_swiz[0] = PIPE_SWIZZLE_X;
32*61046927SAndroid Build Coastguard Worker    format_swiz[1] = PIPE_SWIZZLE_Y;
33*61046927SAndroid Build Coastguard Worker    format_swiz[2] = PIPE_SWIZZLE_Z;
34*61046927SAndroid Build Coastguard Worker    format_swiz[3] = PIPE_SWIZZLE_W;
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker    /* Note: Using the swizzle here to do anything other than replace with a
37*61046927SAndroid Build Coastguard Worker     * constant or replicate a component breaks border colors, because border
38*61046927SAndroid Build Coastguard Worker     * color replacement will happen before this swizzle is applied but it's
39*61046927SAndroid Build Coastguard Worker     * supposed to happen after any "hidden" swizzles that are applied by the
40*61046927SAndroid Build Coastguard Worker     * driver as part of implementing the API format. There are a few
41*61046927SAndroid Build Coastguard Worker     * exceptions, called out below.
42*61046927SAndroid Build Coastguard Worker     */
43*61046927SAndroid Build Coastguard Worker    switch (format) {
44*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_G8B8_G8R8_UNORM:
45*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_B8G8_R8G8_UNORM:
46*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_G8_B8R8_420_UNORM:
47*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_G8_B8_R8_420_UNORM:
48*61046927SAndroid Build Coastguard Worker       /* These formats are currently only used for Vulkan, and border colors
49*61046927SAndroid Build Coastguard Worker        * aren't allowed on these formats in Vulkan because, from the
50*61046927SAndroid Build Coastguard Worker        * description of VkImageViewCreateInfo:
51*61046927SAndroid Build Coastguard Worker        *
52*61046927SAndroid Build Coastguard Worker        *    If the image has a multi-planar format and
53*61046927SAndroid Build Coastguard Worker        *    subresourceRange.aspectMask is VK_IMAGE_ASPECT_COLOR_BIT, ... then
54*61046927SAndroid Build Coastguard Worker        *    ... the sampler to be used with the image view must enable sampler
55*61046927SAndroid Build Coastguard Worker        *    ycbcr conversion.
56*61046927SAndroid Build Coastguard Worker        *
57*61046927SAndroid Build Coastguard Worker        * combined with this VU on VkSamplerCreateInfo:
58*61046927SAndroid Build Coastguard Worker        *
59*61046927SAndroid Build Coastguard Worker        *    If sampler ycbcr conversion is enabled, addressModeU,
60*61046927SAndroid Build Coastguard Worker        *    addressModeV, and addressModeW must be
61*61046927SAndroid Build Coastguard Worker        *    VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, ...
62*61046927SAndroid Build Coastguard Worker        *
63*61046927SAndroid Build Coastguard Worker        * This makes the swizzle safe.
64*61046927SAndroid Build Coastguard Worker        */
65*61046927SAndroid Build Coastguard Worker       format_swiz[0] = PIPE_SWIZZLE_Z;
66*61046927SAndroid Build Coastguard Worker       format_swiz[1] = PIPE_SWIZZLE_X;
67*61046927SAndroid Build Coastguard Worker       format_swiz[2] = PIPE_SWIZZLE_Y;
68*61046927SAndroid Build Coastguard Worker       break;
69*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_DXT1_RGB:
70*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_DXT1_SRGB:
71*61046927SAndroid Build Coastguard Worker       /* same hardware format is used for BC1_RGB / BC1_RGBA */
72*61046927SAndroid Build Coastguard Worker       format_swiz[3] = PIPE_SWIZZLE_1;
73*61046927SAndroid Build Coastguard Worker       break;
74*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_X24S8_UINT:
75*61046927SAndroid Build Coastguard Worker       if (!has_z24uint_s8uint) {
76*61046927SAndroid Build Coastguard Worker          /* using FMT6_8_8_8_8_UINT/XYZW so need to swizzle (0,0,1) in the
77*61046927SAndroid Build Coastguard Worker           * rest (see "Conversion to RGBA").
78*61046927SAndroid Build Coastguard Worker           */
79*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_0;
80*61046927SAndroid Build Coastguard Worker          format_swiz[2] = PIPE_SWIZZLE_0;
81*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_1;
82*61046927SAndroid Build Coastguard Worker       } else {
83*61046927SAndroid Build Coastguard Worker          /* Using FMT6_Z24_UINT_S8_UINT, which is (d, s, 0, 1), so need to
84*61046927SAndroid Build Coastguard Worker           * swizzle away the d. We don't use this if
85*61046927SAndroid Build Coastguard Worker           * customBorderColorWithoutFormat is enabled, so we can fix up the
86*61046927SAndroid Build Coastguard Worker           * border color, and there's a workaround in freedreno.
87*61046927SAndroid Build Coastguard Worker           */
88*61046927SAndroid Build Coastguard Worker          format_swiz[0] = PIPE_SWIZZLE_Y;
89*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_0;
90*61046927SAndroid Build Coastguard Worker       }
91*61046927SAndroid Build Coastguard Worker       break;
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker    default:
94*61046927SAndroid Build Coastguard Worker       /* Our I, L, A, and LA formats use R or RG HW formats except for
95*61046927SAndroid Build Coastguard Worker        * A8_UNORM. These aren't supported in Vulkan, and freedreno uses a hack
96*61046927SAndroid Build Coastguard Worker        * to get the border colors correct by undoing these swizzles.
97*61046927SAndroid Build Coastguard Worker        */
98*61046927SAndroid Build Coastguard Worker       if (util_format_is_alpha(format) && format != PIPE_FORMAT_A8_UNORM) {
99*61046927SAndroid Build Coastguard Worker          format_swiz[0] = PIPE_SWIZZLE_0;
100*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_0;
101*61046927SAndroid Build Coastguard Worker          format_swiz[2] = PIPE_SWIZZLE_0;
102*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_X;
103*61046927SAndroid Build Coastguard Worker       } else if (util_format_is_luminance(format)) {
104*61046927SAndroid Build Coastguard Worker          format_swiz[0] = PIPE_SWIZZLE_X;
105*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_X;
106*61046927SAndroid Build Coastguard Worker          format_swiz[2] = PIPE_SWIZZLE_X;
107*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_1;
108*61046927SAndroid Build Coastguard Worker       } else if (util_format_is_intensity(format)) {
109*61046927SAndroid Build Coastguard Worker          format_swiz[0] = PIPE_SWIZZLE_X;
110*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_X;
111*61046927SAndroid Build Coastguard Worker          format_swiz[2] = PIPE_SWIZZLE_X;
112*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_X;
113*61046927SAndroid Build Coastguard Worker       } else if (util_format_is_luminance_alpha(format)) {
114*61046927SAndroid Build Coastguard Worker          format_swiz[0] = PIPE_SWIZZLE_X;
115*61046927SAndroid Build Coastguard Worker          format_swiz[1] = PIPE_SWIZZLE_X;
116*61046927SAndroid Build Coastguard Worker          format_swiz[2] = PIPE_SWIZZLE_X;
117*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_Y;
118*61046927SAndroid Build Coastguard Worker       } else if (!util_format_has_alpha(format)) {
119*61046927SAndroid Build Coastguard Worker          /* for rgbx, force A to 1.  Harmless for R/RG, where we already get 1. */
120*61046927SAndroid Build Coastguard Worker          format_swiz[3] = PIPE_SWIZZLE_1;
121*61046927SAndroid Build Coastguard Worker       }
122*61046927SAndroid Build Coastguard Worker       break;
123*61046927SAndroid Build Coastguard Worker    }
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker static uint32_t
fdl6_texswiz(const struct fdl_view_args * args,bool has_z24uint_s8uint)127*61046927SAndroid Build Coastguard Worker fdl6_texswiz(const struct fdl_view_args *args, bool has_z24uint_s8uint)
128*61046927SAndroid Build Coastguard Worker {
129*61046927SAndroid Build Coastguard Worker    unsigned char format_swiz[4];
130*61046927SAndroid Build Coastguard Worker    fdl6_format_swiz(args->format, has_z24uint_s8uint, format_swiz);
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    unsigned char swiz[4];
133*61046927SAndroid Build Coastguard Worker    util_format_compose_swizzles(format_swiz, args->swiz, swiz);
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    return A6XX_TEX_CONST_0_SWIZ_X(fdl6_swiz(swiz[0])) |
136*61046927SAndroid Build Coastguard Worker           A6XX_TEX_CONST_0_SWIZ_Y(fdl6_swiz(swiz[1])) |
137*61046927SAndroid Build Coastguard Worker           A6XX_TEX_CONST_0_SWIZ_Z(fdl6_swiz(swiz[2])) |
138*61046927SAndroid Build Coastguard Worker           A6XX_TEX_CONST_0_SWIZ_W(fdl6_swiz(swiz[3]));
139*61046927SAndroid Build Coastguard Worker }
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker #define COND(bool, val) ((bool) ? (val) : 0)
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker void
fdl6_view_init(struct fdl6_view * view,const struct fdl_layout ** layouts,const struct fdl_view_args * args,bool has_z24uint_s8uint)144*61046927SAndroid Build Coastguard Worker fdl6_view_init(struct fdl6_view *view, const struct fdl_layout **layouts,
145*61046927SAndroid Build Coastguard Worker                const struct fdl_view_args *args, bool has_z24uint_s8uint)
146*61046927SAndroid Build Coastguard Worker {
147*61046927SAndroid Build Coastguard Worker    const struct fdl_layout *layout = layouts[0];
148*61046927SAndroid Build Coastguard Worker    uint32_t width = u_minify(layout->width0, args->base_miplevel);
149*61046927SAndroid Build Coastguard Worker    uint32_t height = u_minify(layout->height0, args->base_miplevel);
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker    /* If reinterpreting a compressed format as a size-compatible uncompressed
152*61046927SAndroid Build Coastguard Worker     * format, we need width/height in blocks, and vice-versa. In vulkan this
153*61046927SAndroid Build Coastguard Worker     * includes single-plane 422 formats which util/format doesn't consider
154*61046927SAndroid Build Coastguard Worker     * "compressed" (get_compressed() returns false).
155*61046927SAndroid Build Coastguard Worker     */
156*61046927SAndroid Build Coastguard Worker    if (util_format_get_blockwidth(layout->format) > 1 &&
157*61046927SAndroid Build Coastguard Worker        util_format_get_blockwidth(args->format) == 1) {
158*61046927SAndroid Build Coastguard Worker       width = util_format_get_nblocksx(layout->format, width);
159*61046927SAndroid Build Coastguard Worker    } else if (util_format_get_blockwidth(layout->format) == 1 &&
160*61046927SAndroid Build Coastguard Worker               util_format_get_blockwidth(args->format) > 1) {
161*61046927SAndroid Build Coastguard Worker       width *= util_format_get_blockwidth(args->format);
162*61046927SAndroid Build Coastguard Worker    }
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker    if (util_format_get_blockheight(layout->format) > 1 &&
165*61046927SAndroid Build Coastguard Worker        util_format_get_blockheight(args->format) == 1) {
166*61046927SAndroid Build Coastguard Worker       height = util_format_get_nblocksy(layout->format, height);
167*61046927SAndroid Build Coastguard Worker    } else if (util_format_get_blockheight(layout->format) == 1 &&
168*61046927SAndroid Build Coastguard Worker               util_format_get_blockheight(args->format) > 1) {
169*61046927SAndroid Build Coastguard Worker       height *= util_format_get_blockheight(args->format);
170*61046927SAndroid Build Coastguard Worker    }
171*61046927SAndroid Build Coastguard Worker 
172*61046927SAndroid Build Coastguard Worker    uint32_t storage_depth = args->layer_count;
173*61046927SAndroid Build Coastguard Worker    if (args->type == FDL_VIEW_TYPE_3D) {
174*61046927SAndroid Build Coastguard Worker       storage_depth = u_minify(layout->depth0, args->base_miplevel);
175*61046927SAndroid Build Coastguard Worker    }
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker    uint32_t depth = storage_depth;
178*61046927SAndroid Build Coastguard Worker    if (args->type == FDL_VIEW_TYPE_CUBE) {
179*61046927SAndroid Build Coastguard Worker       /* Cubes are treated as 2D arrays for storage images, so only divide the
180*61046927SAndroid Build Coastguard Worker        * depth by 6 for the texture descriptor.
181*61046927SAndroid Build Coastguard Worker        */
182*61046927SAndroid Build Coastguard Worker       depth /= 6;
183*61046927SAndroid Build Coastguard Worker    }
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    view->offset = fdl_surface_offset(layout, args->base_miplevel, args->base_array_layer);
186*61046927SAndroid Build Coastguard Worker    uint64_t base_addr = args->iova + view->offset;
187*61046927SAndroid Build Coastguard Worker    uint64_t ubwc_addr = args->iova +
188*61046927SAndroid Build Coastguard Worker       fdl_ubwc_offset(layout, args->base_miplevel, args->base_array_layer);
189*61046927SAndroid Build Coastguard Worker 
190*61046927SAndroid Build Coastguard Worker    uint32_t pitch = fdl_pitch(layout, args->base_miplevel);
191*61046927SAndroid Build Coastguard Worker    uint32_t ubwc_pitch = fdl_ubwc_pitch(layout, args->base_miplevel);
192*61046927SAndroid Build Coastguard Worker    uint32_t layer_size = fdl_layer_stride(layout, args->base_miplevel);
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    enum a6xx_format texture_format =
195*61046927SAndroid Build Coastguard Worker       fd6_texture_format(args->format, layout->tile_mode);
196*61046927SAndroid Build Coastguard Worker    enum a3xx_color_swap swap =
197*61046927SAndroid Build Coastguard Worker       fd6_texture_swap(args->format, layout->tile_mode);
198*61046927SAndroid Build Coastguard Worker    enum a6xx_tile_mode tile_mode = fdl_tile_mode(layout, args->base_miplevel);
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker    bool ubwc_enabled = fdl_ubwc_enabled(layout, args->base_miplevel);
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker    bool is_d24s8 = (args->format == PIPE_FORMAT_Z24_UNORM_S8_UINT ||
203*61046927SAndroid Build Coastguard Worker                     args->format == PIPE_FORMAT_Z24X8_UNORM ||
204*61046927SAndroid Build Coastguard Worker                     args->format == PIPE_FORMAT_X24S8_UINT);
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker    if (args->format == PIPE_FORMAT_X24S8_UINT && has_z24uint_s8uint) {
207*61046927SAndroid Build Coastguard Worker       texture_format = FMT6_Z24_UINT_S8_UINT;
208*61046927SAndroid Build Coastguard Worker       swap = WZYX;
209*61046927SAndroid Build Coastguard Worker    }
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker    /* FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 is broken without UBWC on a630.  We
212*61046927SAndroid Build Coastguard Worker     * don't need it without UBWC anyway because the purpose of the format is
213*61046927SAndroid Build Coastguard Worker     * UBWC-compatibility.
214*61046927SAndroid Build Coastguard Worker     */
215*61046927SAndroid Build Coastguard Worker    if (texture_format == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 && !ubwc_enabled)
216*61046927SAndroid Build Coastguard Worker       texture_format = FMT6_8_8_8_8_UNORM;
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    enum a6xx_format storage_format = texture_format;
219*61046927SAndroid Build Coastguard Worker    if (is_d24s8) {
220*61046927SAndroid Build Coastguard Worker       if (ubwc_enabled)
221*61046927SAndroid Build Coastguard Worker          storage_format = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
222*61046927SAndroid Build Coastguard Worker       else
223*61046927SAndroid Build Coastguard Worker          storage_format = FMT6_8_8_8_8_UNORM;
224*61046927SAndroid Build Coastguard Worker    }
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker    view->format = args->format;
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker    memset(view->descriptor, 0, sizeof(view->descriptor));
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    view->descriptor[0] =
231*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_TILE_MODE(tile_mode) |
232*61046927SAndroid Build Coastguard Worker       COND(util_format_is_srgb(args->format), A6XX_TEX_CONST_0_SRGB) |
233*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_FMT(texture_format) |
234*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_SAMPLES(util_logbase2(layout->nr_samples)) |
235*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_SWAP(swap) |
236*61046927SAndroid Build Coastguard Worker       fdl6_texswiz(args, has_z24uint_s8uint) |
237*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_MIPLVLS(args->level_count - 1);
238*61046927SAndroid Build Coastguard Worker    view->descriptor[1] =
239*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height) |
240*61046927SAndroid Build Coastguard Worker       COND(args->ubwc_fc_mutable, A6XX_TEX_CONST_1_MUTABLEEN);
241*61046927SAndroid Build Coastguard Worker    view->descriptor[2] =
242*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_2_PITCHALIGN(layout->pitchalign - 6) |
243*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_2_PITCH(pitch) |
244*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_2_TYPE(fdl6_tex_type(args->type, false));
245*61046927SAndroid Build Coastguard Worker    view->descriptor[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(layer_size);
246*61046927SAndroid Build Coastguard Worker    view->descriptor[4] = base_addr;
247*61046927SAndroid Build Coastguard Worker    view->descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(depth);
248*61046927SAndroid Build Coastguard Worker    view->descriptor[6] = A6XX_TEX_CONST_6_MIN_LOD_CLAMP(args->min_lod_clamp - args->base_miplevel);
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker    if (layout->tile_all)
251*61046927SAndroid Build Coastguard Worker       view->descriptor[3] |= A6XX_TEX_CONST_3_TILE_ALL;
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker    if (args->format == PIPE_FORMAT_R8_G8B8_420_UNORM ||
254*61046927SAndroid Build Coastguard Worker        args->format == PIPE_FORMAT_G8_B8R8_420_UNORM ||
255*61046927SAndroid Build Coastguard Worker        args->format == PIPE_FORMAT_G8_B8_R8_420_UNORM) {
256*61046927SAndroid Build Coastguard Worker       /* chroma offset re-uses MIPLVLS bits */
257*61046927SAndroid Build Coastguard Worker       assert(args->level_count == 1);
258*61046927SAndroid Build Coastguard Worker       if (args->chroma_offsets[0] == FDL_CHROMA_LOCATION_MIDPOINT)
259*61046927SAndroid Build Coastguard Worker          view->descriptor[0] |= A6XX_TEX_CONST_0_CHROMA_MIDPOINT_X;
260*61046927SAndroid Build Coastguard Worker       if (args->chroma_offsets[1] == FDL_CHROMA_LOCATION_MIDPOINT)
261*61046927SAndroid Build Coastguard Worker          view->descriptor[0] |= A6XX_TEX_CONST_0_CHROMA_MIDPOINT_Y;
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker       uint64_t base_addr[3];
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker       if (ubwc_enabled) {
266*61046927SAndroid Build Coastguard Worker          view->descriptor[3] |= A6XX_TEX_CONST_3_FLAG;
267*61046927SAndroid Build Coastguard Worker          /* no separate ubwc base, image must have the expected layout */
268*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < 3; i++) {
269*61046927SAndroid Build Coastguard Worker             base_addr[i] = args->iova +
270*61046927SAndroid Build Coastguard Worker                fdl_ubwc_offset(layouts[i], args->base_miplevel, args->base_array_layer);
271*61046927SAndroid Build Coastguard Worker          }
272*61046927SAndroid Build Coastguard Worker       } else {
273*61046927SAndroid Build Coastguard Worker          for (uint32_t i = 0; i < 3; i++) {
274*61046927SAndroid Build Coastguard Worker             base_addr[i] = args->iova +
275*61046927SAndroid Build Coastguard Worker                fdl_surface_offset(layouts[i], args->base_miplevel, args->base_array_layer);
276*61046927SAndroid Build Coastguard Worker          }
277*61046927SAndroid Build Coastguard Worker       }
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker       view->descriptor[4] = base_addr[0];
280*61046927SAndroid Build Coastguard Worker       view->descriptor[5] |= base_addr[0] >> 32;
281*61046927SAndroid Build Coastguard Worker       view->descriptor[6] =
282*61046927SAndroid Build Coastguard Worker          A6XX_TEX_CONST_6_PLANE_PITCH(fdl_pitch(layouts[1], args->base_miplevel));
283*61046927SAndroid Build Coastguard Worker       view->descriptor[7] = base_addr[1];
284*61046927SAndroid Build Coastguard Worker       view->descriptor[8] = base_addr[1] >> 32;
285*61046927SAndroid Build Coastguard Worker       view->descriptor[9] = base_addr[2];
286*61046927SAndroid Build Coastguard Worker       view->descriptor[10] = base_addr[2] >> 32;
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker       assert(args->type != FDL_VIEW_TYPE_3D);
289*61046927SAndroid Build Coastguard Worker       return;
290*61046927SAndroid Build Coastguard Worker    }
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker    if (ubwc_enabled) {
293*61046927SAndroid Build Coastguard Worker       uint32_t block_width, block_height;
294*61046927SAndroid Build Coastguard Worker       fdl6_get_ubwc_blockwidth(layout, &block_width, &block_height);
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker       view->descriptor[3] |= A6XX_TEX_CONST_3_FLAG;
297*61046927SAndroid Build Coastguard Worker       view->descriptor[7] = ubwc_addr;
298*61046927SAndroid Build Coastguard Worker       view->descriptor[8] = ubwc_addr >> 32;
299*61046927SAndroid Build Coastguard Worker       view->descriptor[9] |= A6XX_TEX_CONST_9_FLAG_BUFFER_ARRAY_PITCH(layout->ubwc_layer_size >> 2);
300*61046927SAndroid Build Coastguard Worker       view->descriptor[10] |=
301*61046927SAndroid Build Coastguard Worker          A6XX_TEX_CONST_10_FLAG_BUFFER_PITCH(ubwc_pitch) |
302*61046927SAndroid Build Coastguard Worker          A6XX_TEX_CONST_10_FLAG_BUFFER_LOGW(util_logbase2_ceil(DIV_ROUND_UP(width, block_width))) |
303*61046927SAndroid Build Coastguard Worker          A6XX_TEX_CONST_10_FLAG_BUFFER_LOGH(util_logbase2_ceil(DIV_ROUND_UP(height, block_height)));
304*61046927SAndroid Build Coastguard Worker    }
305*61046927SAndroid Build Coastguard Worker 
306*61046927SAndroid Build Coastguard Worker    if (args->type == FDL_VIEW_TYPE_3D) {
307*61046927SAndroid Build Coastguard Worker       view->descriptor[3] |=
308*61046927SAndroid Build Coastguard Worker          A6XX_TEX_CONST_3_MIN_LAYERSZ(layout->slices[layout->mip_levels - 1].size0);
309*61046927SAndroid Build Coastguard Worker    }
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    bool samples_average =
312*61046927SAndroid Build Coastguard Worker       layout->nr_samples > 1 &&
313*61046927SAndroid Build Coastguard Worker       !util_format_is_pure_integer(args->format) &&
314*61046927SAndroid Build Coastguard Worker       !util_format_is_depth_or_stencil(args->format);
315*61046927SAndroid Build Coastguard Worker 
316*61046927SAndroid Build Coastguard Worker    view->pitch = pitch;
317*61046927SAndroid Build Coastguard Worker 
318*61046927SAndroid Build Coastguard Worker    view->SP_PS_2D_SRC_INFO =
319*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(storage_format) |
320*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(tile_mode) |
321*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(swap) |
322*61046927SAndroid Build Coastguard Worker       COND(ubwc_enabled, A6XX_SP_PS_2D_SRC_INFO_FLAGS) |
323*61046927SAndroid Build Coastguard Worker       COND(util_format_is_srgb(args->format), A6XX_SP_PS_2D_SRC_INFO_SRGB) |
324*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_SAMPLES(util_logbase2(layout->nr_samples)) |
325*61046927SAndroid Build Coastguard Worker       COND(samples_average, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
326*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_UNK20 |
327*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_INFO_UNK22 |
328*61046927SAndroid Build Coastguard Worker       COND(args->ubwc_fc_mutable, A6XX_SP_PS_2D_SRC_INFO_MUTABLEEN);
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker    view->SP_PS_2D_SRC_SIZE =
331*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_SIZE_WIDTH(width) |
332*61046927SAndroid Build Coastguard Worker       A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(height);
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker    /* note: these have same encoding for MRT and 2D (except 2D PITCH src) */
335*61046927SAndroid Build Coastguard Worker    view->FLAG_BUFFER_PITCH =
336*61046927SAndroid Build Coastguard Worker       A6XX_RB_DEPTH_FLAG_BUFFER_PITCH_PITCH(ubwc_pitch) |
337*61046927SAndroid Build Coastguard Worker       A6XX_RB_DEPTH_FLAG_BUFFER_PITCH_ARRAY_PITCH(layout->ubwc_layer_size >> 2);
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker    const struct util_format_description *format_desc =
340*61046927SAndroid Build Coastguard Worker       util_format_description(args->format);
341*61046927SAndroid Build Coastguard Worker    if (util_format_has_depth(format_desc)) {
342*61046927SAndroid Build Coastguard Worker       view->GRAS_LRZ_DEPTH_VIEW =
343*61046927SAndroid Build Coastguard Worker          A6XX_GRAS_LRZ_DEPTH_VIEW_BASE_LAYER(args->base_array_layer) |
344*61046927SAndroid Build Coastguard Worker          A6XX_GRAS_LRZ_DEPTH_VIEW_LAYER_COUNT(args->layer_count) |
345*61046927SAndroid Build Coastguard Worker          A6XX_GRAS_LRZ_DEPTH_VIEW_BASE_MIP_LEVEL(args->base_miplevel);
346*61046927SAndroid Build Coastguard Worker    }
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker    view->base_addr = base_addr;
349*61046927SAndroid Build Coastguard Worker    view->ubwc_addr = ubwc_addr;
350*61046927SAndroid Build Coastguard Worker    view->layer_size = layer_size;
351*61046927SAndroid Build Coastguard Worker    view->ubwc_layer_size = layout->ubwc_layer_size;
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker    enum a6xx_format color_format =
354*61046927SAndroid Build Coastguard Worker       fd6_color_format(args->format, layout->tile_mode);
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker    /* Don't set fields that are only used for attachments/blit dest if COLOR
357*61046927SAndroid Build Coastguard Worker     * is unsupported.
358*61046927SAndroid Build Coastguard Worker     */
359*61046927SAndroid Build Coastguard Worker    if (color_format == FMT6_NONE)
360*61046927SAndroid Build Coastguard Worker       return;
361*61046927SAndroid Build Coastguard Worker 
362*61046927SAndroid Build Coastguard Worker    enum a3xx_color_swap color_swap =
363*61046927SAndroid Build Coastguard Worker       fd6_color_swap(args->format, layout->tile_mode);
364*61046927SAndroid Build Coastguard Worker    enum a6xx_format blit_format = color_format;
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    if (is_d24s8)
367*61046927SAndroid Build Coastguard Worker       color_format = FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
368*61046927SAndroid Build Coastguard Worker 
369*61046927SAndroid Build Coastguard Worker    if (color_format == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 && !ubwc_enabled)
370*61046927SAndroid Build Coastguard Worker       color_format = FMT6_8_8_8_8_UNORM;
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    /* We don't need FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 / FMT6_8_8_8_8_UNORM
373*61046927SAndroid Build Coastguard Worker     * for event blits.  FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8 also does not
374*61046927SAndroid Build Coastguard Worker     * support fast clears and is slower.
375*61046927SAndroid Build Coastguard Worker     */
376*61046927SAndroid Build Coastguard Worker    if (is_d24s8 || blit_format == FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8)
377*61046927SAndroid Build Coastguard Worker       blit_format = FMT6_Z24_UNORM_S8_UINT;
378*61046927SAndroid Build Coastguard Worker 
379*61046927SAndroid Build Coastguard Worker    memset(view->storage_descriptor, 0, sizeof(view->storage_descriptor));
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[0] =
382*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_FMT(storage_format) |
383*61046927SAndroid Build Coastguard Worker       COND(util_format_is_srgb(args->format), A6XX_TEX_CONST_0_SRGB) |
384*61046927SAndroid Build Coastguard Worker       fdl6_texswiz(args, has_z24uint_s8uint) |
385*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_TILE_MODE(tile_mode) |
386*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_SWAP(color_swap);
387*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[1] = view->descriptor[1];
388*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[2] =
389*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_2_PITCH(pitch) |
390*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_2_TYPE(fdl6_tex_type(args->type, true));
391*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[3] = view->descriptor[3];
392*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[4] = base_addr;
393*61046927SAndroid Build Coastguard Worker    view->storage_descriptor[5] = (base_addr >> 32) | A6XX_TEX_CONST_5_DEPTH(storage_depth);
394*61046927SAndroid Build Coastguard Worker    for (unsigned i = 6; i <= 10; i++)
395*61046927SAndroid Build Coastguard Worker       view->storage_descriptor[i] = view->descriptor[i];
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker    view->width = width;
398*61046927SAndroid Build Coastguard Worker    view->height = height;
399*61046927SAndroid Build Coastguard Worker    view->need_y2_align =
400*61046927SAndroid Build Coastguard Worker       tile_mode == TILE6_LINEAR && args->base_miplevel != layout->mip_levels - 1;
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker    view->ubwc_enabled = ubwc_enabled;
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker    view->RB_MRT_BUF_INFO =
405*61046927SAndroid Build Coastguard Worker       A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
406*61046927SAndroid Build Coastguard Worker       A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(color_format) |
407*61046927SAndroid Build Coastguard Worker       COND(args->chip >= A7XX && ubwc_enabled, A7XX_RB_MRT_BUF_INFO_LOSSLESSCOMPEN) |
408*61046927SAndroid Build Coastguard Worker       A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(color_swap) |
409*61046927SAndroid Build Coastguard Worker       COND(args->ubwc_fc_mutable, A7XX_RB_MRT_BUF_INFO_MUTABLEEN);
410*61046927SAndroid Build Coastguard Worker 
411*61046927SAndroid Build Coastguard Worker    view->SP_FS_MRT_REG =
412*61046927SAndroid Build Coastguard Worker       A6XX_SP_FS_MRT_REG_COLOR_FORMAT(color_format) |
413*61046927SAndroid Build Coastguard Worker       COND(util_format_is_pure_sint(args->format), A6XX_SP_FS_MRT_REG_COLOR_SINT) |
414*61046927SAndroid Build Coastguard Worker       COND(util_format_is_pure_uint(args->format), A6XX_SP_FS_MRT_REG_COLOR_UINT);
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker    view->RB_2D_DST_INFO =
417*61046927SAndroid Build Coastguard Worker       A6XX_RB_2D_DST_INFO_COLOR_FORMAT(color_format) |
418*61046927SAndroid Build Coastguard Worker       A6XX_RB_2D_DST_INFO_TILE_MODE(tile_mode) |
419*61046927SAndroid Build Coastguard Worker       A6XX_RB_2D_DST_INFO_COLOR_SWAP(color_swap) |
420*61046927SAndroid Build Coastguard Worker       COND(ubwc_enabled, A6XX_RB_2D_DST_INFO_FLAGS) |
421*61046927SAndroid Build Coastguard Worker       COND(util_format_is_srgb(args->format), A6XX_RB_2D_DST_INFO_SRGB) |
422*61046927SAndroid Build Coastguard Worker       COND(args->ubwc_fc_mutable, A6XX_RB_2D_DST_INFO_MUTABLEEN);;
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker    view->RB_BLIT_DST_INFO =
425*61046927SAndroid Build Coastguard Worker       A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
426*61046927SAndroid Build Coastguard Worker       A6XX_RB_BLIT_DST_INFO_SAMPLES(util_logbase2(layout->nr_samples)) |
427*61046927SAndroid Build Coastguard Worker       A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(blit_format) |
428*61046927SAndroid Build Coastguard Worker       A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(color_swap) |
429*61046927SAndroid Build Coastguard Worker       COND(ubwc_enabled, A6XX_RB_BLIT_DST_INFO_FLAGS) |
430*61046927SAndroid Build Coastguard Worker       COND(args->ubwc_fc_mutable, A6XX_RB_BLIT_DST_INFO_MUTABLEEN);
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker void
fdl6_buffer_view_init(uint32_t * descriptor,enum pipe_format format,const uint8_t * swiz,uint64_t iova,uint32_t size)434*61046927SAndroid Build Coastguard Worker fdl6_buffer_view_init(uint32_t *descriptor, enum pipe_format format,
435*61046927SAndroid Build Coastguard Worker                       const uint8_t *swiz, uint64_t iova, uint32_t size)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker    unsigned elem_size = util_format_get_blocksize(format);
438*61046927SAndroid Build Coastguard Worker    unsigned elements = size / elem_size;
439*61046927SAndroid Build Coastguard Worker    uint64_t base_iova = iova & ~0x3full;
440*61046927SAndroid Build Coastguard Worker    unsigned texel_offset = (iova & 0x3f) / elem_size;
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker    struct fdl_view_args args = {
443*61046927SAndroid Build Coastguard Worker       .format = format,
444*61046927SAndroid Build Coastguard Worker       .swiz = {swiz[0], swiz[1], swiz[2], swiz[3]},
445*61046927SAndroid Build Coastguard Worker    };
446*61046927SAndroid Build Coastguard Worker 
447*61046927SAndroid Build Coastguard Worker    memset(descriptor, 0, 4 * FDL6_TEX_CONST_DWORDS);
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker    descriptor[0] =
450*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_TILE_MODE(TILE6_LINEAR) |
451*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_SWAP(fd6_texture_swap(format, TILE6_LINEAR)) |
452*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_FMT(fd6_texture_format(format, TILE6_LINEAR)) |
453*61046927SAndroid Build Coastguard Worker       A6XX_TEX_CONST_0_MIPLVLS(0) | fdl6_texswiz(&args, false) |
454*61046927SAndroid Build Coastguard Worker       COND(util_format_is_srgb(format), A6XX_TEX_CONST_0_SRGB);
455*61046927SAndroid Build Coastguard Worker    descriptor[1] = A6XX_TEX_CONST_1_WIDTH(elements & ((1 << 15) - 1)) |
456*61046927SAndroid Build Coastguard Worker                    A6XX_TEX_CONST_1_HEIGHT(elements >> 15);
457*61046927SAndroid Build Coastguard Worker    descriptor[2] = A6XX_TEX_CONST_2_STRUCTSIZETEXELS(1) |
458*61046927SAndroid Build Coastguard Worker                    A6XX_TEX_CONST_2_STARTOFFSETTEXELS(texel_offset) |
459*61046927SAndroid Build Coastguard Worker                    A6XX_TEX_CONST_2_TYPE(A6XX_TEX_BUFFER);
460*61046927SAndroid Build Coastguard Worker    descriptor[4] = base_iova;
461*61046927SAndroid Build Coastguard Worker    descriptor[5] = base_iova >> 32;
462*61046927SAndroid Build Coastguard Worker }
463