17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2018 Intel Corporation 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 shall be included 127ec681f3Smrg * in all copies or substantial portions of the Software. 137ec681f3Smrg * 147ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 157ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 177ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 187ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 197ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 207ec681f3Smrg * DEALINGS IN THE SOFTWARE. 217ec681f3Smrg */ 227ec681f3Smrg 237ec681f3Smrg/* blt command encoding for gen4/5 */ 247ec681f3Smrg#include "crocus_context.h" 257ec681f3Smrg 267ec681f3Smrg#include "crocus_genx_macros.h" 277ec681f3Smrg#include "crocus_genx_protos.h" 287ec681f3Smrg#include "crocus_resource.h" 297ec681f3Smrg 307ec681f3Smrg#define FILE_DEBUG_FLAG DEBUG_BLIT 317ec681f3Smrg 327ec681f3Smrg#if GFX_VER <= 5 337ec681f3Smrg 347ec681f3Smrgstatic uint32_t 357ec681f3Smrgcolor_depth_for_cpp(int cpp) 367ec681f3Smrg{ 377ec681f3Smrg switch (cpp) { 387ec681f3Smrg case 4: return COLOR_DEPTH__32bit; 397ec681f3Smrg case 2: return COLOR_DEPTH__565; 407ec681f3Smrg case 1: return COLOR_DEPTH__8bit; 417ec681f3Smrg default: 427ec681f3Smrg unreachable("not reached"); 437ec681f3Smrg } 447ec681f3Smrg} 457ec681f3Smrg 467ec681f3Smrgstatic void 477ec681f3Smrgblt_set_alpha_to_one(struct crocus_batch *batch, 487ec681f3Smrg struct crocus_resource *dst, 497ec681f3Smrg int x, int y, int width, int height) 507ec681f3Smrg{ 517ec681f3Smrg const struct isl_format_layout *fmtl = isl_format_get_layout(dst->surf.format); 527ec681f3Smrg unsigned cpp = fmtl->bpb / 8; 537ec681f3Smrg uint32_t pitch = dst->surf.row_pitch_B; 547ec681f3Smrg 557ec681f3Smrg if (dst->surf.tiling != ISL_TILING_LINEAR) 567ec681f3Smrg pitch /= 4; 577ec681f3Smrg /* We need to split the blit into chunks that each fit within the blitter's 587ec681f3Smrg * restrictions. We can't use a chunk size of 32768 because we need to 597ec681f3Smrg * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's 607ec681f3Smrg * a nice round power of two, big enough that performance won't suffer, and 617ec681f3Smrg * small enough to guarantee everything fits. 627ec681f3Smrg */ 637ec681f3Smrg const uint32_t max_chunk_size = 16384; 647ec681f3Smrg 657ec681f3Smrg for (uint32_t chunk_x = 0; chunk_x < width; chunk_x += max_chunk_size) { 667ec681f3Smrg for (uint32_t chunk_y = 0; chunk_y < height; chunk_y += max_chunk_size) { 677ec681f3Smrg const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x); 687ec681f3Smrg const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y); 697ec681f3Smrg uint32_t tile_x, tile_y; 707ec681f3Smrg uint64_t offset_B; 717ec681f3Smrg ASSERTED uint32_t z_offset_el, array_offset; 727ec681f3Smrg isl_tiling_get_intratile_offset_el(dst->surf.tiling, dst->surf.dim, 737ec681f3Smrg dst->surf.msaa_layout, 747ec681f3Smrg cpp * 8, dst->surf.samples, 757ec681f3Smrg dst->surf.row_pitch_B, 767ec681f3Smrg dst->surf.array_pitch_el_rows, 777ec681f3Smrg chunk_x, chunk_y, 0, 0, 787ec681f3Smrg &offset_B, 797ec681f3Smrg &tile_x, &tile_y, 807ec681f3Smrg &z_offset_el, &array_offset); 817ec681f3Smrg assert(z_offset_el == 0); 827ec681f3Smrg assert(array_offset == 0); 837ec681f3Smrg crocus_emit_cmd(batch, GENX(XY_COLOR_BLT), xyblt) { 847ec681f3Smrg xyblt.TilingEnable = dst->surf.tiling != ISL_TILING_LINEAR; 857ec681f3Smrg xyblt.ColorDepth = color_depth_for_cpp(cpp); 867ec681f3Smrg xyblt.RasterOperation = 0xF0; 877ec681f3Smrg xyblt.DestinationPitch = pitch; 887ec681f3Smrg xyblt._32bppByteMask = 2; 897ec681f3Smrg xyblt.DestinationBaseAddress = rw_bo(dst->bo, offset_B); 907ec681f3Smrg xyblt.DestinationX1Coordinate = tile_x; 917ec681f3Smrg xyblt.DestinationY1Coordinate = tile_y; 927ec681f3Smrg xyblt.DestinationX2Coordinate = tile_x + chunk_w; 937ec681f3Smrg xyblt.DestinationY2Coordinate = tile_y + chunk_h; 947ec681f3Smrg xyblt.SolidPatternColor = 0xffffffff; 957ec681f3Smrg } 967ec681f3Smrg } 977ec681f3Smrg } 987ec681f3Smrg} 997ec681f3Smrg 1007ec681f3Smrgstatic bool validate_blit_for_blt(struct crocus_batch *batch, 1017ec681f3Smrg const struct pipe_blit_info *info) 1027ec681f3Smrg{ 1037ec681f3Smrg /* If the source and destination are the same size with no mirroring, 1047ec681f3Smrg * the rectangles are within the size of the texture and there is no 1057ec681f3Smrg * scissor, then we can probably use the blit engine. 1067ec681f3Smrg */ 1077ec681f3Smrg if (info->dst.box.width != info->src.box.width || 1087ec681f3Smrg info->dst.box.height != info->src.box.height) 1097ec681f3Smrg return false; 1107ec681f3Smrg 1117ec681f3Smrg if (info->scissor_enable) 1127ec681f3Smrg return false; 1137ec681f3Smrg 1147ec681f3Smrg if (info->dst.box.height < 0 || info->src.box.height < 0) 1157ec681f3Smrg return false; 1167ec681f3Smrg 1177ec681f3Smrg if (info->dst.box.depth > 1 || info->src.box.depth > 1) 1187ec681f3Smrg return false; 1197ec681f3Smrg 1207ec681f3Smrg const struct util_format_description *desc = 1217ec681f3Smrg util_format_description(info->src.format); 1227ec681f3Smrg int i = util_format_get_first_non_void_channel(info->src.format); 1237ec681f3Smrg if (i == -1) 1247ec681f3Smrg return false; 1257ec681f3Smrg 1267ec681f3Smrg /* can't do the alpha to 1 setting for these. */ 1277ec681f3Smrg if ((util_format_has_alpha1(info->src.format) && 1287ec681f3Smrg util_format_has_alpha(info->dst.format) && 1297ec681f3Smrg desc->channel[i].size > 8)) 1307ec681f3Smrg return false; 1317ec681f3Smrg return true; 1327ec681f3Smrg} 1337ec681f3Smrg 1347ec681f3Smrgstatic inline int crocus_resource_blt_pitch(struct crocus_resource *res) 1357ec681f3Smrg{ 1367ec681f3Smrg int pitch = res->surf.row_pitch_B; 1377ec681f3Smrg if (res->surf.tiling != ISL_TILING_LINEAR) 1387ec681f3Smrg pitch /= 4; 1397ec681f3Smrg return pitch; 1407ec681f3Smrg} 1417ec681f3Smrg 1427ec681f3Smrg 1437ec681f3Smrgstatic bool emit_copy_blt(struct crocus_batch *batch, 1447ec681f3Smrg struct crocus_resource *src, 1457ec681f3Smrg struct crocus_resource *dst, 1467ec681f3Smrg unsigned cpp, 1477ec681f3Smrg int32_t src_pitch, 1487ec681f3Smrg unsigned src_offset, 1497ec681f3Smrg int32_t dst_pitch, 1507ec681f3Smrg unsigned dst_offset, 1517ec681f3Smrg uint16_t src_x, uint16_t src_y, 1527ec681f3Smrg uint16_t dst_x, uint16_t dst_y, 1537ec681f3Smrg uint16_t w, uint16_t h) 1547ec681f3Smrg 1557ec681f3Smrg{ 1567ec681f3Smrg uint32_t src_tile_w, src_tile_h; 1577ec681f3Smrg uint32_t dst_tile_w, dst_tile_h; 1587ec681f3Smrg int dst_y2 = dst_y + h; 1597ec681f3Smrg int dst_x2 = dst_x + w; 1607ec681f3Smrg 1617ec681f3Smrg DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", 1627ec681f3Smrg __func__, 1637ec681f3Smrg src, src_pitch, src_offset, src_x, src_y, 1647ec681f3Smrg dst, dst_pitch, dst_offset, dst_x, dst_y, w, h); 1657ec681f3Smrg 1667ec681f3Smrg isl_get_tile_dims(src->surf.tiling, cpp, &src_tile_w, &src_tile_h); 1677ec681f3Smrg isl_get_tile_dims(dst->surf.tiling, cpp, &dst_tile_w, &dst_tile_h); 1687ec681f3Smrg 1697ec681f3Smrg /* For Tiled surfaces, the pitch has to be a multiple of the Tile width 1707ec681f3Smrg * (X direction width of the Tile). This is ensured while allocating the 1717ec681f3Smrg * buffer object. 1727ec681f3Smrg */ 1737ec681f3Smrg assert(src->surf.tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0); 1747ec681f3Smrg assert(dst->surf.tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0); 1757ec681f3Smrg 1767ec681f3Smrg /* For big formats (such as floating point), do the copy using 16 or 1777ec681f3Smrg * 32bpp and multiply the coordinates. 1787ec681f3Smrg */ 1797ec681f3Smrg if (cpp > 4) { 1807ec681f3Smrg if (cpp % 4 == 2) { 1817ec681f3Smrg dst_x *= cpp / 2; 1827ec681f3Smrg dst_x2 *= cpp / 2; 1837ec681f3Smrg src_x *= cpp / 2; 1847ec681f3Smrg cpp = 2; 1857ec681f3Smrg } else { 1867ec681f3Smrg assert(cpp % 4 == 0); 1877ec681f3Smrg dst_x *= cpp / 4; 1887ec681f3Smrg dst_x2 *= cpp / 4; 1897ec681f3Smrg src_x *= cpp / 4; 1907ec681f3Smrg cpp = 4; 1917ec681f3Smrg } 1927ec681f3Smrg } 1937ec681f3Smrg 1947ec681f3Smrg /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop 1957ec681f3Smrg * the low bits. Offsets must be naturally aligned. 1967ec681f3Smrg */ 1977ec681f3Smrg if (src_pitch % 4 != 0 || src_offset % cpp != 0 || 1987ec681f3Smrg dst_pitch % 4 != 0 || dst_offset % cpp != 0) 1997ec681f3Smrg return false; 2007ec681f3Smrg 2017ec681f3Smrg /* For tiled source and destination, pitch value should be specified 2027ec681f3Smrg * as a number of Dwords. 2037ec681f3Smrg */ 2047ec681f3Smrg if (dst->surf.tiling != ISL_TILING_LINEAR) 2057ec681f3Smrg dst_pitch /= 4; 2067ec681f3Smrg 2077ec681f3Smrg if (src->surf.tiling != ISL_TILING_LINEAR) 2087ec681f3Smrg src_pitch /= 4; 2097ec681f3Smrg 2107ec681f3Smrg assert(cpp <= 4); 2117ec681f3Smrg crocus_emit_cmd(batch, GENX(XY_SRC_COPY_BLT), xyblt) { 2127ec681f3Smrg xyblt.RasterOperation = 0xCC; 2137ec681f3Smrg xyblt.DestinationTilingEnable = dst->surf.tiling != ISL_TILING_LINEAR; 2147ec681f3Smrg xyblt.SourceTilingEnable = src->surf.tiling != ISL_TILING_LINEAR; 2157ec681f3Smrg xyblt.SourceBaseAddress = ro_bo(src->bo, src_offset); 2167ec681f3Smrg xyblt.DestinationBaseAddress = rw_bo(dst->bo, dst_offset); 2177ec681f3Smrg xyblt.ColorDepth = color_depth_for_cpp(cpp); 2187ec681f3Smrg xyblt._32bppByteMask = cpp == 4 ? 0x3 : 0x1; 2197ec681f3Smrg xyblt.DestinationX1Coordinate = dst_x; 2207ec681f3Smrg xyblt.DestinationY1Coordinate = dst_y; 2217ec681f3Smrg xyblt.DestinationX2Coordinate = dst_x2; 2227ec681f3Smrg xyblt.DestinationY2Coordinate = dst_y2; 2237ec681f3Smrg xyblt.DestinationPitch = dst_pitch; 2247ec681f3Smrg xyblt.SourceX1Coordinate = src_x; 2257ec681f3Smrg xyblt.SourceY1Coordinate = src_y; 2267ec681f3Smrg xyblt.SourcePitch = src_pitch; 2277ec681f3Smrg }; 2287ec681f3Smrg 2297ec681f3Smrg crocus_emit_mi_flush(batch); 2307ec681f3Smrg return true; 2317ec681f3Smrg} 2327ec681f3Smrg 2337ec681f3Smrgstatic bool crocus_emit_blt(struct crocus_batch *batch, 2347ec681f3Smrg struct crocus_resource *src, 2357ec681f3Smrg struct crocus_resource *dst, 2367ec681f3Smrg unsigned dst_level, 2377ec681f3Smrg unsigned dst_x, unsigned dst_y, 2387ec681f3Smrg unsigned dst_z, 2397ec681f3Smrg unsigned src_level, 2407ec681f3Smrg const struct pipe_box *src_box) 2417ec681f3Smrg{ 2427ec681f3Smrg const struct isl_format_layout *src_fmtl = isl_format_get_layout(src->surf.format); 2437ec681f3Smrg unsigned src_cpp = src_fmtl->bpb / 8; 2447ec681f3Smrg const struct isl_format_layout *dst_fmtl = isl_format_get_layout(dst->surf.format); 2457ec681f3Smrg const unsigned dst_cpp = dst_fmtl->bpb / 8; 2467ec681f3Smrg uint16_t src_x, src_y; 2477ec681f3Smrg uint32_t src_image_x, src_image_y, dst_image_x, dst_image_y; 2487ec681f3Smrg uint32_t src_width = src_box->width, src_height = src_box->height; 2497ec681f3Smrg 2507ec681f3Smrg /* gen4/5 can't handle Y tiled blits. */ 2517ec681f3Smrg if (src->surf.tiling == ISL_TILING_Y0 || dst->surf.tiling == ISL_TILING_Y0) 2527ec681f3Smrg return false; 2537ec681f3Smrg 2547ec681f3Smrg if (src->surf.format != dst->surf.format) 2557ec681f3Smrg return false; 2567ec681f3Smrg 2577ec681f3Smrg if (src_cpp != dst_cpp) 2587ec681f3Smrg return false; 2597ec681f3Smrg 2607ec681f3Smrg src_x = src_box->x; 2617ec681f3Smrg src_y = src_box->y; 2627ec681f3Smrg 2637ec681f3Smrg assert(src_cpp == dst_cpp); 2647ec681f3Smrg 2657ec681f3Smrg crocus_resource_get_image_offset(src, src_level, src_box->z, &src_image_x, 2667ec681f3Smrg &src_image_y); 2677ec681f3Smrg if (util_format_is_compressed(src->base.b.format)) { 2687ec681f3Smrg int bw = util_format_get_blockwidth(src->base.b.format); 2697ec681f3Smrg int bh = util_format_get_blockheight(src->base.b.format); 2707ec681f3Smrg assert(src_x % bw == 0); 2717ec681f3Smrg assert(src_y % bh == 0); 2727ec681f3Smrg src_x /= (int)bw; 2737ec681f3Smrg src_y /= (int)bh; 2747ec681f3Smrg src_width = DIV_ROUND_UP(src_width, (int)bw); 2757ec681f3Smrg src_height = DIV_ROUND_UP(src_height, (int)bh); 2767ec681f3Smrg } 2777ec681f3Smrg 2787ec681f3Smrg crocus_resource_get_image_offset(dst, dst_level, dst_z, &dst_image_x, 2797ec681f3Smrg &dst_image_y); 2807ec681f3Smrg if (util_format_is_compressed(dst->base.b.format)) { 2817ec681f3Smrg int bw = util_format_get_blockwidth(dst->base.b.format); 2827ec681f3Smrg int bh = util_format_get_blockheight(dst->base.b.format); 2837ec681f3Smrg assert(dst_x % bw == 0); 2847ec681f3Smrg assert(dst_y % bh == 0); 2857ec681f3Smrg dst_x /= (int)bw; 2867ec681f3Smrg dst_y /= (int)bh; 2877ec681f3Smrg } 2887ec681f3Smrg src_x += src_image_x; 2897ec681f3Smrg src_y += src_image_y; 2907ec681f3Smrg dst_x += dst_image_x; 2917ec681f3Smrg dst_y += dst_image_y; 2927ec681f3Smrg 2937ec681f3Smrg /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics 2947ec681f3Smrg * Data Size Limitations): 2957ec681f3Smrg * 2967ec681f3Smrg * The BLT engine is capable of transferring very large quantities of 2977ec681f3Smrg * graphics data. Any graphics data read from and written to the 2987ec681f3Smrg * destination is permitted to represent a number of pixels that 2997ec681f3Smrg * occupies up to 65,536 scan lines and up to 32,768 bytes per scan line 3007ec681f3Smrg * at the destination. The maximum number of pixels that may be 3017ec681f3Smrg * represented per scan line’s worth of graphics data depends on the 3027ec681f3Smrg * color depth. 3037ec681f3Smrg * 3047ec681f3Smrg * The blitter's pitch is a signed 16-bit integer, but measured in bytes 3057ec681f3Smrg * for linear surfaces and DWords for tiled surfaces. So the maximum 3067ec681f3Smrg * pitch is 32k linear and 128k tiled. 3077ec681f3Smrg */ 3087ec681f3Smrg if (crocus_resource_blt_pitch(src) >= 32768 || 3097ec681f3Smrg crocus_resource_blt_pitch(dst) >= 32768) { 3107ec681f3Smrg return false; 3117ec681f3Smrg } 3127ec681f3Smrg 3137ec681f3Smrg /* We need to split the blit into chunks that each fit within the blitter's 3147ec681f3Smrg * restrictions. We can't use a chunk size of 32768 because we need to 3157ec681f3Smrg * ensure that src_tile_x + chunk_size fits. We choose 16384 because it's 3167ec681f3Smrg * a nice round power of two, big enough that performance won't suffer, and 3177ec681f3Smrg * small enough to guarantee everything fits. 3187ec681f3Smrg */ 3197ec681f3Smrg const uint32_t max_chunk_size = 16384; 3207ec681f3Smrg 3217ec681f3Smrg for (uint32_t chunk_x = 0; chunk_x < src_width; chunk_x += max_chunk_size) { 3227ec681f3Smrg for (uint32_t chunk_y = 0; chunk_y < src_height; chunk_y += max_chunk_size) { 3237ec681f3Smrg const uint32_t chunk_w = MIN2(max_chunk_size, src_width - chunk_x); 3247ec681f3Smrg const uint32_t chunk_h = MIN2(max_chunk_size, src_height - chunk_y); 3257ec681f3Smrg 3267ec681f3Smrg uint64_t src_offset; 3277ec681f3Smrg uint32_t src_tile_x, src_tile_y; 3287ec681f3Smrg ASSERTED uint32_t z_offset_el, array_offset; 3297ec681f3Smrg isl_tiling_get_intratile_offset_el(src->surf.tiling, src->surf.dim, 3307ec681f3Smrg src->surf.msaa_layout, 3317ec681f3Smrg src_cpp * 8, src->surf.samples, 3327ec681f3Smrg src->surf.row_pitch_B, 3337ec681f3Smrg src->surf.array_pitch_el_rows, 3347ec681f3Smrg src_x + chunk_x, src_y + chunk_y, 0, 0, 3357ec681f3Smrg &src_offset, 3367ec681f3Smrg &src_tile_x, &src_tile_y, 3377ec681f3Smrg &z_offset_el, &array_offset); 3387ec681f3Smrg assert(z_offset_el == 0); 3397ec681f3Smrg assert(array_offset == 0); 3407ec681f3Smrg 3417ec681f3Smrg uint64_t dst_offset; 3427ec681f3Smrg uint32_t dst_tile_x, dst_tile_y; 3437ec681f3Smrg isl_tiling_get_intratile_offset_el(dst->surf.tiling, dst->surf.dim, 3447ec681f3Smrg dst->surf.msaa_layout, 3457ec681f3Smrg dst_cpp * 8, dst->surf.samples, 3467ec681f3Smrg dst->surf.row_pitch_B, 3477ec681f3Smrg dst->surf.array_pitch_el_rows, 3487ec681f3Smrg dst_x + chunk_x, dst_y + chunk_y, 0, 0, 3497ec681f3Smrg &dst_offset, 3507ec681f3Smrg &dst_tile_x, &dst_tile_y, 3517ec681f3Smrg &z_offset_el, &array_offset); 3527ec681f3Smrg assert(z_offset_el == 0); 3537ec681f3Smrg assert(array_offset == 0); 3547ec681f3Smrg if (!emit_copy_blt(batch, src, dst, 3557ec681f3Smrg src_cpp, src->surf.row_pitch_B, 3567ec681f3Smrg src_offset, 3577ec681f3Smrg dst->surf.row_pitch_B, dst_offset, 3587ec681f3Smrg src_tile_x, src_tile_y, 3597ec681f3Smrg dst_tile_x, dst_tile_y, 3607ec681f3Smrg chunk_w, chunk_h)) { 3617ec681f3Smrg return false; 3627ec681f3Smrg } 3637ec681f3Smrg } 3647ec681f3Smrg } 3657ec681f3Smrg 3667ec681f3Smrg if (util_format_has_alpha1(src->base.b.format) && 3677ec681f3Smrg util_format_has_alpha(dst->base.b.format)) 3687ec681f3Smrg blt_set_alpha_to_one(batch, dst, 0, 0, src_width, src_height); 3697ec681f3Smrg return true; 3707ec681f3Smrg} 3717ec681f3Smrg 3727ec681f3Smrgstatic bool crocus_blit_blt(struct crocus_batch *batch, 3737ec681f3Smrg const struct pipe_blit_info *info) 3747ec681f3Smrg{ 3757ec681f3Smrg if (!validate_blit_for_blt(batch, info)) 3767ec681f3Smrg return false; 3777ec681f3Smrg 3787ec681f3Smrg return crocus_emit_blt(batch, 3797ec681f3Smrg (struct crocus_resource *)info->src.resource, 3807ec681f3Smrg (struct crocus_resource *)info->dst.resource, 3817ec681f3Smrg info->dst.level, 3827ec681f3Smrg info->dst.box.x, 3837ec681f3Smrg info->dst.box.y, 3847ec681f3Smrg info->dst.box.z, 3857ec681f3Smrg info->src.level, 3867ec681f3Smrg &info->src.box); 3877ec681f3Smrg} 3887ec681f3Smrg 3897ec681f3Smrg 3907ec681f3Smrgstatic bool crocus_copy_region_blt(struct crocus_batch *batch, 3917ec681f3Smrg struct crocus_resource *dst, 3927ec681f3Smrg unsigned dst_level, 3937ec681f3Smrg unsigned dstx, unsigned dsty, unsigned dstz, 3947ec681f3Smrg struct crocus_resource *src, 3957ec681f3Smrg unsigned src_level, 3967ec681f3Smrg const struct pipe_box *src_box) 3977ec681f3Smrg{ 3987ec681f3Smrg if (dst->base.b.target == PIPE_BUFFER || src->base.b.target == PIPE_BUFFER) 3997ec681f3Smrg return false; 4007ec681f3Smrg return crocus_emit_blt(batch, 4017ec681f3Smrg src, 4027ec681f3Smrg dst, 4037ec681f3Smrg dst_level, 4047ec681f3Smrg dstx, dsty, dstz, 4057ec681f3Smrg src_level, 4067ec681f3Smrg src_box); 4077ec681f3Smrg} 4087ec681f3Smrg#endif 4097ec681f3Smrg 4107ec681f3Smrgvoid 4117ec681f3SmrggenX(crocus_init_blt)(struct crocus_screen *screen) 4127ec681f3Smrg{ 4137ec681f3Smrg#if GFX_VER <= 5 4147ec681f3Smrg screen->vtbl.blit_blt = crocus_blit_blt; 4157ec681f3Smrg screen->vtbl.copy_region_blt = crocus_copy_region_blt; 4167ec681f3Smrg#else 4177ec681f3Smrg screen->vtbl.blit_blt = NULL; 4187ec681f3Smrg screen->vtbl.copy_region_blt = NULL; 4197ec681f3Smrg#endif 4207ec681f3Smrg} 421