diff options
author | Wladimir J. van der Laan <[email protected]> | 2017-11-18 10:44:29 +0100 |
---|---|---|
committer | Christian Gmeiner <[email protected]> | 2017-11-30 07:27:48 +0100 |
commit | 77768b185977fa3dde2bc2d2108c83e22f9aef15 (patch) | |
tree | cb7afb30990f4a474a85ffad154402f3204d7a37 /src/gallium/drivers/etnaviv/etnaviv_emit.h | |
parent | 571d980695cb434ad28ae0af959157e65598bcbb (diff) |
etnaviv: GC7000: Move etna_coalesce to emit header file
Want to be able to emit state from the texture implementation,
and the blitter implementation.
Signed-off-by: Wladimir J. van der Laan <[email protected]>
Reviewed-by: Christian Gmeiner <[email protected]>
Diffstat (limited to 'src/gallium/drivers/etnaviv/etnaviv_emit.h')
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_emit.h | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.h b/src/gallium/drivers/etnaviv/etnaviv_emit.h index 3c3d1294dc8..dd90127ddd4 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_emit.h +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.h @@ -34,6 +34,12 @@ struct etna_context; struct compiled_rs_state; +struct etna_coalesce { + uint32_t start; + uint32_t last_reg; + uint32_t last_fixp; +}; + static inline void etna_emit_load_state(struct etna_cmd_stream *stream, const uint16_t offset, const uint16_t count, const int fixp) @@ -138,6 +144,83 @@ etna_draw_instanced(struct etna_cmd_stream *stream, etna_cmd_stream_emit(stream, 0); } +static inline void +etna_coalesce_start(struct etna_cmd_stream *stream, + struct etna_coalesce *coalesce) +{ + coalesce->start = etna_cmd_stream_offset(stream); + coalesce->last_reg = 0; + coalesce->last_fixp = 0; +} + +static inline void +etna_coalesce_end(struct etna_cmd_stream *stream, + struct etna_coalesce *coalesce) +{ + uint32_t end = etna_cmd_stream_offset(stream); + uint32_t size = end - coalesce->start; + + if (size) { + uint32_t offset = coalesce->start - 1; + uint32_t value = etna_cmd_stream_get(stream, offset); + + value |= VIV_FE_LOAD_STATE_HEADER_COUNT(size); + etna_cmd_stream_set(stream, offset, value); + } + + /* append needed padding */ + if (end % 2 == 1) + etna_cmd_stream_emit(stream, 0xdeadbeef); +} + +static inline void +check_coalsence(struct etna_cmd_stream *stream, struct etna_coalesce *coalesce, + uint32_t reg, uint32_t fixp) +{ + if (coalesce->last_reg != 0) { + if (((coalesce->last_reg + 4) != reg) || (coalesce->last_fixp != fixp)) { + etna_coalesce_end(stream, coalesce); + etna_emit_load_state(stream, reg >> 2, 0, fixp); + coalesce->start = etna_cmd_stream_offset(stream); + } + } else { + etna_emit_load_state(stream, reg >> 2, 0, fixp); + coalesce->start = etna_cmd_stream_offset(stream); + } + + coalesce->last_reg = reg; + coalesce->last_fixp = fixp; +} + +static inline void +etna_coalsence_emit(struct etna_cmd_stream *stream, + struct etna_coalesce *coalesce, uint32_t reg, + uint32_t value) +{ + check_coalsence(stream, coalesce, reg, 0); + etna_cmd_stream_emit(stream, value); +} + +static inline void +etna_coalsence_emit_fixp(struct etna_cmd_stream *stream, + struct etna_coalesce *coalesce, uint32_t reg, + uint32_t value) +{ + check_coalsence(stream, coalesce, reg, 1); + etna_cmd_stream_emit(stream, value); +} + +static inline void +etna_coalsence_emit_reloc(struct etna_cmd_stream *stream, + struct etna_coalesce *coalesce, uint32_t reg, + const struct etna_reloc *r) +{ + if (r->bo) { + check_coalsence(stream, coalesce, reg, 0); + etna_cmd_stream_reloc(stream, r); + } +} + void etna_emit_state(struct etna_context *ctx); |