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