1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2018 Intel Corporation 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 shall be included 12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci/* blt command encoding for gen4/5 */ 24bf215546Sopenharmony_ci#include "crocus_context.h" 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "crocus_genx_macros.h" 27bf215546Sopenharmony_ci#include "crocus_genx_protos.h" 28bf215546Sopenharmony_ci#include "crocus_resource.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#define FILE_DEBUG_FLAG DEBUG_BLIT 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#if GFX_VER <= 5 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_cistatic uint32_t 35bf215546Sopenharmony_cicolor_depth_for_cpp(int cpp) 36bf215546Sopenharmony_ci{ 37bf215546Sopenharmony_ci switch (cpp) { 38bf215546Sopenharmony_ci case 4: return COLOR_DEPTH_32bit; 39bf215546Sopenharmony_ci case 2: return COLOR_DEPTH_565; 40bf215546Sopenharmony_ci case 1: return COLOR_DEPTH_8bit; 41bf215546Sopenharmony_ci default: 42bf215546Sopenharmony_ci unreachable("not reached"); 43bf215546Sopenharmony_ci } 44bf215546Sopenharmony_ci} 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cistatic void 47bf215546Sopenharmony_ciblt_set_alpha_to_one(struct crocus_batch *batch, 48bf215546Sopenharmony_ci struct crocus_resource *dst, 49bf215546Sopenharmony_ci int x, int y, int width, int height) 50bf215546Sopenharmony_ci{ 51bf215546Sopenharmony_ci const struct isl_format_layout *fmtl = isl_format_get_layout(dst->surf.format); 52bf215546Sopenharmony_ci unsigned cpp = fmtl->bpb / 8; 53bf215546Sopenharmony_ci uint32_t pitch = dst->surf.row_pitch_B; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci if (dst->surf.tiling != ISL_TILING_LINEAR) 56bf215546Sopenharmony_ci pitch /= 4; 57bf215546Sopenharmony_ci /* We need to split the blit into chunks that each fit within the blitter's 58bf215546Sopenharmony_ci * restrictions. We can't use a chunk size of 32768 because we need to 59bf215546Sopenharmony_ci * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's 60bf215546Sopenharmony_ci * a nice round power of two, big enough that performance won't suffer, and 61bf215546Sopenharmony_ci * small enough to guarantee everything fits. 62bf215546Sopenharmony_ci */ 63bf215546Sopenharmony_ci const uint32_t max_chunk_size = 16384; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci for (uint32_t chunk_x = 0; chunk_x < width; chunk_x += max_chunk_size) { 66bf215546Sopenharmony_ci for (uint32_t chunk_y = 0; chunk_y < height; chunk_y += max_chunk_size) { 67bf215546Sopenharmony_ci const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x); 68bf215546Sopenharmony_ci const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); 69bf215546Sopenharmony_ci uint32_t tile_x, tile_y; 70bf215546Sopenharmony_ci uint64_t offset_B; 71bf215546Sopenharmony_ci ASSERTED uint32_t z_offset_el, array_offset; 72bf215546Sopenharmony_ci isl_tiling_get_intratile_offset_el(dst->surf.tiling, dst->surf.dim, 73bf215546Sopenharmony_ci dst->surf.msaa_layout, 74bf215546Sopenharmony_ci cpp * 8, dst->surf.samples, 75bf215546Sopenharmony_ci dst->surf.row_pitch_B, 76bf215546Sopenharmony_ci dst->surf.array_pitch_el_rows, 77bf215546Sopenharmony_ci chunk_x, chunk_y, 0, 0, 78bf215546Sopenharmony_ci &offset_B, 79bf215546Sopenharmony_ci &tile_x, &tile_y, 80bf215546Sopenharmony_ci &z_offset_el, &array_offset); 81bf215546Sopenharmony_ci assert(z_offset_el == 0); 82bf215546Sopenharmony_ci assert(array_offset == 0); 83bf215546Sopenharmony_ci crocus_emit_cmd(batch, GENX(XY_COLOR_BLT), xyblt) { 84bf215546Sopenharmony_ci xyblt.TilingEnable = dst->surf.tiling != ISL_TILING_LINEAR; 85bf215546Sopenharmony_ci xyblt.ColorDepth = color_depth_for_cpp(cpp); 86bf215546Sopenharmony_ci xyblt.RasterOperation = 0xF0; 87bf215546Sopenharmony_ci xyblt.DestinationPitch = pitch; 88bf215546Sopenharmony_ci xyblt._32bppByteMask = 2; 89bf215546Sopenharmony_ci xyblt.DestinationBaseAddress = rw_bo(dst->bo, offset_B); 90bf215546Sopenharmony_ci xyblt.DestinationX1Coordinate = tile_x; 91bf215546Sopenharmony_ci xyblt.DestinationY1Coordinate = tile_y; 92bf215546Sopenharmony_ci xyblt.DestinationX2Coordinate = tile_x + chunk_w; 93bf215546Sopenharmony_ci xyblt.DestinationY2Coordinate = tile_y + chunk_h; 94bf215546Sopenharmony_ci xyblt.SolidPatternColor = 0xffffffff; 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci } 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci} 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cistatic bool validate_blit_for_blt(struct crocus_batch *batch, 101bf215546Sopenharmony_ci const struct pipe_blit_info *info) 102bf215546Sopenharmony_ci{ 103bf215546Sopenharmony_ci /* If the source and destination are the same size with no mirroring, 104bf215546Sopenharmony_ci * the rectangles are within the size of the texture and there is no 105bf215546Sopenharmony_ci * scissor, then we can probably use the blit engine. 106bf215546Sopenharmony_ci */ 107bf215546Sopenharmony_ci if (info->dst.box.width != info->src.box.width || 108bf215546Sopenharmony_ci info->dst.box.height != info->src.box.height) 109bf215546Sopenharmony_ci return false; 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci if (info->scissor_enable) 112bf215546Sopenharmony_ci return false; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci if (info->dst.box.height < 0 || info->src.box.height < 0) 115bf215546Sopenharmony_ci return false; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci if (info->dst.box.depth > 1 || info->src.box.depth > 1) 118bf215546Sopenharmony_ci return false; 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci const struct util_format_description *desc = 121bf215546Sopenharmony_ci util_format_description(info->src.format); 122bf215546Sopenharmony_ci int i = util_format_get_first_non_void_channel(info->src.format); 123bf215546Sopenharmony_ci if (i == -1) 124bf215546Sopenharmony_ci return false; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci /* can't do the alpha to 1 setting for these. */ 127bf215546Sopenharmony_ci if ((util_format_has_alpha1(info->src.format) && 128bf215546Sopenharmony_ci util_format_has_alpha(info->dst.format) && 129bf215546Sopenharmony_ci desc->channel[i].size > 8)) 130bf215546Sopenharmony_ci return false; 131bf215546Sopenharmony_ci return true; 132bf215546Sopenharmony_ci} 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_cistatic inline int crocus_resource_blt_pitch(struct crocus_resource *res) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci int pitch = res->surf.row_pitch_B; 137bf215546Sopenharmony_ci if (res->surf.tiling != ISL_TILING_LINEAR) 138bf215546Sopenharmony_ci pitch /= 4; 139bf215546Sopenharmony_ci return pitch; 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_cistatic bool emit_copy_blt(struct crocus_batch *batch, 144bf215546Sopenharmony_ci struct crocus_resource *src, 145bf215546Sopenharmony_ci struct crocus_resource *dst, 146bf215546Sopenharmony_ci unsigned cpp, 147bf215546Sopenharmony_ci int32_t src_pitch, 148bf215546Sopenharmony_ci unsigned src_offset, 149bf215546Sopenharmony_ci int32_t dst_pitch, 150bf215546Sopenharmony_ci unsigned dst_offset, 151bf215546Sopenharmony_ci uint16_t src_x, uint16_t src_y, 152bf215546Sopenharmony_ci uint16_t dst_x, uint16_t dst_y, 153bf215546Sopenharmony_ci uint16_t w, uint16_t h) 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci uint32_t src_tile_w, src_tile_h; 157bf215546Sopenharmony_ci uint32_t dst_tile_w, dst_tile_h; 158bf215546Sopenharmony_ci int dst_y2 = dst_y + h; 159bf215546Sopenharmony_ci int dst_x2 = dst_x + w; 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", 162bf215546Sopenharmony_ci __func__, 163bf215546Sopenharmony_ci src, src_pitch, src_offset, src_x, src_y, 164bf215546Sopenharmony_ci dst, dst_pitch, dst_offset, dst_x, dst_y, w, h); 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci isl_get_tile_dims(src->surf.tiling, cpp, &src_tile_w, &src_tile_h); 167bf215546Sopenharmony_ci isl_get_tile_dims(dst->surf.tiling, cpp, &dst_tile_w, &dst_tile_h); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci /* For Tiled surfaces, the pitch has to be a multiple of the Tile width 170bf215546Sopenharmony_ci * (X direction width of the Tile). This is ensured while allocating the 171bf215546Sopenharmony_ci * buffer object. 172bf215546Sopenharmony_ci */ 173bf215546Sopenharmony_ci assert(src->surf.tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0); 174bf215546Sopenharmony_ci assert(dst->surf.tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0); 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci /* For big formats (such as floating point), do the copy using 16 or 177bf215546Sopenharmony_ci * 32bpp and multiply the coordinates. 178bf215546Sopenharmony_ci */ 179bf215546Sopenharmony_ci if (cpp > 4) { 180bf215546Sopenharmony_ci if (cpp % 4 == 2) { 181bf215546Sopenharmony_ci dst_x *= cpp / 2; 182bf215546Sopenharmony_ci dst_x2 *= cpp / 2; 183bf215546Sopenharmony_ci src_x *= cpp / 2; 184bf215546Sopenharmony_ci cpp = 2; 185bf215546Sopenharmony_ci } else { 186bf215546Sopenharmony_ci assert(cpp % 4 == 0); 187bf215546Sopenharmony_ci dst_x *= cpp / 4; 188bf215546Sopenharmony_ci dst_x2 *= cpp / 4; 189bf215546Sopenharmony_ci src_x *= cpp / 4; 190bf215546Sopenharmony_ci cpp = 4; 191bf215546Sopenharmony_ci } 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop 195bf215546Sopenharmony_ci * the low bits. Offsets must be naturally aligned. 196bf215546Sopenharmony_ci */ 197bf215546Sopenharmony_ci if (src_pitch % 4 != 0 || src_offset % cpp != 0 || 198bf215546Sopenharmony_ci dst_pitch % 4 != 0 || dst_offset % cpp != 0) 199bf215546Sopenharmony_ci return false; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci /* For tiled source and destination, pitch value should be specified 202bf215546Sopenharmony_ci * as a number of Dwords. 203bf215546Sopenharmony_ci */ 204bf215546Sopenharmony_ci if (dst->surf.tiling != ISL_TILING_LINEAR) 205bf215546Sopenharmony_ci dst_pitch /= 4; 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci if (src->surf.tiling != ISL_TILING_LINEAR) 208bf215546Sopenharmony_ci src_pitch /= 4; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci assert(cpp <= 4); 211bf215546Sopenharmony_ci crocus_emit_cmd(batch, GENX(XY_SRC_COPY_BLT), xyblt) { 212bf215546Sopenharmony_ci xyblt.RasterOperation = 0xCC; 213bf215546Sopenharmony_ci xyblt.DestinationTilingEnable = dst->surf.tiling != ISL_TILING_LINEAR; 214bf215546Sopenharmony_ci xyblt.SourceTilingEnable = src->surf.tiling != ISL_TILING_LINEAR; 215bf215546Sopenharmony_ci xyblt.SourceBaseAddress = ro_bo(src->bo, src_offset); 216bf215546Sopenharmony_ci xyblt.DestinationBaseAddress = rw_bo(dst->bo, dst_offset); 217bf215546Sopenharmony_ci xyblt.ColorDepth = color_depth_for_cpp(cpp); 218bf215546Sopenharmony_ci xyblt._32bppByteMask = cpp == 4 ? 0x3 : 0x1; 219bf215546Sopenharmony_ci xyblt.DestinationX1Coordinate = dst_x; 220bf215546Sopenharmony_ci xyblt.DestinationY1Coordinate = dst_y; 221bf215546Sopenharmony_ci xyblt.DestinationX2Coordinate = dst_x2; 222bf215546Sopenharmony_ci xyblt.DestinationY2Coordinate = dst_y2; 223bf215546Sopenharmony_ci xyblt.DestinationPitch = dst_pitch; 224bf215546Sopenharmony_ci xyblt.SourceX1Coordinate = src_x; 225bf215546Sopenharmony_ci xyblt.SourceY1Coordinate = src_y; 226bf215546Sopenharmony_ci xyblt.SourcePitch = src_pitch; 227bf215546Sopenharmony_ci }; 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci crocus_emit_mi_flush(batch); 230bf215546Sopenharmony_ci return true; 231bf215546Sopenharmony_ci} 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistatic bool crocus_emit_blt(struct crocus_batch *batch, 234bf215546Sopenharmony_ci struct crocus_resource *src, 235bf215546Sopenharmony_ci struct crocus_resource *dst, 236bf215546Sopenharmony_ci unsigned dst_level, 237bf215546Sopenharmony_ci unsigned dst_x, unsigned dst_y, 238bf215546Sopenharmony_ci unsigned dst_z, 239bf215546Sopenharmony_ci unsigned src_level, 240bf215546Sopenharmony_ci const struct pipe_box *src_box) 241bf215546Sopenharmony_ci{ 242bf215546Sopenharmony_ci const struct isl_format_layout *src_fmtl = isl_format_get_layout(src->surf.format); 243bf215546Sopenharmony_ci unsigned src_cpp = src_fmtl->bpb / 8; 244bf215546Sopenharmony_ci const struct isl_format_layout *dst_fmtl = isl_format_get_layout(dst->surf.format); 245bf215546Sopenharmony_ci const unsigned dst_cpp = dst_fmtl->bpb / 8; 246bf215546Sopenharmony_ci uint16_t src_x, src_y; 247bf215546Sopenharmony_ci uint32_t src_image_x, src_image_y, dst_image_x, dst_image_y; 248bf215546Sopenharmony_ci uint32_t src_width = src_box->width, src_height = src_box->height; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci /* gen4/5 can't handle Y tiled blits. */ 251bf215546Sopenharmony_ci if (src->surf.tiling == ISL_TILING_Y0 || dst->surf.tiling == ISL_TILING_Y0) 252bf215546Sopenharmony_ci return false; 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci if (src->surf.format != dst->surf.format) 255bf215546Sopenharmony_ci return false; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ci if (src_cpp != dst_cpp) 258bf215546Sopenharmony_ci return false; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci src_x = src_box->x; 261bf215546Sopenharmony_ci src_y = src_box->y; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci assert(src_cpp == dst_cpp); 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci crocus_resource_get_image_offset(src, src_level, src_box->z, &src_image_x, 266bf215546Sopenharmony_ci &src_image_y); 267bf215546Sopenharmony_ci if (util_format_is_compressed(src->base.b.format)) { 268bf215546Sopenharmony_ci int bw = util_format_get_blockwidth(src->base.b.format); 269bf215546Sopenharmony_ci int bh = util_format_get_blockheight(src->base.b.format); 270bf215546Sopenharmony_ci assert(src_x % bw == 0); 271bf215546Sopenharmony_ci assert(src_y % bh == 0); 272bf215546Sopenharmony_ci src_x /= (int)bw; 273bf215546Sopenharmony_ci src_y /= (int)bh; 274bf215546Sopenharmony_ci src_width = DIV_ROUND_UP(src_width, (int)bw); 275bf215546Sopenharmony_ci src_height = DIV_ROUND_UP(src_height, (int)bh); 276bf215546Sopenharmony_ci } 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci crocus_resource_get_image_offset(dst, dst_level, dst_z, &dst_image_x, 279bf215546Sopenharmony_ci &dst_image_y); 280bf215546Sopenharmony_ci if (util_format_is_compressed(dst->base.b.format)) { 281bf215546Sopenharmony_ci int bw = util_format_get_blockwidth(dst->base.b.format); 282bf215546Sopenharmony_ci int bh = util_format_get_blockheight(dst->base.b.format); 283bf215546Sopenharmony_ci assert(dst_x % bw == 0); 284bf215546Sopenharmony_ci assert(dst_y % bh == 0); 285bf215546Sopenharmony_ci dst_x /= (int)bw; 286bf215546Sopenharmony_ci dst_y /= (int)bh; 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci src_x += src_image_x; 289bf215546Sopenharmony_ci src_y += src_image_y; 290bf215546Sopenharmony_ci dst_x += dst_image_x; 291bf215546Sopenharmony_ci dst_y += dst_image_y; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics 294bf215546Sopenharmony_ci * Data Size Limitations): 295bf215546Sopenharmony_ci * 296bf215546Sopenharmony_ci * The BLT engine is capable of transferring very large quantities of 297bf215546Sopenharmony_ci * graphics data. Any graphics data read from and written to the 298bf215546Sopenharmony_ci * destination is permitted to represent a number of pixels that 299bf215546Sopenharmony_ci * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line 300bf215546Sopenharmony_ci * at the destination. The maximum number of pixels that may be 301bf215546Sopenharmony_ci * represented per scan line’s worth of graphics data depends on the 302bf215546Sopenharmony_ci * color depth. 303bf215546Sopenharmony_ci * 304bf215546Sopenharmony_ci * The blitter's pitch is a signed 16-bit integer, but measured in bytes 305bf215546Sopenharmony_ci * for linear surfaces and DWords for tiled surfaces. So the maximum 306bf215546Sopenharmony_ci * pitch is 32k linear and 128k tiled. 307bf215546Sopenharmony_ci */ 308bf215546Sopenharmony_ci if (crocus_resource_blt_pitch(src) >= 32768 || 309bf215546Sopenharmony_ci crocus_resource_blt_pitch(dst) >= 32768) { 310bf215546Sopenharmony_ci return false; 311bf215546Sopenharmony_ci } 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci /* We need to split the blit into chunks that each fit within the blitter's 314bf215546Sopenharmony_ci * restrictions. We can't use a chunk size of 32768 because we need to 315bf215546Sopenharmony_ci * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's 316bf215546Sopenharmony_ci * a nice round power of two, big enough that performance won't suffer, and 317bf215546Sopenharmony_ci * small enough to guarantee everything fits. 318bf215546Sopenharmony_ci */ 319bf215546Sopenharmony_ci const uint32_t max_chunk_size = 16384; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci for (uint32_t chunk_x = 0; chunk_x < src_width; chunk_x += max_chunk_size) { 322bf215546Sopenharmony_ci for (uint32_t chunk_y = 0; chunk_y < src_height; chunk_y += max_chunk_size) { 323bf215546Sopenharmony_ci const uint32_t chunk_w = MIN2(max_chunk_size, src_width - chunk_x); 324bf215546Sopenharmony_ci const uint32_t chunk_h = MIN2(max_chunk_size, src_height - chunk_y); 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci uint64_t src_offset; 327bf215546Sopenharmony_ci uint32_t src_tile_x, src_tile_y; 328bf215546Sopenharmony_ci ASSERTED uint32_t z_offset_el, array_offset; 329bf215546Sopenharmony_ci isl_tiling_get_intratile_offset_el(src->surf.tiling, src->surf.dim, 330bf215546Sopenharmony_ci src->surf.msaa_layout, 331bf215546Sopenharmony_ci src_cpp * 8, src->surf.samples, 332bf215546Sopenharmony_ci src->surf.row_pitch_B, 333bf215546Sopenharmony_ci src->surf.array_pitch_el_rows, 334bf215546Sopenharmony_ci src_x + chunk_x, src_y + chunk_y, 0, 0, 335bf215546Sopenharmony_ci &src_offset, 336bf215546Sopenharmony_ci &src_tile_x, &src_tile_y, 337bf215546Sopenharmony_ci &z_offset_el, &array_offset); 338bf215546Sopenharmony_ci assert(z_offset_el == 0); 339bf215546Sopenharmony_ci assert(array_offset == 0); 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci uint64_t dst_offset; 342bf215546Sopenharmony_ci uint32_t dst_tile_x, dst_tile_y; 343bf215546Sopenharmony_ci isl_tiling_get_intratile_offset_el(dst->surf.tiling, dst->surf.dim, 344bf215546Sopenharmony_ci dst->surf.msaa_layout, 345bf215546Sopenharmony_ci dst_cpp * 8, dst->surf.samples, 346bf215546Sopenharmony_ci dst->surf.row_pitch_B, 347bf215546Sopenharmony_ci dst->surf.array_pitch_el_rows, 348bf215546Sopenharmony_ci dst_x + chunk_x, dst_y + chunk_y, 0, 0, 349bf215546Sopenharmony_ci &dst_offset, 350bf215546Sopenharmony_ci &dst_tile_x, &dst_tile_y, 351bf215546Sopenharmony_ci &z_offset_el, &array_offset); 352bf215546Sopenharmony_ci assert(z_offset_el == 0); 353bf215546Sopenharmony_ci assert(array_offset == 0); 354bf215546Sopenharmony_ci if (!emit_copy_blt(batch, src, dst, 355bf215546Sopenharmony_ci src_cpp, src->surf.row_pitch_B, 356bf215546Sopenharmony_ci src_offset, 357bf215546Sopenharmony_ci dst->surf.row_pitch_B, dst_offset, 358bf215546Sopenharmony_ci src_tile_x, src_tile_y, 359bf215546Sopenharmony_ci dst_tile_x, dst_tile_y, 360bf215546Sopenharmony_ci chunk_w, chunk_h)) { 361bf215546Sopenharmony_ci return false; 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if (util_format_has_alpha1(src->base.b.format) && 367bf215546Sopenharmony_ci util_format_has_alpha(dst->base.b.format)) 368bf215546Sopenharmony_ci blt_set_alpha_to_one(batch, dst, 0, 0, src_width, src_height); 369bf215546Sopenharmony_ci return true; 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_cistatic bool crocus_blit_blt(struct crocus_batch *batch, 373bf215546Sopenharmony_ci const struct pipe_blit_info *info) 374bf215546Sopenharmony_ci{ 375bf215546Sopenharmony_ci if (!validate_blit_for_blt(batch, info)) 376bf215546Sopenharmony_ci return false; 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci return crocus_emit_blt(batch, 379bf215546Sopenharmony_ci (struct crocus_resource *)info->src.resource, 380bf215546Sopenharmony_ci (struct crocus_resource *)info->dst.resource, 381bf215546Sopenharmony_ci info->dst.level, 382bf215546Sopenharmony_ci info->dst.box.x, 383bf215546Sopenharmony_ci info->dst.box.y, 384bf215546Sopenharmony_ci info->dst.box.z, 385bf215546Sopenharmony_ci info->src.level, 386bf215546Sopenharmony_ci &info->src.box); 387bf215546Sopenharmony_ci} 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_cistatic bool crocus_copy_region_blt(struct crocus_batch *batch, 391bf215546Sopenharmony_ci struct crocus_resource *dst, 392bf215546Sopenharmony_ci unsigned dst_level, 393bf215546Sopenharmony_ci unsigned dstx, unsigned dsty, unsigned dstz, 394bf215546Sopenharmony_ci struct crocus_resource *src, 395bf215546Sopenharmony_ci unsigned src_level, 396bf215546Sopenharmony_ci const struct pipe_box *src_box) 397bf215546Sopenharmony_ci{ 398bf215546Sopenharmony_ci if (dst->base.b.target == PIPE_BUFFER || src->base.b.target == PIPE_BUFFER) 399bf215546Sopenharmony_ci return false; 400bf215546Sopenharmony_ci return crocus_emit_blt(batch, 401bf215546Sopenharmony_ci src, 402bf215546Sopenharmony_ci dst, 403bf215546Sopenharmony_ci dst_level, 404bf215546Sopenharmony_ci dstx, dsty, dstz, 405bf215546Sopenharmony_ci src_level, 406bf215546Sopenharmony_ci src_box); 407bf215546Sopenharmony_ci} 408bf215546Sopenharmony_ci#endif 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_civoid 411bf215546Sopenharmony_cigenX(crocus_init_blt)(struct crocus_screen *screen) 412bf215546Sopenharmony_ci{ 413bf215546Sopenharmony_ci#if GFX_VER <= 5 414bf215546Sopenharmony_ci screen->vtbl.blit_blt = crocus_blit_blt; 415bf215546Sopenharmony_ci screen->vtbl.copy_region_blt = crocus_copy_region_blt; 416bf215546Sopenharmony_ci#else 417bf215546Sopenharmony_ci screen->vtbl.blit_blt = NULL; 418bf215546Sopenharmony_ci screen->vtbl.copy_region_blt = NULL; 419bf215546Sopenharmony_ci#endif 420bf215546Sopenharmony_ci} 421