1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2014-2017 Broadcom 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci/** @file v3d_tiling.c 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci * Handles information about the V3D tiling formats, and loading and storing 27bf215546Sopenharmony_ci * from them. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include <stdint.h> 31bf215546Sopenharmony_ci#include "v3d_tiling.h" 32bf215546Sopenharmony_ci#include "broadcom/common/v3d_cpu_tiling.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci/** Return the width in pixels of a 64-byte microtile. */ 35bf215546Sopenharmony_ciuint32_t 36bf215546Sopenharmony_civ3d_utile_width(int cpp) 37bf215546Sopenharmony_ci{ 38bf215546Sopenharmony_ci switch (cpp) { 39bf215546Sopenharmony_ci case 1: 40bf215546Sopenharmony_ci case 2: 41bf215546Sopenharmony_ci return 8; 42bf215546Sopenharmony_ci case 4: 43bf215546Sopenharmony_ci case 8: 44bf215546Sopenharmony_ci return 4; 45bf215546Sopenharmony_ci case 16: 46bf215546Sopenharmony_ci return 2; 47bf215546Sopenharmony_ci default: 48bf215546Sopenharmony_ci unreachable("unknown cpp"); 49bf215546Sopenharmony_ci } 50bf215546Sopenharmony_ci} 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci/** Return the height in pixels of a 64-byte microtile. */ 53bf215546Sopenharmony_ciuint32_t 54bf215546Sopenharmony_civ3d_utile_height(int cpp) 55bf215546Sopenharmony_ci{ 56bf215546Sopenharmony_ci switch (cpp) { 57bf215546Sopenharmony_ci case 1: 58bf215546Sopenharmony_ci return 8; 59bf215546Sopenharmony_ci case 2: 60bf215546Sopenharmony_ci case 4: 61bf215546Sopenharmony_ci return 4; 62bf215546Sopenharmony_ci case 8: 63bf215546Sopenharmony_ci case 16: 64bf215546Sopenharmony_ci return 2; 65bf215546Sopenharmony_ci default: 66bf215546Sopenharmony_ci unreachable("unknown cpp"); 67bf215546Sopenharmony_ci } 68bf215546Sopenharmony_ci} 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci/** 71bf215546Sopenharmony_ci * Returns the byte address for a given pixel within a utile. 72bf215546Sopenharmony_ci * 73bf215546Sopenharmony_ci * Utiles are 64b blocks of pixels in raster order, with 32bpp being a 4x4 74bf215546Sopenharmony_ci * arrangement. 75bf215546Sopenharmony_ci */ 76bf215546Sopenharmony_cistatic inline uint32_t 77bf215546Sopenharmony_civ3d_get_utile_pixel_offset(uint32_t cpp, uint32_t x, uint32_t y) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci uint32_t utile_w = v3d_utile_width(cpp); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci assert(x < utile_w && y < v3d_utile_height(cpp)); 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci return x * cpp + y * utile_w * cpp; 84bf215546Sopenharmony_ci} 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci/** 87bf215546Sopenharmony_ci * Returns the byte offset for a given pixel in a LINEARTILE layout. 88bf215546Sopenharmony_ci * 89bf215546Sopenharmony_ci * LINEARTILE is a single line of utiles in either the X or Y direction. 90bf215546Sopenharmony_ci */ 91bf215546Sopenharmony_cistatic inline uint32_t 92bf215546Sopenharmony_civ3d_get_lt_pixel_offset(uint32_t cpp, uint32_t image_h, uint32_t x, uint32_t y) 93bf215546Sopenharmony_ci{ 94bf215546Sopenharmony_ci uint32_t utile_w = v3d_utile_width(cpp); 95bf215546Sopenharmony_ci uint32_t utile_h = v3d_utile_height(cpp); 96bf215546Sopenharmony_ci uint32_t utile_index_x = x / utile_w; 97bf215546Sopenharmony_ci uint32_t utile_index_y = y / utile_h; 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci assert(utile_index_x == 0 || utile_index_y == 0); 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci return (64 * (utile_index_x + utile_index_y) + 102bf215546Sopenharmony_ci v3d_get_utile_pixel_offset(cpp, 103bf215546Sopenharmony_ci x & (utile_w - 1), 104bf215546Sopenharmony_ci y & (utile_h - 1))); 105bf215546Sopenharmony_ci} 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci/** 108bf215546Sopenharmony_ci * Returns the byte offset for a given pixel in a UBLINEAR layout. 109bf215546Sopenharmony_ci * 110bf215546Sopenharmony_ci * UBLINEAR is the layout where pixels are arranged in UIF blocks (2x2 111bf215546Sopenharmony_ci * utiles), and the UIF blocks are in 1 or 2 columns in raster order. 112bf215546Sopenharmony_ci */ 113bf215546Sopenharmony_cistatic inline uint32_t 114bf215546Sopenharmony_civ3d_get_ublinear_pixel_offset(uint32_t cpp, uint32_t x, uint32_t y, 115bf215546Sopenharmony_ci int ublinear_number) 116bf215546Sopenharmony_ci{ 117bf215546Sopenharmony_ci uint32_t utile_w = v3d_utile_width(cpp); 118bf215546Sopenharmony_ci uint32_t utile_h = v3d_utile_height(cpp); 119bf215546Sopenharmony_ci uint32_t ub_w = utile_w * 2; 120bf215546Sopenharmony_ci uint32_t ub_h = utile_h * 2; 121bf215546Sopenharmony_ci uint32_t ub_x = x / ub_w; 122bf215546Sopenharmony_ci uint32_t ub_y = y / ub_h; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return (256 * (ub_y * ublinear_number + 125bf215546Sopenharmony_ci ub_x) + 126bf215546Sopenharmony_ci ((x & utile_w) ? 64 : 0) + 127bf215546Sopenharmony_ci ((y & utile_h) ? 128 : 0) + 128bf215546Sopenharmony_ci + v3d_get_utile_pixel_offset(cpp, 129bf215546Sopenharmony_ci x & (utile_w - 1), 130bf215546Sopenharmony_ci y & (utile_h - 1))); 131bf215546Sopenharmony_ci} 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_cistatic inline uint32_t 134bf215546Sopenharmony_civ3d_get_ublinear_2_column_pixel_offset(uint32_t cpp, uint32_t image_h, 135bf215546Sopenharmony_ci uint32_t x, uint32_t y) 136bf215546Sopenharmony_ci{ 137bf215546Sopenharmony_ci return v3d_get_ublinear_pixel_offset(cpp, x, y, 2); 138bf215546Sopenharmony_ci} 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_cistatic inline uint32_t 141bf215546Sopenharmony_civ3d_get_ublinear_1_column_pixel_offset(uint32_t cpp, uint32_t image_h, 142bf215546Sopenharmony_ci uint32_t x, uint32_t y) 143bf215546Sopenharmony_ci{ 144bf215546Sopenharmony_ci return v3d_get_ublinear_pixel_offset(cpp, x, y, 1); 145bf215546Sopenharmony_ci} 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci/** 148bf215546Sopenharmony_ci * Returns the byte offset for a given pixel in a UIF layout. 149bf215546Sopenharmony_ci * 150bf215546Sopenharmony_ci * UIF is the general V3D tiling layout shared across 3D, media, and scanout. 151bf215546Sopenharmony_ci * It stores pixels in UIF blocks (2x2 utiles), and UIF blocks are stored in 152bf215546Sopenharmony_ci * 4x4 groups, and those 4x4 groups are then stored in raster order. 153bf215546Sopenharmony_ci */ 154bf215546Sopenharmony_cistatic inline uint32_t 155bf215546Sopenharmony_civ3d_get_uif_pixel_offset(uint32_t cpp, uint32_t image_h, uint32_t x, uint32_t y, 156bf215546Sopenharmony_ci bool do_xor) 157bf215546Sopenharmony_ci{ 158bf215546Sopenharmony_ci uint32_t utile_w = v3d_utile_width(cpp); 159bf215546Sopenharmony_ci uint32_t utile_h = v3d_utile_height(cpp); 160bf215546Sopenharmony_ci uint32_t mb_width = utile_w * 2; 161bf215546Sopenharmony_ci uint32_t mb_height = utile_h * 2; 162bf215546Sopenharmony_ci uint32_t log2_mb_width = ffs(mb_width) - 1; 163bf215546Sopenharmony_ci uint32_t log2_mb_height = ffs(mb_height) - 1; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci /* Macroblock X, y */ 166bf215546Sopenharmony_ci uint32_t mb_x = x >> log2_mb_width; 167bf215546Sopenharmony_ci uint32_t mb_y = y >> log2_mb_height; 168bf215546Sopenharmony_ci /* X, y within the macroblock */ 169bf215546Sopenharmony_ci uint32_t mb_pixel_x = x - (mb_x << log2_mb_width); 170bf215546Sopenharmony_ci uint32_t mb_pixel_y = y - (mb_y << log2_mb_height); 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci if (do_xor && (mb_x / 4) & 1) 173bf215546Sopenharmony_ci mb_y ^= 0x10; 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci uint32_t mb_h = align(image_h, 1 << log2_mb_height) >> log2_mb_height; 176bf215546Sopenharmony_ci uint32_t mb_id = ((mb_x / 4) * ((mb_h - 1) * 4)) + mb_x + mb_y * 4; 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci uint32_t mb_base_addr = mb_id * 256; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci bool top = mb_pixel_y < utile_h; 181bf215546Sopenharmony_ci bool left = mb_pixel_x < utile_w; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci /* Docs have this in pixels, we do bytes here. */ 184bf215546Sopenharmony_ci uint32_t mb_tile_offset = (!top * 128 + !left * 64); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci uint32_t utile_x = mb_pixel_x & (utile_w - 1); 187bf215546Sopenharmony_ci uint32_t utile_y = mb_pixel_y & (utile_h - 1); 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci uint32_t mb_pixel_address = (mb_base_addr + 190bf215546Sopenharmony_ci mb_tile_offset + 191bf215546Sopenharmony_ci v3d_get_utile_pixel_offset(cpp, 192bf215546Sopenharmony_ci utile_x, 193bf215546Sopenharmony_ci utile_y)); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci return mb_pixel_address; 196bf215546Sopenharmony_ci} 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_cistatic inline uint32_t 199bf215546Sopenharmony_civ3d_get_uif_xor_pixel_offset(uint32_t cpp, uint32_t image_h, 200bf215546Sopenharmony_ci uint32_t x, uint32_t y) 201bf215546Sopenharmony_ci{ 202bf215546Sopenharmony_ci return v3d_get_uif_pixel_offset(cpp, image_h, x, y, true); 203bf215546Sopenharmony_ci} 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_cistatic inline uint32_t 206bf215546Sopenharmony_civ3d_get_uif_no_xor_pixel_offset(uint32_t cpp, uint32_t image_h, 207bf215546Sopenharmony_ci uint32_t x, uint32_t y) 208bf215546Sopenharmony_ci{ 209bf215546Sopenharmony_ci return v3d_get_uif_pixel_offset(cpp, image_h, x, y, false); 210bf215546Sopenharmony_ci} 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci/* Loads/stores non-utile-aligned boxes by walking over the destination 213bf215546Sopenharmony_ci * rectangle, computing the address on the GPU, and storing/loading a pixel at 214bf215546Sopenharmony_ci * a time. 215bf215546Sopenharmony_ci */ 216bf215546Sopenharmony_cistatic inline void 217bf215546Sopenharmony_civ3d_move_pixels_unaligned(void *gpu, uint32_t gpu_stride, 218bf215546Sopenharmony_ci void *cpu, uint32_t cpu_stride, 219bf215546Sopenharmony_ci int cpp, uint32_t image_h, 220bf215546Sopenharmony_ci const struct pipe_box *box, 221bf215546Sopenharmony_ci uint32_t (*get_pixel_offset)(uint32_t cpp, 222bf215546Sopenharmony_ci uint32_t image_h, 223bf215546Sopenharmony_ci uint32_t x, uint32_t y), 224bf215546Sopenharmony_ci bool is_load) 225bf215546Sopenharmony_ci{ 226bf215546Sopenharmony_ci for (uint32_t y = 0; y < box->height; y++) { 227bf215546Sopenharmony_ci void *cpu_row = cpu + y * cpu_stride; 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci for (int x = 0; x < box->width; x++) { 230bf215546Sopenharmony_ci uint32_t pixel_offset = get_pixel_offset(cpp, image_h, 231bf215546Sopenharmony_ci box->x + x, 232bf215546Sopenharmony_ci box->y + y); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci if (false) { 235bf215546Sopenharmony_ci fprintf(stderr, "%3d,%3d -> %d\n", 236bf215546Sopenharmony_ci box->x + x, box->y + y, 237bf215546Sopenharmony_ci pixel_offset); 238bf215546Sopenharmony_ci } 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ci if (is_load) { 241bf215546Sopenharmony_ci memcpy(cpu_row + x * cpp, 242bf215546Sopenharmony_ci gpu + pixel_offset, 243bf215546Sopenharmony_ci cpp); 244bf215546Sopenharmony_ci } else { 245bf215546Sopenharmony_ci memcpy(gpu + pixel_offset, 246bf215546Sopenharmony_ci cpu_row + x * cpp, 247bf215546Sopenharmony_ci cpp); 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci} 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci/* Breaks the image down into utiles and calls either the fast whole-utile 254bf215546Sopenharmony_ci * load/store functions, or the unaligned fallback case. 255bf215546Sopenharmony_ci */ 256bf215546Sopenharmony_cistatic inline void 257bf215546Sopenharmony_civ3d_move_pixels_general_percpp(void *gpu, uint32_t gpu_stride, 258bf215546Sopenharmony_ci void *cpu, uint32_t cpu_stride, 259bf215546Sopenharmony_ci int cpp, uint32_t image_h, 260bf215546Sopenharmony_ci const struct pipe_box *box, 261bf215546Sopenharmony_ci uint32_t (*get_pixel_offset)(uint32_t cpp, 262bf215546Sopenharmony_ci uint32_t image_h, 263bf215546Sopenharmony_ci uint32_t x, uint32_t y), 264bf215546Sopenharmony_ci bool is_load) 265bf215546Sopenharmony_ci{ 266bf215546Sopenharmony_ci uint32_t utile_w = v3d_utile_width(cpp); 267bf215546Sopenharmony_ci uint32_t utile_h = v3d_utile_height(cpp); 268bf215546Sopenharmony_ci uint32_t utile_gpu_stride = utile_w * cpp; 269bf215546Sopenharmony_ci uint32_t x1 = box->x; 270bf215546Sopenharmony_ci uint32_t y1 = box->y; 271bf215546Sopenharmony_ci uint32_t x2 = box->x + box->width; 272bf215546Sopenharmony_ci uint32_t y2 = box->y + box->height; 273bf215546Sopenharmony_ci uint32_t align_x1 = align(x1, utile_w); 274bf215546Sopenharmony_ci uint32_t align_y1 = align(y1, utile_h); 275bf215546Sopenharmony_ci uint32_t align_x2 = x2 & ~(utile_w - 1); 276bf215546Sopenharmony_ci uint32_t align_y2 = y2 & ~(utile_h - 1); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci /* Load/store all the whole utiles first. */ 279bf215546Sopenharmony_ci for (uint32_t y = align_y1; y < align_y2; y += utile_h) { 280bf215546Sopenharmony_ci void *cpu_row = cpu + (y - box->y) * cpu_stride; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci for (uint32_t x = align_x1; x < align_x2; x += utile_w) { 283bf215546Sopenharmony_ci void *utile_gpu = (gpu + 284bf215546Sopenharmony_ci get_pixel_offset(cpp, image_h, x, y)); 285bf215546Sopenharmony_ci void *utile_cpu = cpu_row + (x - box->x) * cpp; 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (is_load) { 288bf215546Sopenharmony_ci v3d_load_utile(utile_cpu, cpu_stride, 289bf215546Sopenharmony_ci utile_gpu, utile_gpu_stride); 290bf215546Sopenharmony_ci } else { 291bf215546Sopenharmony_ci v3d_store_utile(utile_gpu, utile_gpu_stride, 292bf215546Sopenharmony_ci utile_cpu, cpu_stride); 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci /* If there were no aligned utiles in the middle, load/store the whole 298bf215546Sopenharmony_ci * thing unaligned. 299bf215546Sopenharmony_ci */ 300bf215546Sopenharmony_ci if (align_y2 <= align_y1 || 301bf215546Sopenharmony_ci align_x2 <= align_x1) { 302bf215546Sopenharmony_ci v3d_move_pixels_unaligned(gpu, gpu_stride, 303bf215546Sopenharmony_ci cpu, cpu_stride, 304bf215546Sopenharmony_ci cpp, image_h, 305bf215546Sopenharmony_ci box, 306bf215546Sopenharmony_ci get_pixel_offset, is_load); 307bf215546Sopenharmony_ci return; 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci /* Load/store the partial utiles. */ 311bf215546Sopenharmony_ci struct pipe_box partial_boxes[4] = { 312bf215546Sopenharmony_ci /* Top */ 313bf215546Sopenharmony_ci { 314bf215546Sopenharmony_ci .x = x1, 315bf215546Sopenharmony_ci .width = x2 - x1, 316bf215546Sopenharmony_ci .y = y1, 317bf215546Sopenharmony_ci .height = align_y1 - y1, 318bf215546Sopenharmony_ci }, 319bf215546Sopenharmony_ci /* Bottom */ 320bf215546Sopenharmony_ci { 321bf215546Sopenharmony_ci .x = x1, 322bf215546Sopenharmony_ci .width = x2 - x1, 323bf215546Sopenharmony_ci .y = align_y2, 324bf215546Sopenharmony_ci .height = y2 - align_y2, 325bf215546Sopenharmony_ci }, 326bf215546Sopenharmony_ci /* Left */ 327bf215546Sopenharmony_ci { 328bf215546Sopenharmony_ci .x = x1, 329bf215546Sopenharmony_ci .width = align_x1 - x1, 330bf215546Sopenharmony_ci .y = align_y1, 331bf215546Sopenharmony_ci .height = align_y2 - align_y1, 332bf215546Sopenharmony_ci }, 333bf215546Sopenharmony_ci /* Right */ 334bf215546Sopenharmony_ci { 335bf215546Sopenharmony_ci .x = align_x2, 336bf215546Sopenharmony_ci .width = x2 - align_x2, 337bf215546Sopenharmony_ci .y = align_y1, 338bf215546Sopenharmony_ci .height = align_y2 - align_y1, 339bf215546Sopenharmony_ci }, 340bf215546Sopenharmony_ci }; 341bf215546Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(partial_boxes); i++) { 342bf215546Sopenharmony_ci void *partial_cpu = (cpu + 343bf215546Sopenharmony_ci (partial_boxes[i].y - y1) * cpu_stride + 344bf215546Sopenharmony_ci (partial_boxes[i].x - x1) * cpp); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci v3d_move_pixels_unaligned(gpu, gpu_stride, 347bf215546Sopenharmony_ci partial_cpu, cpu_stride, 348bf215546Sopenharmony_ci cpp, image_h, 349bf215546Sopenharmony_ci &partial_boxes[i], 350bf215546Sopenharmony_ci get_pixel_offset, is_load); 351bf215546Sopenharmony_ci } 352bf215546Sopenharmony_ci} 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_cistatic inline void 355bf215546Sopenharmony_civ3d_move_pixels_general(void *gpu, uint32_t gpu_stride, 356bf215546Sopenharmony_ci void *cpu, uint32_t cpu_stride, 357bf215546Sopenharmony_ci int cpp, uint32_t image_h, 358bf215546Sopenharmony_ci const struct pipe_box *box, 359bf215546Sopenharmony_ci uint32_t (*get_pixel_offset)(uint32_t cpp, 360bf215546Sopenharmony_ci uint32_t image_h, 361bf215546Sopenharmony_ci uint32_t x, uint32_t y), 362bf215546Sopenharmony_ci bool is_load) 363bf215546Sopenharmony_ci{ 364bf215546Sopenharmony_ci switch (cpp) { 365bf215546Sopenharmony_ci case 1: 366bf215546Sopenharmony_ci v3d_move_pixels_general_percpp(gpu, gpu_stride, 367bf215546Sopenharmony_ci cpu, cpu_stride, 368bf215546Sopenharmony_ci 1, image_h, box, 369bf215546Sopenharmony_ci get_pixel_offset, 370bf215546Sopenharmony_ci is_load); 371bf215546Sopenharmony_ci break; 372bf215546Sopenharmony_ci case 2: 373bf215546Sopenharmony_ci v3d_move_pixels_general_percpp(gpu, gpu_stride, 374bf215546Sopenharmony_ci cpu, cpu_stride, 375bf215546Sopenharmony_ci 2, image_h, box, 376bf215546Sopenharmony_ci get_pixel_offset, 377bf215546Sopenharmony_ci is_load); 378bf215546Sopenharmony_ci break; 379bf215546Sopenharmony_ci case 4: 380bf215546Sopenharmony_ci v3d_move_pixels_general_percpp(gpu, gpu_stride, 381bf215546Sopenharmony_ci cpu, cpu_stride, 382bf215546Sopenharmony_ci 4, image_h, box, 383bf215546Sopenharmony_ci get_pixel_offset, 384bf215546Sopenharmony_ci is_load); 385bf215546Sopenharmony_ci break; 386bf215546Sopenharmony_ci case 8: 387bf215546Sopenharmony_ci v3d_move_pixels_general_percpp(gpu, gpu_stride, 388bf215546Sopenharmony_ci cpu, cpu_stride, 389bf215546Sopenharmony_ci 8, image_h, box, 390bf215546Sopenharmony_ci get_pixel_offset, 391bf215546Sopenharmony_ci is_load); 392bf215546Sopenharmony_ci break; 393bf215546Sopenharmony_ci case 16: 394bf215546Sopenharmony_ci v3d_move_pixels_general_percpp(gpu, gpu_stride, 395bf215546Sopenharmony_ci cpu, cpu_stride, 396bf215546Sopenharmony_ci 16, image_h, box, 397bf215546Sopenharmony_ci get_pixel_offset, 398bf215546Sopenharmony_ci is_load); 399bf215546Sopenharmony_ci break; 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci} 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_cistatic inline void 404bf215546Sopenharmony_civ3d_move_tiled_image(void *gpu, uint32_t gpu_stride, 405bf215546Sopenharmony_ci void *cpu, uint32_t cpu_stride, 406bf215546Sopenharmony_ci enum v3d_tiling_mode tiling_format, 407bf215546Sopenharmony_ci int cpp, 408bf215546Sopenharmony_ci uint32_t image_h, 409bf215546Sopenharmony_ci const struct pipe_box *box, 410bf215546Sopenharmony_ci bool is_load) 411bf215546Sopenharmony_ci{ 412bf215546Sopenharmony_ci switch (tiling_format) { 413bf215546Sopenharmony_ci case V3D_TILING_UIF_XOR: 414bf215546Sopenharmony_ci v3d_move_pixels_general(gpu, gpu_stride, 415bf215546Sopenharmony_ci cpu, cpu_stride, 416bf215546Sopenharmony_ci cpp, image_h, box, 417bf215546Sopenharmony_ci v3d_get_uif_xor_pixel_offset, 418bf215546Sopenharmony_ci is_load); 419bf215546Sopenharmony_ci break; 420bf215546Sopenharmony_ci case V3D_TILING_UIF_NO_XOR: 421bf215546Sopenharmony_ci v3d_move_pixels_general(gpu, gpu_stride, 422bf215546Sopenharmony_ci cpu, cpu_stride, 423bf215546Sopenharmony_ci cpp, image_h, box, 424bf215546Sopenharmony_ci v3d_get_uif_no_xor_pixel_offset, 425bf215546Sopenharmony_ci is_load); 426bf215546Sopenharmony_ci break; 427bf215546Sopenharmony_ci case V3D_TILING_UBLINEAR_2_COLUMN: 428bf215546Sopenharmony_ci v3d_move_pixels_general(gpu, gpu_stride, 429bf215546Sopenharmony_ci cpu, cpu_stride, 430bf215546Sopenharmony_ci cpp, image_h, box, 431bf215546Sopenharmony_ci v3d_get_ublinear_2_column_pixel_offset, 432bf215546Sopenharmony_ci is_load); 433bf215546Sopenharmony_ci break; 434bf215546Sopenharmony_ci case V3D_TILING_UBLINEAR_1_COLUMN: 435bf215546Sopenharmony_ci v3d_move_pixels_general(gpu, gpu_stride, 436bf215546Sopenharmony_ci cpu, cpu_stride, 437bf215546Sopenharmony_ci cpp, image_h, box, 438bf215546Sopenharmony_ci v3d_get_ublinear_1_column_pixel_offset, 439bf215546Sopenharmony_ci is_load); 440bf215546Sopenharmony_ci break; 441bf215546Sopenharmony_ci case V3D_TILING_LINEARTILE: 442bf215546Sopenharmony_ci v3d_move_pixels_general(gpu, gpu_stride, 443bf215546Sopenharmony_ci cpu, cpu_stride, 444bf215546Sopenharmony_ci cpp, image_h, box, 445bf215546Sopenharmony_ci v3d_get_lt_pixel_offset, 446bf215546Sopenharmony_ci is_load); 447bf215546Sopenharmony_ci break; 448bf215546Sopenharmony_ci default: 449bf215546Sopenharmony_ci unreachable("Unsupported tiling format"); 450bf215546Sopenharmony_ci break; 451bf215546Sopenharmony_ci } 452bf215546Sopenharmony_ci} 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci/** 455bf215546Sopenharmony_ci * Loads pixel data from the start (microtile-aligned) box in \p src to the 456bf215546Sopenharmony_ci * start of \p dst according to the given tiling format. 457bf215546Sopenharmony_ci */ 458bf215546Sopenharmony_civoid 459bf215546Sopenharmony_civ3d_load_tiled_image(void *dst, uint32_t dst_stride, 460bf215546Sopenharmony_ci void *src, uint32_t src_stride, 461bf215546Sopenharmony_ci enum v3d_tiling_mode tiling_format, int cpp, 462bf215546Sopenharmony_ci uint32_t image_h, 463bf215546Sopenharmony_ci const struct pipe_box *box) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci v3d_move_tiled_image(src, src_stride, 466bf215546Sopenharmony_ci dst, dst_stride, 467bf215546Sopenharmony_ci tiling_format, 468bf215546Sopenharmony_ci cpp, 469bf215546Sopenharmony_ci image_h, 470bf215546Sopenharmony_ci box, 471bf215546Sopenharmony_ci true); 472bf215546Sopenharmony_ci} 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci/** 475bf215546Sopenharmony_ci * Stores pixel data from the start of \p src into a (microtile-aligned) box in 476bf215546Sopenharmony_ci * \p dst according to the given tiling format. 477bf215546Sopenharmony_ci */ 478bf215546Sopenharmony_civoid 479bf215546Sopenharmony_civ3d_store_tiled_image(void *dst, uint32_t dst_stride, 480bf215546Sopenharmony_ci void *src, uint32_t src_stride, 481bf215546Sopenharmony_ci enum v3d_tiling_mode tiling_format, int cpp, 482bf215546Sopenharmony_ci uint32_t image_h, 483bf215546Sopenharmony_ci const struct pipe_box *box) 484bf215546Sopenharmony_ci{ 485bf215546Sopenharmony_ci v3d_move_tiled_image(dst, dst_stride, 486bf215546Sopenharmony_ci src, src_stride, 487bf215546Sopenharmony_ci tiling_format, 488bf215546Sopenharmony_ci cpp, 489bf215546Sopenharmony_ci image_h, 490bf215546Sopenharmony_ci box, 491bf215546Sopenharmony_ci false); 492bf215546Sopenharmony_ci} 493