summaryrefslogtreecommitdiff
path: root/src/etnaviv/etna_rs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/etnaviv/etna_rs.c')
-rw-r--r--src/etnaviv/etna_rs.c82
1 files changed, 65 insertions, 17 deletions
diff --git a/src/etnaviv/etna_rs.c b/src/etnaviv/etna_rs.c
index a03662a..45321a5 100644
--- a/src/etnaviv/etna_rs.c
+++ b/src/etnaviv/etna_rs.c
@@ -26,6 +26,11 @@
#include <etnaviv/state.xml.h>
#include <etnaviv/state_3d.xml.h>
+//#define DEBUG
+#ifdef DEBUG
+# include <stdio.h>
+#endif
+
/* Some kind of RS flush, used in the older drivers */
void etna_warm_up_rs(struct etna_ctx *cmdbuf, viv_addr_t aux_rt_physical, viv_addr_t aux_rt_ts_physical)
{
@@ -57,6 +62,11 @@ void etna_compile_rs_state(struct etna_ctx *restrict ctx, struct compiled_rs_sta
/* TILED and SUPERTILED layout have their strides multiplied with 4 in RS */
unsigned source_stride_shift = (rs->source_tiling != ETNA_LAYOUT_LINEAR) ? 2 : 0;
unsigned dest_stride_shift = (rs->dest_tiling != ETNA_LAYOUT_LINEAR) ? 2 : 0;
+
+ /* tiling == ETNA_LAYOUT_MULTI_TILED or ETNA_LAYOUT_MULTI_SUPERTILED? */
+ bool source_multi = (rs->source_tiling & 0x4)?true:false;
+ bool dest_multi = (rs->dest_tiling & 0x4)?true:false;
+
/* TODO could just pre-generate command buffer, would simply submit to one memcpy */
SET_STATE(RS_CONFIG, VIVS_RS_CONFIG_SOURCE_FORMAT(rs->source_format) |
(rs->downsample_x?VIVS_RS_CONFIG_DOWNSAMPLE_X:0) |
@@ -66,20 +76,30 @@ void etna_compile_rs_state(struct etna_ctx *restrict ctx, struct compiled_rs_sta
((rs->dest_tiling&1)?VIVS_RS_CONFIG_DEST_TILED:0) |
((rs->swap_rb)?VIVS_RS_CONFIG_SWAP_RB:0) |
((rs->flip)?VIVS_RS_CONFIG_FLIP:0));
- SET_STATE(RS_SOURCE_ADDR, rs->source_addr);
- SET_STATE(RS_PIPE_SOURCE_ADDR[0], rs->source_addr);
- SET_STATE(RS_PIPE_SOURCE_ADDR[1], rs->source_addr); /* TODO */
- SET_STATE(RS_SOURCE_STRIDE, (rs->source_stride << source_stride_shift) | ((rs->source_tiling&2)?VIVS_RS_SOURCE_STRIDE_TILING:0));
- SET_STATE(RS_DEST_ADDR, rs->dest_addr);
- SET_STATE(RS_PIPE_DEST_ADDR[0], rs->dest_addr);
- SET_STATE(RS_PIPE_DEST_ADDR[1], rs->dest_addr); /* TODO */
- SET_STATE(RS_DEST_STRIDE, (rs->dest_stride << dest_stride_shift) | ((rs->dest_tiling&2)?VIVS_RS_DEST_STRIDE_TILING:0));
+ SET_STATE(RS_SOURCE_ADDR, rs->source_addr[0]);
+ SET_STATE(RS_PIPE_SOURCE_ADDR[0], rs->source_addr[0]);
+ SET_STATE(RS_SOURCE_STRIDE, (rs->source_stride << source_stride_shift) |
+ ((rs->source_tiling&2)?VIVS_RS_SOURCE_STRIDE_TILING:0) |
+ ((source_multi)?VIVS_RS_SOURCE_STRIDE_MULTI:0));
+ SET_STATE(RS_DEST_ADDR, rs->dest_addr[0]);
+ SET_STATE(RS_PIPE_DEST_ADDR[0], rs->dest_addr[0]);
+ SET_STATE(RS_DEST_STRIDE, (rs->dest_stride << dest_stride_shift) |
+ ((rs->dest_tiling&2)?VIVS_RS_DEST_STRIDE_TILING:0) |
+ ((dest_multi)?VIVS_RS_DEST_STRIDE_MULTI:0));
if (ctx->conn->chip.pixel_pipes == 1)
{
SET_STATE(RS_WINDOW_SIZE, VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) | VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height));
}
else if (ctx->conn->chip.pixel_pipes == 2)
{
+ if (source_multi)
+ {
+ SET_STATE(RS_PIPE_SOURCE_ADDR[1], rs->source_addr[1]);
+ }
+ if (dest_multi)
+ {
+ SET_STATE(RS_PIPE_DEST_ADDR[1], rs->dest_addr[1]);
+ }
SET_STATE(RS_WINDOW_SIZE, VIVS_RS_WINDOW_SIZE_WIDTH(rs->width) | VIVS_RS_WINDOW_SIZE_HEIGHT(rs->height / 2));
}
SET_STATE(RS_PIPE_OFFSET[0], VIVS_RS_PIPE_OFFSET_X(0) | VIVS_RS_PIPE_OFFSET_Y(0));
@@ -92,6 +112,18 @@ void etna_compile_rs_state(struct etna_ctx *restrict ctx, struct compiled_rs_sta
SET_STATE(RS_FILL_VALUE[2], rs->clear_value[2]);
SET_STATE(RS_FILL_VALUE[3], rs->clear_value[3]);
SET_STATE(RS_EXTRA_CONFIG, VIVS_RS_EXTRA_CONFIG_AA(rs->aa) | VIVS_RS_EXTRA_CONFIG_ENDIAN(rs->endian_mode));
+
+#ifdef DEBUG
+ printf("cs->dest_addr1: 0x%08x\n", cs->RS_PIPE_DEST_ADDR[0]);
+ printf("cs->dest_addr2: 0x%08x\n", cs->RS_PIPE_DEST_ADDR[1]);
+ printf("cs->source_addr1 0x%08x\n", cs->RS_PIPE_SOURCE_ADDR[0]);
+ printf("cs->source_addr2: 0x%08x\n", cs->RS_PIPE_SOURCE_ADDR[1]);
+ printf("rs->dest_tiling: 0x%08x\n", rs->dest_tiling);
+ printf("rs->source_tiling: 0x%08x\n", rs->source_tiling);
+ printf("cs->dest_stride: 0x%08x\n", cs->RS_DEST_STRIDE);
+ printf("cs->source_stride: 0x%08x\n", cs->RS_SOURCE_STRIDE);
+ printf("\n");
+#endif
}
/* submit RS state, without any processing and no dependence on context
@@ -126,21 +158,37 @@ void etna_submit_rs_state(struct etna_ctx *restrict ctx, const struct compiled_r
}
else if (ctx->conn->chip.pixel_pipes == 2)
{
- etna_reserve(ctx, 34);
+ etna_reserve(ctx, 34); /* worst case - both pipes multi=1 */
/*0 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_CONFIG>>2, 1, 0);
/*1 */ ETNA_EMIT(ctx, cs->RS_CONFIG);
/*2 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_SOURCE_STRIDE>>2, 1, 0);
/*3 */ ETNA_EMIT(ctx, cs->RS_SOURCE_STRIDE);
/*4 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_DEST_STRIDE>>2, 1, 0);
/*5 */ ETNA_EMIT(ctx, cs->RS_DEST_STRIDE);
- /*6 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_SOURCE_ADDR(0)>>2, 2, 0);
- /*7 */ ETNA_EMIT(ctx, cs->RS_PIPE_SOURCE_ADDR[0]);
- /*8 */ ETNA_EMIT(ctx, cs->RS_PIPE_SOURCE_ADDR[1]);
- /*9 */ ETNA_EMIT(ctx, 0x00000000); /* pad */
- /*10*/ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_DEST_ADDR(0)>>2, 2, 0);
- /*11*/ ETNA_EMIT(ctx, cs->RS_PIPE_DEST_ADDR[0]);
- /*12*/ ETNA_EMIT(ctx, cs->RS_PIPE_DEST_ADDR[1]);
- /*13*/ ETNA_EMIT(ctx, 0x00000000); /* pad */
+ if (cs->RS_SOURCE_STRIDE & VIVS_RS_SOURCE_STRIDE_MULTI)
+ {
+ /*6 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_SOURCE_ADDR(0)>>2, 2, 0);
+ /*7 */ ETNA_EMIT(ctx, cs->RS_PIPE_SOURCE_ADDR[0]);
+ /*8 */ ETNA_EMIT(ctx, cs->RS_PIPE_SOURCE_ADDR[1]);
+ /*9 */ ETNA_EMIT(ctx, 0x00000000); /* pad */
+ }
+ else
+ {
+ /*6 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_SOURCE_ADDR(0)>>2, 1, 0);
+ /*7 */ ETNA_EMIT(ctx, cs->RS_PIPE_SOURCE_ADDR[0]);
+ }
+ if (cs->RS_DEST_STRIDE & VIVS_RS_DEST_STRIDE_MULTI)
+ {
+ /*10*/ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_DEST_ADDR(0)>>2, 2, 0);
+ /*11*/ ETNA_EMIT(ctx, cs->RS_PIPE_DEST_ADDR[0]);
+ /*12*/ ETNA_EMIT(ctx, cs->RS_PIPE_DEST_ADDR[1]);
+ /*13*/ ETNA_EMIT(ctx, 0x00000000); /* pad */
+ }
+ else
+ {
+ /*10 */ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_DEST_ADDR(0)>>2, 1, 0);
+ /*11 */ ETNA_EMIT(ctx, cs->RS_PIPE_DEST_ADDR[0]);
+ }
/*14*/ ETNA_EMIT_LOAD_STATE(ctx, VIVS_RS_PIPE_OFFSET(0)>>2, 2, 0);
/*15*/ ETNA_EMIT(ctx, cs->RS_PIPE_OFFSET[0]);
/*16*/ ETNA_EMIT(ctx, cs->RS_PIPE_OFFSET[1]);