- src_width, src_height, false, GL_COPY);
-}
-
-static bool
-alignment_valid(struct brw_context *brw, unsigned offset,
- enum isl_tiling tiling)
-{
- /* Tiled buffers must be page-aligned (4K). */
- if (tiling != ISL_TILING_LINEAR)
- return (offset & 4095) == 0;
-
- /* On Gen8+, linear buffers must be cacheline-aligned. */
- if (brw->gen >= 8)
- return (offset & 63) == 0;
-
- return true;
-}
-
-static uint32_t
-xy_blit_cmd(enum isl_tiling src_tiling, enum isl_tiling dst_tiling,
- uint32_t cpp)
-{
- uint32_t CMD = 0;
-
- assert(cpp <= 4);
- switch (cpp) {
- case 1:
- case 2:
- CMD = XY_SRC_COPY_BLT_CMD;
- break;
- case 4:
- CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
- break;
- default:
- unreachable("not reached");
- }
-
- if (dst_tiling != ISL_TILING_LINEAR)
- CMD |= XY_DST_TILED;
-
- if (src_tiling != ISL_TILING_LINEAR)
- CMD |= XY_SRC_TILED;
-
- return CMD;
-}
-
-/* Copy BitBlt
- */
-bool
-intelEmitCopyBlit(struct brw_context *brw,
- GLuint cpp,
- int32_t src_pitch,
- struct brw_bo *src_buffer,
- GLuint src_offset,
- enum isl_tiling src_tiling,
- int32_t dst_pitch,
- struct brw_bo *dst_buffer,
- GLuint dst_offset,
- enum isl_tiling dst_tiling,
- GLshort src_x, GLshort src_y,
- GLshort dst_x, GLshort dst_y,
- GLshort w, GLshort h,
- GLenum logic_op)
-{
- GLuint CMD, BR13;
- int dst_y2 = dst_y + h;
- int dst_x2 = dst_x + w;
- bool dst_y_tiled = dst_tiling == ISL_TILING_Y0;
- bool src_y_tiled = src_tiling == ISL_TILING_Y0;
- uint32_t src_tile_w, src_tile_h;
- uint32_t dst_tile_w, dst_tile_h;
-
- if ((dst_y_tiled || src_y_tiled) && brw->gen < 6)
- return false;
-
- const unsigned bo_sizes = dst_buffer->size + src_buffer->size;
-
- /* do space check before going any further */
- if (!brw_batch_has_aperture_space(brw, bo_sizes))
- intel_batchbuffer_flush(brw);
-
- if (!brw_batch_has_aperture_space(brw, bo_sizes))
- return false;
-
- unsigned length = brw->gen >= 8 ? 10 : 8;
-
- intel_batchbuffer_require_space(brw, length * 4, BLT_RING);
- DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
- __func__,
- src_buffer, src_pitch, src_offset, src_x, src_y,
- dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
-
- intel_get_tile_dims(src_tiling, cpp, &src_tile_w, &src_tile_h);
- intel_get_tile_dims(dst_tiling, cpp, &dst_tile_w, &dst_tile_h);
-
- /* For Tiled surfaces, the pitch has to be a multiple of the Tile width
- * (X direction width of the Tile). This is ensured while allocating the
- * buffer object.
- */
- assert(src_tiling == ISL_TILING_LINEAR || (src_pitch % src_tile_w) == 0);
- assert(dst_tiling == ISL_TILING_LINEAR || (dst_pitch % dst_tile_w) == 0);
-
- /* For big formats (such as floating point), do the copy using 16 or
- * 32bpp and multiply the coordinates.
- */
- if (cpp > 4) {
- if (cpp % 4 == 2) {
- dst_x *= cpp / 2;
- dst_x2 *= cpp / 2;
- src_x *= cpp / 2;
- cpp = 2;
- } else {
- assert(cpp % 4 == 0);
- dst_x *= cpp / 4;
- dst_x2 *= cpp / 4;
- src_x *= cpp / 4;
- cpp = 4;
- }
- }
-
- if (!alignment_valid(brw, dst_offset, dst_tiling))
- return false;
- if (!alignment_valid(brw, src_offset, src_tiling))
- return false;
-
- /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to drop
- * the low bits. Offsets must be naturally aligned.
- */
- if (src_pitch % 4 != 0 || src_offset % cpp != 0 ||
- dst_pitch % 4 != 0 || dst_offset % cpp != 0)
- return false;
-
- assert(cpp <= 4);
- BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
-
- CMD = xy_blit_cmd(src_tiling, dst_tiling, cpp);
-
- /* For tiled source and destination, pitch value should be specified
- * as a number of Dwords.
- */
- if (dst_tiling != ISL_TILING_LINEAR)
- dst_pitch /= 4;
-
- if (src_tiling != ISL_TILING_LINEAR)
- src_pitch /= 4;
-
- if (dst_y2 <= dst_y || dst_x2 <= dst_x)
- return true;
-
- assert(dst_x < dst_x2);
- assert(dst_y < dst_y2);
-
- BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, src_y_tiled);
- OUT_BATCH(CMD | (length - 2));
- OUT_BATCH(BR13 | (uint16_t)dst_pitch);
- OUT_BATCH(SET_FIELD(dst_y, BLT_Y) | SET_FIELD(dst_x, BLT_X));
- OUT_BATCH(SET_FIELD(dst_y2, BLT_Y) | SET_FIELD(dst_x2, BLT_X));
- if (brw->gen >= 8) {
- OUT_RELOC64(dst_buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- dst_offset);
- } else {
- OUT_RELOC(dst_buffer,
- I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
- dst_offset);
- }
- OUT_BATCH(SET_FIELD(src_y, BLT_Y) | SET_FIELD(src_x, BLT_X));
- OUT_BATCH((uint16_t)src_pitch);
- if (brw->gen >= 8) {
- OUT_RELOC64(src_buffer,
- I915_GEM_DOMAIN_RENDER, 0,
- src_offset);
- } else {
- OUT_RELOC(src_buffer,
- I915_GEM_DOMAIN_RENDER, 0,
- src_offset);
- }
-
- ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
-
- brw_emit_mi_flush(brw);
-
- return true;