[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