this introduces some tracking of the number of vertices drawn in the current batch: the draw command needs an offset to the start of the binning data
Signed-off-by: Jonathan Marek <jonat...@marek.ca> --- .../drivers/freedreno/adreno_pm4.xml.h | 7 +++++ .../drivers/freedreno/freedreno_batch.c | 1 + .../drivers/freedreno/freedreno_batch.h | 1 + .../drivers/freedreno/freedreno_draw.c | 2 ++ .../drivers/freedreno/freedreno_draw.h | 28 +++++++++++++++++-- .../drivers/freedreno/freedreno_util.h | 8 ++++-- 6 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/freedreno/adreno_pm4.xml.h b/src/gallium/drivers/freedreno/adreno_pm4.xml.h index 88d1c4e6eb..27bbb1928e 100644 --- a/src/gallium/drivers/freedreno/adreno_pm4.xml.h +++ b/src/gallium/drivers/freedreno/adreno_pm4.xml.h @@ -108,6 +108,13 @@ enum pc_di_src_sel { DI_SRC_SEL_RESERVED = 3, }; +enum pc_di_face_cull_sel { + DI_FACE_CULL_NONE = 0, + DI_FACE_CULL_FETCH = 1, + DI_FACE_BACKFACE_CULL = 2, + DI_FACE_FRONTFACE_CULL = 3, +}; + enum pc_di_index_size { INDEX_SIZE_IGN = 0, INDEX_SIZE_16_BIT = 0, diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c index a714d97f5c..7ffadea4e0 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.c +++ b/src/gallium/drivers/freedreno/freedreno_batch.c @@ -76,6 +76,7 @@ batch_init(struct fd_batch *batch) batch->flushed = false; batch->gmem_reason = 0; batch->num_draws = 0; + batch->num_vertices = 0; batch->stage = FD_STAGE_NULL; fd_reset_wfi(batch); diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index 6ff4014ddc..7e6c780aca 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -124,6 +124,7 @@ struct fd_batch { FD_GMEM_LOGICOP_ENABLED = 0x20, } gmem_reason; unsigned num_draws; /* number of draws in current batch */ + unsigned num_vertices; /* number of vertices in current batch */ /* Track the maximal bounds of the scissor of all the draws within a * batch. Used at the tile rendering step (fd_gmem_render_tiles(), diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index e130895aac..974a153773 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -263,6 +263,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) if (ctx->draw_vbo(ctx, info, index_offset)) batch->needs_flush = true; + batch->num_vertices += info->count; + for (i = 0; i < ctx->streamout.num_targets; i++) ctx->streamout.offsets[i] += info->count; diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h index 4a922d9ca3..7f4407a3ae 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.h +++ b/src/gallium/drivers/freedreno/freedreno_draw.h @@ -41,6 +41,7 @@ struct fd_ringbuffer; void fd_draw_init(struct pipe_context *pctx); + static inline void fd_draw(struct fd_batch *batch, struct fd_ringbuffer *ring, enum pc_di_primtype primtype, @@ -75,9 +76,31 @@ fd_draw(struct fd_batch *batch, struct fd_ringbuffer *ring, } if (is_a20x(batch->ctx->screen)) { - OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 4 : 2); + /* a20x has a different draw command for drawing with binning data + * that makes it harder to patch so always use hw binning if enabled + * + * binning data is is 1 byte/vertex (8x8x4 bin position of vertex) + * base ptr set by the CP_SET_DRAW_INIT_FLAGS command + * + * TODO: investigate the faceness_cull_select parameter to see how + * it is used with hw binning to use "faceness" bits + */ + bool bin = (vismode == USE_VISIBILITY); + uint32_t draw_initiator = DRAW_A20X(primtype, DI_FACE_CULL_NONE, + src_sel, idx_type, bin, bin, count); + uint32_t size = 2; + if (bin) + size += 2; + if (idx_buffer) + size += 2; + + OUT_PKT3(ring, bin ? CP_DRAW_INDX_BIN : CP_DRAW_INDX, size); OUT_RING(ring, 0x00000000); - OUT_RING(ring, DRAW_A20X(primtype, src_sel, idx_type, vismode, count)); + OUT_RING(ring, draw_initiator); + if (bin) { + OUT_RING(ring, batch->num_vertices); + OUT_RING(ring, count); + } } else { OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 5 : 3); OUT_RING(ring, 0x00000000); /* viz query info. */ @@ -103,7 +126,6 @@ fd_draw(struct fd_batch *batch, struct fd_ringbuffer *ring, fd_reset_wfi(batch); } - static inline enum pc_di_index_size size2indextype(unsigned index_size) { diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 30e3c6a735..5f18a90b03 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -115,15 +115,19 @@ static inline uint32_t DRAW(enum pc_di_primtype prim_type, } static inline uint32_t DRAW_A20X(enum pc_di_primtype prim_type, + enum pc_di_face_cull_sel faceness_cull_select, enum pc_di_src_sel source_select, enum pc_di_index_size index_size, - enum pc_di_vis_cull_mode vis_cull_mode, + bool pre_fetch_cull_enable, + bool grp_cull_enable, uint16_t count) { return (prim_type << 0) | (source_select << 6) | + (faceness_cull_select << 8) | ((index_size & 1) << 11) | ((index_size >> 1) << 13) | - (vis_cull_mode << 9) | + (pre_fetch_cull_enable << 14) | + (grp_cull_enable << 15) | (count << 16); } -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev