summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/intel_batchbuffer.c106
-rw-r--r--lib/intel_batchbuffer.h17
-rw-r--r--lib/intel_reg.h18
3 files changed, 141 insertions, 0 deletions
diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
index c70f6d8b..f26bee15 100644
--- a/lib/intel_batchbuffer.c
+++ b/lib/intel_batchbuffer.c
@@ -457,6 +457,112 @@ unsigned igt_buf_height(struct igt_buf *buf)
return buf->size/buf->stride;
}
+/*
+ * pitches are in bytes if the surfaces are linear, number of dwords
+ * otherwise
+ */
+static uint32_t fast_copy_pitch(struct igt_buf *buf)
+{
+ if (buf->tiling != I915_TILING_NONE)
+ return buf->stride / 4;
+ else
+ return buf->stride;
+}
+
+/**
+ * igt_blitter_fast_copy:
+ * @batch: batchbuffer object
+ * @context: libdrm hardware context to use
+ * @src: source i-g-t buffer object
+ * @src_x: source pixel x-coordination
+ * @src_y: source pixel y-coordination
+ * @width: width of the copied rectangle
+ * @height: height of the copied rectangle
+ * @dst: destination i-g-t buffer object
+ * @dst_x: destination pixel x-coordination
+ * @dst_y: destination pixel y-coordination
+ *
+ * Copy @src into @dst using the gen9 fast copy blitter comamnd.
+ *
+ * The source and destination surfaces cannot overlap.
+ */
+void igt_blitter_fast_copy(struct intel_batchbuffer *batch,
+ struct igt_buf *src, unsigned src_x, unsigned src_y,
+ unsigned width, unsigned height,
+ struct igt_buf *dst, unsigned dst_x, unsigned dst_y)
+{
+ uint32_t src_pitch, dst_pitch;
+ uint32_t dword0 = 0, dword1 = 0;
+
+ src_pitch = fast_copy_pitch(src);
+ dst_pitch = fast_copy_pitch(dst);
+
+#define CHECK_RANGE(x) ((x) >= 0 && (x) < (1 << 15))
+ assert(CHECK_RANGE(src_x) && CHECK_RANGE(src_y) &&
+ CHECK_RANGE(dst_x) && CHECK_RANGE(dst_y) &&
+ CHECK_RANGE(width) && CHECK_RANGE(height) &&
+ CHECK_RANGE(src_x + width) && CHECK_RANGE(src_y + height) &&
+ CHECK_RANGE(dst_x + width) && CHECK_RANGE(dst_y + height) &&
+ CHECK_RANGE(src_pitch) && CHECK_RANGE(dst_pitch));
+#undef CHECK_RANGE
+
+ dword0 |= XY_FAST_COPY_BLT;
+
+ switch (src->tiling) {
+ case I915_TILING_X:
+ dword0 |= XY_FAST_COPY_SRC_TILING_X;
+ break;
+ case I915_TILING_Y:
+ case I915_TILING_Yf:
+ dword0 |= XY_FAST_COPY_SRC_TILING_Yb_Yf;
+ break;
+ case I915_TILING_Ys:
+ dword0 |= XY_FAST_COPY_SRC_TILING_Ys;
+ break;
+ case I915_TILING_NONE:
+ default:
+ break;
+ }
+
+ switch (dst->tiling) {
+ case I915_TILING_X:
+ dword0 |= XY_FAST_COPY_DST_TILING_X;
+ break;
+ case I915_TILING_Y:
+ case I915_TILING_Yf:
+ dword0 |= XY_FAST_COPY_DST_TILING_Yb_Yf;
+ break;
+ case I915_TILING_Ys:
+ dword0 |= XY_FAST_COPY_DST_TILING_Ys;
+ break;
+ case I915_TILING_NONE:
+ default:
+ break;
+ }
+
+ if (src->tiling == I915_TILING_Yf)
+ dword1 |= XY_FAST_COPY_SRC_TILING_Yf;
+ if (dst->tiling == I915_TILING_Yf)
+ dword1 |= XY_FAST_COPY_DST_TILING_Yf;
+
+ dword1 |= XY_FAST_COPY_COLOR_DEPTH_32;
+
+ BEGIN_BATCH(10, 2);
+ OUT_BATCH(dword0);
+ OUT_BATCH(dword1 | dst_pitch);
+ OUT_BATCH((dst_y << 16) | dst_x); /* dst x1,y1 */
+ OUT_BATCH(((dst_y + height) << 16) | (dst_x + width)); /* dst x2,y2 */
+ OUT_RELOC(dst->bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+ OUT_BATCH(0); /* dst address upper bits */
+ OUT_BATCH((src_y << 16) | src_x); /* src x1,y1 */
+ OUT_BATCH(src_pitch);
+ OUT_RELOC(src->bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+ OUT_BATCH(0); /* src address upper bits */
+ ADVANCE_BATCH();
+
+ intel_batchbuffer_flush(batch);
+}
+
/**
* igt_get_render_copyfunc:
* @devid: pci device id
diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
index 12f7be1c..00d63b7d 100644
--- a/lib/intel_batchbuffer.h
+++ b/lib/intel_batchbuffer.h
@@ -186,6 +186,18 @@ void intel_copy_bo(struct intel_batchbuffer *batch,
long int size);
/**
+ * Yf/Ys tiling
+ *
+ * Tiling mode in the I915_TILING_... namespace for new tiling modes which are
+ * defined in the kernel. (They are not fenceable so the kernel does not need
+ * to know about them.)
+ *
+ * They are to be used the the blitting routines below.
+ */
+#define I915_TILING_Yf 3
+#define I915_TILING_Ys 4
+
+/**
* igt_buf:
* @bo: underlying libdrm buffer object
* @stride: stride of the buffer
@@ -210,6 +222,11 @@ struct igt_buf {
unsigned igt_buf_width(struct igt_buf *buf);
unsigned igt_buf_height(struct igt_buf *buf);
+void igt_blitter_fast_copy(struct intel_batchbuffer *batch,
+ struct igt_buf *src, unsigned src_x, unsigned src_y,
+ unsigned width, unsigned height,
+ struct igt_buf *dst, unsigned dst_x, unsigned dst_y);
+
/**
* igt_render_copyfunc_t:
* @batch: batchbuffer object
diff --git a/lib/intel_reg.h b/lib/intel_reg.h
index ade1c0cc..0ffa803d 100644
--- a/lib/intel_reg.h
+++ b/lib/intel_reg.h
@@ -2514,6 +2514,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XY_MONO_SRC_BLT_WRITE_ALPHA (1<<21)
#define XY_MONO_SRC_BLT_WRITE_RGB (1<<20)
+#define XY_FAST_COPY_BLT ((2<<29)|(0x42<<22)|0x8)
+/* dword 0 */
+#define XY_FAST_COPY_SRC_TILING_LINEAR (0 << 20)
+#define XY_FAST_COPY_SRC_TILING_X (1 << 20)
+#define XY_FAST_COPY_SRC_TILING_Yb_Yf (2 << 20)
+#define XY_FAST_COPY_SRC_TILING_Ys (3 << 20)
+#define XY_FAST_COPY_SRC_HORIZONTAL_ALIGNMENT(n) (n << 17)
+#define XY_FAST_COPY_SRC_VERTICAL_ALIGNMENT(n) (n << 15)
+#define XY_FAST_COPY_DST_TILING_X (1 << 13)
+#define XY_FAST_COPY_DST_TILING_Yb_Yf (2 << 13)
+#define XY_FAST_COPY_DST_TILING_Ys (3 << 13)
+#define XY_FAST_COPY_DST_HORIZONTAL_ALIGNMENT(n) (n << 10)
+#define XY_FAST_COPY_DST_VERTICAL_ALIGNMENT(n) (n << 8)
+/* dword 1 */
+#define XY_FAST_COPY_SRC_TILING_Yf (1 << 31)
+#define XY_FAST_COPY_DST_TILING_Yf (1 << 30)
+#define XY_FAST_COPY_COLOR_DEPTH_32 (3 << 24)
+
#define MI_STORE_DWORD_IMM ((0x20<<23)|2)
#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */