[Mesa-dev] [PATCH 01/11] freedreno: implement the USE_VISIBILITY case for a20x in fd_draw

Jonathan Marek jonathan at marek.ca
Mon Oct 8 04:06:01 UTC 2018


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 <jonathan at 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



More information about the mesa-dev mailing list