.source = src->bo,
.source_offset = src_offset,
.source_stride = src_lev->stride,
+ .source_padded_width = src_lev->padded_width,
.source_padded_height = src_lev->padded_height,
.dest_format = translate_rs_format(dst_format),
.dest_tiling = dst->layout,
ctx->stats.rs_operations++;
- if (screen->specs.pixel_pipes == 1) {
+ if (cs->RS_KICKER_INPLACE) {
+ etna_cmd_stream_reserve(stream, 6);
+ etna_coalesce_start(stream, &coalesce);
+ /* 0/1 */ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG);
+ /* 2/3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE);
+ /* 4/5 */ EMIT_STATE(RS_KICKER_INPLACE, cs->RS_KICKER_INPLACE);
+ etna_coalesce_end(stream, &coalesce);
+ } else if (screen->specs.pixel_pipes == 1) {
etna_cmd_stream_reserve(stream, 22);
etna_coalesce_start(stream, &coalesce);
/* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG);
cs->RS_FILL_VALUE[3] = rs->clear_value[3];
cs->RS_EXTRA_CONFIG = VIVS_RS_EXTRA_CONFIG_AA(rs->aa) |
VIVS_RS_EXTRA_CONFIG_ENDIAN(rs->endian_mode);
- /* TODO: cs->RS_UNK016B0 = s->size / 64 ?
- * The blob does this consistently but there seems to be no currently supported
- * model that needs it.
+
+ /* If source the same as destination, and the hardware supports this,
+ * do an in-place resolve to fill in unrendered tiles.
*/
+ if (ctx->specs.single_buffer && rs->source == rs->dest &&
+ rs->source_offset == rs->dest_offset &&
+ rs->source_format == rs->dest_format &&
+ rs->source_tiling == rs->dest_tiling &&
+ rs->source_stride == rs->dest_stride &&
+ !rs->downsample_x && !rs->downsample_y &&
+ !rs->swap_rb && !rs->flip &&
+ !rs->clear_mode && rs->source_padded_width) {
+ /* Total number of tiles (same as for autodisable) */
+ cs->RS_KICKER_INPLACE = rs->source_padded_width * rs->source_padded_height / 16;
+ }
}
void
struct etna_bo *source;
uint32_t source_offset;
uint32_t source_stride;
+ uint32_t source_padded_width; /* total padded width (only needed for source) */
uint32_t source_padded_height; /* total padded height */
struct etna_bo *dest;
uint32_t dest_offset;
uint32_t RS_FILL_VALUE[4];
uint32_t RS_EXTRA_CONFIG;
uint32_t RS_PIPE_OFFSET[2];
+ uint32_t RS_KICKER_INPLACE; /* Set if source is destination */
struct etna_reloc source[2];
struct etna_reloc dest[2];