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