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