diff options
Diffstat (limited to 'src/etnaviv/etna_rs.c')
-rw-r--r-- | src/etnaviv/etna_rs.c | 82 |
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]); |