17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2014-2017 Broadcom 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 217ec681f3Smrg * IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg/** @file v3d_tiling.c 257ec681f3Smrg * 267ec681f3Smrg * Handles information about the V3D tiling formats, and loading and storing 277ec681f3Smrg * from them. 287ec681f3Smrg */ 297ec681f3Smrg 307ec681f3Smrg#include <stdint.h> 317ec681f3Smrg#include "v3d_tiling.h" 327ec681f3Smrg#include "broadcom/common/v3d_cpu_tiling.h" 337ec681f3Smrg 347ec681f3Smrg/** Return the width in pixels of a 64-byte microtile. */ 357ec681f3Smrguint32_t 367ec681f3Smrgv3d_utile_width(int cpp) 377ec681f3Smrg{ 387ec681f3Smrg switch (cpp) { 397ec681f3Smrg case 1: 407ec681f3Smrg case 2: 417ec681f3Smrg return 8; 427ec681f3Smrg case 4: 437ec681f3Smrg case 8: 447ec681f3Smrg return 4; 457ec681f3Smrg case 16: 467ec681f3Smrg return 2; 477ec681f3Smrg default: 487ec681f3Smrg unreachable("unknown cpp"); 497ec681f3Smrg } 507ec681f3Smrg} 517ec681f3Smrg 527ec681f3Smrg/** Return the height in pixels of a 64-byte microtile. */ 537ec681f3Smrguint32_t 547ec681f3Smrgv3d_utile_height(int cpp) 557ec681f3Smrg{ 567ec681f3Smrg switch (cpp) { 577ec681f3Smrg case 1: 587ec681f3Smrg return 8; 597ec681f3Smrg case 2: 607ec681f3Smrg case 4: 617ec681f3Smrg return 4; 627ec681f3Smrg case 8: 637ec681f3Smrg case 16: 647ec681f3Smrg return 2; 657ec681f3Smrg default: 667ec681f3Smrg unreachable("unknown cpp"); 677ec681f3Smrg } 687ec681f3Smrg} 697ec681f3Smrg 707ec681f3Smrg/** 717ec681f3Smrg * Returns the byte address for a given pixel within a utile. 727ec681f3Smrg * 737ec681f3Smrg * Utiles are 64b blocks of pixels in raster order, with 32bpp being a 4x4 747ec681f3Smrg * arrangement. 757ec681f3Smrg */ 767ec681f3Smrgstatic inline uint32_t 777ec681f3Smrgv3d_get_utile_pixel_offset(uint32_t cpp, uint32_t x, uint32_t y) 787ec681f3Smrg{ 797ec681f3Smrg uint32_t utile_w = v3d_utile_width(cpp); 807ec681f3Smrg 817ec681f3Smrg assert(x < utile_w && y < v3d_utile_height(cpp)); 827ec681f3Smrg 837ec681f3Smrg return x * cpp + y * utile_w * cpp; 847ec681f3Smrg} 857ec681f3Smrg 867ec681f3Smrg/** 877ec681f3Smrg * Returns the byte offset for a given pixel in a LINEARTILE layout. 887ec681f3Smrg * 897ec681f3Smrg * LINEARTILE is a single line of utiles in either the X or Y direction. 907ec681f3Smrg */ 917ec681f3Smrgstatic inline uint32_t 927ec681f3Smrgv3d_get_lt_pixel_offset(uint32_t cpp, uint32_t image_h, uint32_t x, uint32_t y) 937ec681f3Smrg{ 947ec681f3Smrg uint32_t utile_w = v3d_utile_width(cpp); 957ec681f3Smrg uint32_t utile_h = v3d_utile_height(cpp); 967ec681f3Smrg uint32_t utile_index_x = x / utile_w; 977ec681f3Smrg uint32_t utile_index_y = y / utile_h; 987ec681f3Smrg 997ec681f3Smrg assert(utile_index_x == 0 || utile_index_y == 0); 1007ec681f3Smrg 1017ec681f3Smrg return (64 * (utile_index_x + utile_index_y) + 1027ec681f3Smrg v3d_get_utile_pixel_offset(cpp, 1037ec681f3Smrg x & (utile_w - 1), 1047ec681f3Smrg y & (utile_h - 1))); 1057ec681f3Smrg} 1067ec681f3Smrg 1077ec681f3Smrg/** 1087ec681f3Smrg * Returns the byte offset for a given pixel in a UBLINEAR layout. 1097ec681f3Smrg * 1107ec681f3Smrg * UBLINEAR is the layout where pixels are arranged in UIF blocks (2x2 1117ec681f3Smrg * utiles), and the UIF blocks are in 1 or 2 columns in raster order. 1127ec681f3Smrg */ 1137ec681f3Smrgstatic inline uint32_t 1147ec681f3Smrgv3d_get_ublinear_pixel_offset(uint32_t cpp, uint32_t x, uint32_t y, 1157ec681f3Smrg int ublinear_number) 1167ec681f3Smrg{ 1177ec681f3Smrg uint32_t utile_w = v3d_utile_width(cpp); 1187ec681f3Smrg uint32_t utile_h = v3d_utile_height(cpp); 1197ec681f3Smrg uint32_t ub_w = utile_w * 2; 1207ec681f3Smrg uint32_t ub_h = utile_h * 2; 1217ec681f3Smrg uint32_t ub_x = x / ub_w; 1227ec681f3Smrg uint32_t ub_y = y / ub_h; 1237ec681f3Smrg 1247ec681f3Smrg return (256 * (ub_y * ublinear_number + 1257ec681f3Smrg ub_x) + 1267ec681f3Smrg ((x & utile_w) ? 64 : 0) + 1277ec681f3Smrg ((y & utile_h) ? 128 : 0) + 1287ec681f3Smrg + v3d_get_utile_pixel_offset(cpp, 1297ec681f3Smrg x & (utile_w - 1), 1307ec681f3Smrg y & (utile_h - 1))); 1317ec681f3Smrg} 1327ec681f3Smrg 1337ec681f3Smrgstatic inline uint32_t 1347ec681f3Smrgv3d_get_ublinear_2_column_pixel_offset(uint32_t cpp, uint32_t image_h, 1357ec681f3Smrg uint32_t x, uint32_t y) 1367ec681f3Smrg{ 1377ec681f3Smrg return v3d_get_ublinear_pixel_offset(cpp, x, y, 2); 1387ec681f3Smrg} 1397ec681f3Smrg 1407ec681f3Smrgstatic inline uint32_t 1417ec681f3Smrgv3d_get_ublinear_1_column_pixel_offset(uint32_t cpp, uint32_t image_h, 1427ec681f3Smrg uint32_t x, uint32_t y) 1437ec681f3Smrg{ 1447ec681f3Smrg return v3d_get_ublinear_pixel_offset(cpp, x, y, 1); 1457ec681f3Smrg} 1467ec681f3Smrg 1477ec681f3Smrg/** 1487ec681f3Smrg * Returns the byte offset for a given pixel in a UIF layout. 1497ec681f3Smrg * 1507ec681f3Smrg * UIF is the general V3D tiling layout shared across 3D, media, and scanout. 1517ec681f3Smrg * It stores pixels in UIF blocks (2x2 utiles), and UIF blocks are stored in 1527ec681f3Smrg * 4x4 groups, and those 4x4 groups are then stored in raster order. 1537ec681f3Smrg */ 1547ec681f3Smrgstatic inline uint32_t 1557ec681f3Smrgv3d_get_uif_pixel_offset(uint32_t cpp, uint32_t image_h, uint32_t x, uint32_t y, 1567ec681f3Smrg bool do_xor) 1577ec681f3Smrg{ 1587ec681f3Smrg uint32_t utile_w = v3d_utile_width(cpp); 1597ec681f3Smrg uint32_t utile_h = v3d_utile_height(cpp); 1607ec681f3Smrg uint32_t mb_width = utile_w * 2; 1617ec681f3Smrg uint32_t mb_height = utile_h * 2; 1627ec681f3Smrg uint32_t log2_mb_width = ffs(mb_width) - 1; 1637ec681f3Smrg uint32_t log2_mb_height = ffs(mb_height) - 1; 1647ec681f3Smrg 1657ec681f3Smrg /* Macroblock X, y */ 1667ec681f3Smrg uint32_t mb_x = x >> log2_mb_width; 1677ec681f3Smrg uint32_t mb_y = y >> log2_mb_height; 1687ec681f3Smrg /* X, y within the macroblock */ 1697ec681f3Smrg uint32_t mb_pixel_x = x - (mb_x << log2_mb_width); 1707ec681f3Smrg uint32_t mb_pixel_y = y - (mb_y << log2_mb_height); 1717ec681f3Smrg 1727ec681f3Smrg if (do_xor && (mb_x / 4) & 1) 1737ec681f3Smrg mb_y ^= 0x10; 1747ec681f3Smrg 1757ec681f3Smrg uint32_t mb_h = align(image_h, 1 << log2_mb_height) >> log2_mb_height; 1767ec681f3Smrg uint32_t mb_id = ((mb_x / 4) * ((mb_h - 1) * 4)) + mb_x + mb_y * 4; 1777ec681f3Smrg 1787ec681f3Smrg uint32_t mb_base_addr = mb_id * 256; 1797ec681f3Smrg 1807ec681f3Smrg bool top = mb_pixel_y < utile_h; 1817ec681f3Smrg bool left = mb_pixel_x < utile_w; 1827ec681f3Smrg 1837ec681f3Smrg /* Docs have this in pixels, we do bytes here. */ 1847ec681f3Smrg uint32_t mb_tile_offset = (!top * 128 + !left * 64); 1857ec681f3Smrg 1867ec681f3Smrg uint32_t utile_x = mb_pixel_x & (utile_w - 1); 1877ec681f3Smrg uint32_t utile_y = mb_pixel_y & (utile_h - 1); 1887ec681f3Smrg 1897ec681f3Smrg uint32_t mb_pixel_address = (mb_base_addr + 1907ec681f3Smrg mb_tile_offset + 1917ec681f3Smrg v3d_get_utile_pixel_offset(cpp, 1927ec681f3Smrg utile_x, 1937ec681f3Smrg utile_y)); 1947ec681f3Smrg 1957ec681f3Smrg return mb_pixel_address; 1967ec681f3Smrg} 1977ec681f3Smrg 1987ec681f3Smrgstatic inline uint32_t 1997ec681f3Smrgv3d_get_uif_xor_pixel_offset(uint32_t cpp, uint32_t image_h, 2007ec681f3Smrg uint32_t x, uint32_t y) 2017ec681f3Smrg{ 2027ec681f3Smrg return v3d_get_uif_pixel_offset(cpp, image_h, x, y, true); 2037ec681f3Smrg} 2047ec681f3Smrg 2057ec681f3Smrgstatic inline uint32_t 2067ec681f3Smrgv3d_get_uif_no_xor_pixel_offset(uint32_t cpp, uint32_t image_h, 2077ec681f3Smrg uint32_t x, uint32_t y) 2087ec681f3Smrg{ 2097ec681f3Smrg return v3d_get_uif_pixel_offset(cpp, image_h, x, y, false); 2107ec681f3Smrg} 2117ec681f3Smrg 2127ec681f3Smrg/* Loads/stores non-utile-aligned boxes by walking over the destination 2137ec681f3Smrg * rectangle, computing the address on the GPU, and storing/loading a pixel at 2147ec681f3Smrg * a time. 2157ec681f3Smrg */ 2167ec681f3Smrgstatic inline void 2177ec681f3Smrgv3d_move_pixels_unaligned(void *gpu, uint32_t gpu_stride, 2187ec681f3Smrg void *cpu, uint32_t cpu_stride, 2197ec681f3Smrg int cpp, uint32_t image_h, 2207ec681f3Smrg const struct pipe_box *box, 2217ec681f3Smrg uint32_t (*get_pixel_offset)(uint32_t cpp, 2227ec681f3Smrg uint32_t image_h, 2237ec681f3Smrg uint32_t x, uint32_t y), 2247ec681f3Smrg bool is_load) 2257ec681f3Smrg{ 2267ec681f3Smrg for (uint32_t y = 0; y < box->height; y++) { 2277ec681f3Smrg void *cpu_row = cpu + y * cpu_stride; 2287ec681f3Smrg 2297ec681f3Smrg for (int x = 0; x < box->width; x++) { 2307ec681f3Smrg uint32_t pixel_offset = get_pixel_offset(cpp, image_h, 2317ec681f3Smrg box->x + x, 2327ec681f3Smrg box->y + y); 2337ec681f3Smrg 2347ec681f3Smrg if (false) { 2357ec681f3Smrg fprintf(stderr, "%3d,%3d -> %d\n", 2367ec681f3Smrg box->x + x, box->y + y, 2377ec681f3Smrg pixel_offset); 2387ec681f3Smrg } 2397ec681f3Smrg 2407ec681f3Smrg if (is_load) { 2417ec681f3Smrg memcpy(cpu_row + x * cpp, 2427ec681f3Smrg gpu + pixel_offset, 2437ec681f3Smrg cpp); 2447ec681f3Smrg } else { 2457ec681f3Smrg memcpy(gpu + pixel_offset, 2467ec681f3Smrg cpu_row + x * cpp, 2477ec681f3Smrg cpp); 2487ec681f3Smrg } 2497ec681f3Smrg } 2507ec681f3Smrg } 2517ec681f3Smrg} 2527ec681f3Smrg 2537ec681f3Smrg/* Breaks the image down into utiles and calls either the fast whole-utile 2547ec681f3Smrg * load/store functions, or the unaligned fallback case. 2557ec681f3Smrg */ 2567ec681f3Smrgstatic inline void 2577ec681f3Smrgv3d_move_pixels_general_percpp(void *gpu, uint32_t gpu_stride, 2587ec681f3Smrg void *cpu, uint32_t cpu_stride, 2597ec681f3Smrg int cpp, uint32_t image_h, 2607ec681f3Smrg const struct pipe_box *box, 2617ec681f3Smrg uint32_t (*get_pixel_offset)(uint32_t cpp, 2627ec681f3Smrg uint32_t image_h, 2637ec681f3Smrg uint32_t x, uint32_t y), 2647ec681f3Smrg bool is_load) 2657ec681f3Smrg{ 2667ec681f3Smrg uint32_t utile_w = v3d_utile_width(cpp); 2677ec681f3Smrg uint32_t utile_h = v3d_utile_height(cpp); 2687ec681f3Smrg uint32_t utile_gpu_stride = utile_w * cpp; 2697ec681f3Smrg uint32_t x1 = box->x; 2707ec681f3Smrg uint32_t y1 = box->y; 2717ec681f3Smrg uint32_t x2 = box->x + box->width; 2727ec681f3Smrg uint32_t y2 = box->y + box->height; 2737ec681f3Smrg uint32_t align_x1 = align(x1, utile_w); 2747ec681f3Smrg uint32_t align_y1 = align(y1, utile_h); 2757ec681f3Smrg uint32_t align_x2 = x2 & ~(utile_w - 1); 2767ec681f3Smrg uint32_t align_y2 = y2 & ~(utile_h - 1); 2777ec681f3Smrg 2787ec681f3Smrg /* Load/store all the whole utiles first. */ 2797ec681f3Smrg for (uint32_t y = align_y1; y < align_y2; y += utile_h) { 2807ec681f3Smrg void *cpu_row = cpu + (y - box->y) * cpu_stride; 2817ec681f3Smrg 2827ec681f3Smrg for (uint32_t x = align_x1; x < align_x2; x += utile_w) { 2837ec681f3Smrg void *utile_gpu = (gpu + 2847ec681f3Smrg get_pixel_offset(cpp, image_h, x, y)); 2857ec681f3Smrg void *utile_cpu = cpu_row + (x - box->x) * cpp; 2867ec681f3Smrg 2877ec681f3Smrg if (is_load) { 2887ec681f3Smrg v3d_load_utile(utile_cpu, cpu_stride, 2897ec681f3Smrg utile_gpu, utile_gpu_stride); 2907ec681f3Smrg } else { 2917ec681f3Smrg v3d_store_utile(utile_gpu, utile_gpu_stride, 2927ec681f3Smrg utile_cpu, cpu_stride); 2937ec681f3Smrg } 2947ec681f3Smrg } 2957ec681f3Smrg } 2967ec681f3Smrg 2977ec681f3Smrg /* If there were no aligned utiles in the middle, load/store the whole 2987ec681f3Smrg * thing unaligned. 2997ec681f3Smrg */ 3007ec681f3Smrg if (align_y2 <= align_y1 || 3017ec681f3Smrg align_x2 <= align_x1) { 3027ec681f3Smrg v3d_move_pixels_unaligned(gpu, gpu_stride, 3037ec681f3Smrg cpu, cpu_stride, 3047ec681f3Smrg cpp, image_h, 3057ec681f3Smrg box, 3067ec681f3Smrg get_pixel_offset, is_load); 3077ec681f3Smrg return; 3087ec681f3Smrg } 3097ec681f3Smrg 3107ec681f3Smrg /* Load/store the partial utiles. */ 3117ec681f3Smrg struct pipe_box partial_boxes[4] = { 3127ec681f3Smrg /* Top */ 3137ec681f3Smrg { 3147ec681f3Smrg .x = x1, 3157ec681f3Smrg .width = x2 - x1, 3167ec681f3Smrg .y = y1, 3177ec681f3Smrg .height = align_y1 - y1, 3187ec681f3Smrg }, 3197ec681f3Smrg /* Bottom */ 3207ec681f3Smrg { 3217ec681f3Smrg .x = x1, 3227ec681f3Smrg .width = x2 - x1, 3237ec681f3Smrg .y = align_y2, 3247ec681f3Smrg .height = y2 - align_y2, 3257ec681f3Smrg }, 3267ec681f3Smrg /* Left */ 3277ec681f3Smrg { 3287ec681f3Smrg .x = x1, 3297ec681f3Smrg .width = align_x1 - x1, 3307ec681f3Smrg .y = align_y1, 3317ec681f3Smrg .height = align_y2 - align_y1, 3327ec681f3Smrg }, 3337ec681f3Smrg /* Right */ 3347ec681f3Smrg { 3357ec681f3Smrg .x = align_x2, 3367ec681f3Smrg .width = x2 - align_x2, 3377ec681f3Smrg .y = align_y1, 3387ec681f3Smrg .height = align_y2 - align_y1, 3397ec681f3Smrg }, 3407ec681f3Smrg }; 3417ec681f3Smrg for (int i = 0; i < ARRAY_SIZE(partial_boxes); i++) { 3427ec681f3Smrg void *partial_cpu = (cpu + 3437ec681f3Smrg (partial_boxes[i].y - y1) * cpu_stride + 3447ec681f3Smrg (partial_boxes[i].x - x1) * cpp); 3457ec681f3Smrg 3467ec681f3Smrg v3d_move_pixels_unaligned(gpu, gpu_stride, 3477ec681f3Smrg partial_cpu, cpu_stride, 3487ec681f3Smrg cpp, image_h, 3497ec681f3Smrg &partial_boxes[i], 3507ec681f3Smrg get_pixel_offset, is_load); 3517ec681f3Smrg } 3527ec681f3Smrg} 3537ec681f3Smrg 3547ec681f3Smrgstatic inline void 3557ec681f3Smrgv3d_move_pixels_general(void *gpu, uint32_t gpu_stride, 3567ec681f3Smrg void *cpu, uint32_t cpu_stride, 3577ec681f3Smrg int cpp, uint32_t image_h, 3587ec681f3Smrg const struct pipe_box *box, 3597ec681f3Smrg uint32_t (*get_pixel_offset)(uint32_t cpp, 3607ec681f3Smrg uint32_t image_h, 3617ec681f3Smrg uint32_t x, uint32_t y), 3627ec681f3Smrg bool is_load) 3637ec681f3Smrg{ 3647ec681f3Smrg switch (cpp) { 3657ec681f3Smrg case 1: 3667ec681f3Smrg v3d_move_pixels_general_percpp(gpu, gpu_stride, 3677ec681f3Smrg cpu, cpu_stride, 3687ec681f3Smrg 1, image_h, box, 3697ec681f3Smrg get_pixel_offset, 3707ec681f3Smrg is_load); 3717ec681f3Smrg break; 3727ec681f3Smrg case 2: 3737ec681f3Smrg v3d_move_pixels_general_percpp(gpu, gpu_stride, 3747ec681f3Smrg cpu, cpu_stride, 3757ec681f3Smrg 2, image_h, box, 3767ec681f3Smrg get_pixel_offset, 3777ec681f3Smrg is_load); 3787ec681f3Smrg break; 3797ec681f3Smrg case 4: 3807ec681f3Smrg v3d_move_pixels_general_percpp(gpu, gpu_stride, 3817ec681f3Smrg cpu, cpu_stride, 3827ec681f3Smrg 4, image_h, box, 3837ec681f3Smrg get_pixel_offset, 3847ec681f3Smrg is_load); 3857ec681f3Smrg break; 3867ec681f3Smrg case 8: 3877ec681f3Smrg v3d_move_pixels_general_percpp(gpu, gpu_stride, 3887ec681f3Smrg cpu, cpu_stride, 3897ec681f3Smrg 8, image_h, box, 3907ec681f3Smrg get_pixel_offset, 3917ec681f3Smrg is_load); 3927ec681f3Smrg break; 3937ec681f3Smrg case 16: 3947ec681f3Smrg v3d_move_pixels_general_percpp(gpu, gpu_stride, 3957ec681f3Smrg cpu, cpu_stride, 3967ec681f3Smrg 16, image_h, box, 3977ec681f3Smrg get_pixel_offset, 3987ec681f3Smrg is_load); 3997ec681f3Smrg break; 4007ec681f3Smrg } 4017ec681f3Smrg} 4027ec681f3Smrg 4037ec681f3Smrgstatic inline void 4047ec681f3Smrgv3d_move_tiled_image(void *gpu, uint32_t gpu_stride, 4057ec681f3Smrg void *cpu, uint32_t cpu_stride, 4067ec681f3Smrg enum v3d_tiling_mode tiling_format, 4077ec681f3Smrg int cpp, 4087ec681f3Smrg uint32_t image_h, 4097ec681f3Smrg const struct pipe_box *box, 4107ec681f3Smrg bool is_load) 4117ec681f3Smrg{ 4127ec681f3Smrg switch (tiling_format) { 4137ec681f3Smrg case V3D_TILING_UIF_XOR: 4147ec681f3Smrg v3d_move_pixels_general(gpu, gpu_stride, 4157ec681f3Smrg cpu, cpu_stride, 4167ec681f3Smrg cpp, image_h, box, 4177ec681f3Smrg v3d_get_uif_xor_pixel_offset, 4187ec681f3Smrg is_load); 4197ec681f3Smrg break; 4207ec681f3Smrg case V3D_TILING_UIF_NO_XOR: 4217ec681f3Smrg v3d_move_pixels_general(gpu, gpu_stride, 4227ec681f3Smrg cpu, cpu_stride, 4237ec681f3Smrg cpp, image_h, box, 4247ec681f3Smrg v3d_get_uif_no_xor_pixel_offset, 4257ec681f3Smrg is_load); 4267ec681f3Smrg break; 4277ec681f3Smrg case V3D_TILING_UBLINEAR_2_COLUMN: 4287ec681f3Smrg v3d_move_pixels_general(gpu, gpu_stride, 4297ec681f3Smrg cpu, cpu_stride, 4307ec681f3Smrg cpp, image_h, box, 4317ec681f3Smrg v3d_get_ublinear_2_column_pixel_offset, 4327ec681f3Smrg is_load); 4337ec681f3Smrg break; 4347ec681f3Smrg case V3D_TILING_UBLINEAR_1_COLUMN: 4357ec681f3Smrg v3d_move_pixels_general(gpu, gpu_stride, 4367ec681f3Smrg cpu, cpu_stride, 4377ec681f3Smrg cpp, image_h, box, 4387ec681f3Smrg v3d_get_ublinear_1_column_pixel_offset, 4397ec681f3Smrg is_load); 4407ec681f3Smrg break; 4417ec681f3Smrg case V3D_TILING_LINEARTILE: 4427ec681f3Smrg v3d_move_pixels_general(gpu, gpu_stride, 4437ec681f3Smrg cpu, cpu_stride, 4447ec681f3Smrg cpp, image_h, box, 4457ec681f3Smrg v3d_get_lt_pixel_offset, 4467ec681f3Smrg is_load); 4477ec681f3Smrg break; 4487ec681f3Smrg default: 4497ec681f3Smrg unreachable("Unsupported tiling format"); 4507ec681f3Smrg break; 4517ec681f3Smrg } 4527ec681f3Smrg} 4537ec681f3Smrg 4547ec681f3Smrg/** 4557ec681f3Smrg * Loads pixel data from the start (microtile-aligned) box in \p src to the 4567ec681f3Smrg * start of \p dst according to the given tiling format. 4577ec681f3Smrg */ 4587ec681f3Smrgvoid 4597ec681f3Smrgv3d_load_tiled_image(void *dst, uint32_t dst_stride, 4607ec681f3Smrg void *src, uint32_t src_stride, 4617ec681f3Smrg enum v3d_tiling_mode tiling_format, int cpp, 4627ec681f3Smrg uint32_t image_h, 4637ec681f3Smrg const struct pipe_box *box) 4647ec681f3Smrg{ 4657ec681f3Smrg v3d_move_tiled_image(src, src_stride, 4667ec681f3Smrg dst, dst_stride, 4677ec681f3Smrg tiling_format, 4687ec681f3Smrg cpp, 4697ec681f3Smrg image_h, 4707ec681f3Smrg box, 4717ec681f3Smrg true); 4727ec681f3Smrg} 4737ec681f3Smrg 4747ec681f3Smrg/** 4757ec681f3Smrg * Stores pixel data from the start of \p src into a (microtile-aligned) box in 4767ec681f3Smrg * \p dst according to the given tiling format. 4777ec681f3Smrg */ 4787ec681f3Smrgvoid 4797ec681f3Smrgv3d_store_tiled_image(void *dst, uint32_t dst_stride, 4807ec681f3Smrg void *src, uint32_t src_stride, 4817ec681f3Smrg enum v3d_tiling_mode tiling_format, int cpp, 4827ec681f3Smrg uint32_t image_h, 4837ec681f3Smrg const struct pipe_box *box) 4847ec681f3Smrg{ 4857ec681f3Smrg v3d_move_tiled_image(dst, dst_stride, 4867ec681f3Smrg src, src_stride, 4877ec681f3Smrg tiling_format, 4887ec681f3Smrg cpp, 4897ec681f3Smrg image_h, 4907ec681f3Smrg box, 4917ec681f3Smrg false); 4927ec681f3Smrg} 493