summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2015-06-02 13:50:58 +0100
committerRussell King <rmk@arm.linux.org.uk>2015-06-29 12:58:34 +0100
commit5ff3645997ccf4aaaeebe2fec7d7855108843548 (patch)
tree90b376c2ce64afce031e4538420373fdef0a758a
parent852797ab5ce277c74ffa3c8ace9c73f103777358 (diff)
etnaviv: convert etnaviv_blit_srcdst() to use absolute source origin mode
etnaviv_blit_srcdst() is a single-box copy from a source origin point to a single box on the destination. It doesn't make sense to calculate a relative offset for the source, we might as well use absolute origin mode. Switch to absolute origin mode, and add a DE op helper for this operation. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--etnaviv/etnaviv_accel.c8
-rw-r--r--etnaviv/etnaviv_op.c30
-rw-r--r--etnaviv/etnaviv_op.h2
3 files changed, 37 insertions, 3 deletions
diff --git a/etnaviv/etnaviv_accel.c b/etnaviv/etnaviv_accel.c
index 3727a71..112d472 100644
--- a/etnaviv/etnaviv_accel.c
+++ b/etnaviv/etnaviv_accel.c
@@ -180,10 +180,12 @@ static void etnaviv_blit_srcdst(struct etnaviv *etnaviv,
struct etnaviv_de_op *op,
int src_x, int src_y, int dst_x, int dst_y, int width, int height)
{
+ xPoint src_origin;
BoxRec box;
- op->src.offset.x = src_x - (dst_x + op->dst.offset.x);
- op->src.offset.y = src_y - (dst_y + op->dst.offset.y);
+ op->src_origin_mode = SRC_ORIGIN_NONE;
+ src_origin.x = src_x;
+ src_origin.y = src_y;
box.x1 = dst_x;
box.y1 = dst_y;
@@ -191,7 +193,7 @@ static void etnaviv_blit_srcdst(struct etnaviv *etnaviv,
box.y2 = dst_y + height;
etnaviv_blit_start(etnaviv, op);
- etnaviv_blit(etnaviv, op, &box, 1);
+ etnaviv_de_op_src_origin(etnaviv, op, src_origin, &box);
etnaviv_blit_complete(etnaviv);
}
diff --git a/etnaviv/etnaviv_op.c b/etnaviv/etnaviv_op.c
index 584375e..e831466 100644
--- a/etnaviv/etnaviv_op.c
+++ b/etnaviv/etnaviv_op.c
@@ -199,6 +199,36 @@ void etnaviv_de_end(struct etnaviv *etnaviv)
etnaviv_emit(etnaviv);
}
+void etnaviv_de_op_src_origin(struct etnaviv *etnaviv,
+ const struct etnaviv_de_op *op, xPoint src_origin, const BoxRec *dest)
+{
+ unsigned int high_wm = etnaviv->batch_de_high_watermark;
+ size_t op_size = etnaviv_size_2d_draw(etnaviv, 1) + 6 + 2;
+ xPoint offset = op->dst.offset;
+
+ if (op_size > high_wm - etnaviv->batch_size) {
+ etnaviv_de_end(etnaviv);
+ BATCH_OP_START(etnaviv);
+ }
+
+ EMIT_LOADSTATE(etnaviv, VIVS_DE_SRC_ORIGIN, 1);
+ EMIT(etnaviv, VIVS_DE_SRC_ORIGIN_X(src_origin.x) |
+ VIVS_DE_SRC_ORIGIN_Y(src_origin.y));
+ EMIT_DRAW_2D(etnaviv, 1);
+ EMIT(etnaviv,
+ VIV_FE_DRAW_2D_TOP_LEFT_X(offset.x + dest->x1) |
+ VIV_FE_DRAW_2D_TOP_LEFT_Y(offset.y + dest->y1));
+ EMIT(etnaviv,
+ VIV_FE_DRAW_2D_BOTTOM_RIGHT_X(offset.x + dest->x2) |
+ VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y(offset.y + dest->y2));
+ EMIT_LOADSTATE(etnaviv, 4, 1);
+ EMIT(etnaviv, 0);
+ EMIT_LOADSTATE(etnaviv, 4, 1);
+ EMIT(etnaviv, 0);
+ EMIT_LOADSTATE(etnaviv, 4, 1);
+ EMIT(etnaviv, 0);
+}
+
void etnaviv_de_op(struct etnaviv *etnaviv, const struct etnaviv_de_op *op,
const BoxRec *pBox, size_t nBox)
{
diff --git a/etnaviv/etnaviv_op.h b/etnaviv/etnaviv_op.h
index 201191b..19e0063 100644
--- a/etnaviv/etnaviv_op.h
+++ b/etnaviv/etnaviv_op.h
@@ -90,6 +90,8 @@ struct etnaviv_vr_op {
void etnaviv_de_start(struct etnaviv *etnaviv, const struct etnaviv_de_op *op);
void etnaviv_de_end(struct etnaviv *etnaviv);
+void etnaviv_de_op_src_origin(struct etnaviv *etnaviv,
+ const struct etnaviv_de_op *op, xPoint src_origin, const BoxRec *dest);
void etnaviv_de_op(struct etnaviv *etnaviv, const struct etnaviv_de_op *op,
const BoxRec *pBox, size_t nBox);
void etnaviv_vr_op(struct etnaviv *etnaviv, struct etnaviv_vr_op *op,