Mesa (master): freedreno: fix indexbuffer upload

Rob Clark robclark at kemper.freedesktop.org
Sun May 14 19:10:37 UTC 2017


Module: Mesa
Branch: master
Commit: 06a51fb4e5bcec4fa9911b6a20a38deac45d9e21
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=06a51fb4e5bcec4fa9911b6a20a38deac45d9e21

Author: Rob Clark <robdclark at gmail.com>
Date:   Sat May 13 14:43:45 2017 -0400

freedreno: fix indexbuffer upload

My fault for not having time to test Marek's patches while they were on
list.

Fixes: 330d0607 ("gallium: remove pipe_index_buffer and set_index_buffer")
Signed-off-by: Rob Clark <robdclark at gmail.com>

---

 src/gallium/drivers/freedreno/a2xx/fd2_draw.c  |  2 +-
 src/gallium/drivers/freedreno/a3xx/fd3_draw.c  |  8 ++++----
 src/gallium/drivers/freedreno/a4xx/fd4_draw.h  |  2 +-
 src/gallium/drivers/freedreno/a5xx/fd5_draw.h  |  2 +-
 src/gallium/drivers/freedreno/freedreno_draw.c | 22 ++++++++++++++++------
 src/gallium/drivers/freedreno/freedreno_draw.h |  5 +++--
 6 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
index 4f31619088..f7915d66c1 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c
@@ -109,7 +109,7 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 	OUT_RING(ring, info->min_index);        /* VGT_MIN_VTX_INDX */
 
 	fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode],
-				 IGNORE_VISIBILITY, info);
+				 IGNORE_VISIBILITY, info, index_offset);
 
 	OUT_PKT3(ring, CP_SET_CONSTANT, 2);
 	OUT_RING(ring, CP_REG(REG_A2XX_UNKNOWN_2010));
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
index 270322453e..761f25bc01 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c
@@ -55,7 +55,7 @@ add_sat(uint32_t a, int32_t b)
 
 static void
 draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
-		struct fd3_emit *emit)
+		struct fd3_emit *emit, unsigned index_offset)
 {
 	const struct pipe_draw_info *info = emit->info;
 	enum pc_di_primtype primtype = ctx->primtypes[info->mode];
@@ -86,7 +86,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
 
 	fd_draw_emit(ctx->batch, ring, primtype,
 			emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
-			info);
+			info, index_offset);
 }
 
 /* fixup dirty shader state in case some "unrelated" (from the state-
@@ -157,14 +157,14 @@ fd3_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
 
 	emit.key.binning_pass = false;
 	emit.dirty = dirty;
-	draw_impl(ctx, ctx->batch->draw, &emit);
+	draw_impl(ctx, ctx->batch->draw, &emit, index_offset);
 
 	/* and now binning pass: */
 	emit.key.binning_pass = true;
 	emit.dirty = dirty & ~(FD_DIRTY_BLEND);
 	emit.vp = NULL;   /* we changed key so need to refetch vp */
 	emit.fp = NULL;
-	draw_impl(ctx, ctx->batch->binning, &emit);
+	draw_impl(ctx, ctx->batch->binning, &emit, index_offset);
 
 	fd_context_all_clean(ctx);
 
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.h b/src/gallium/drivers/freedreno/a4xx/fd4_draw.h
index 950675f43f..842a952719 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.h
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.h
@@ -105,7 +105,7 @@ fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
 		enum pc_di_primtype primtype,
 		enum pc_di_vis_cull_mode vismode,
 		const struct pipe_draw_info *info,
-                unsigned index_offset)
+		unsigned index_offset)
 {
 	struct pipe_resource *idx_buffer = NULL;
 	enum a4xx_index_size idx_type;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.h b/src/gallium/drivers/freedreno/a5xx/fd5_draw.h
index 5baf1676f1..de210e4565 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.h
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.h
@@ -81,7 +81,7 @@ fd5_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
 		enum pc_di_primtype primtype,
 		enum pc_di_vis_cull_mode vismode,
 		const struct pipe_draw_info *info,
-                unsigned index_offset)
+		unsigned index_offset)
 {
 	struct pipe_resource *idx_buffer = NULL;
 	enum a4xx_index_size idx_type;
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 1d86a49dd4..08cba77751 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -91,11 +91,20 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 	}
 
 	/* Upload a user index buffer. */
-	struct pipe_resource *indexbuf = info->has_user_indices ? NULL : info->index.resource;
-        unsigned index_offset = 0;
-	if (info->index_size && info->has_user_indices &&
-	    !util_upload_index_buffer(pctx, info, &indexbuf, &index_offset)) {
-		return;
+	struct pipe_resource *indexbuf = NULL;
+	unsigned index_offset = 0;
+	struct pipe_draw_info new_info;
+	if (info->index_size) {
+		if (info->has_user_indices) {
+			if (!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset))
+				return;
+			new_info = *info;
+			new_info.index.resource = indexbuf;
+			new_info.has_user_indices = false;
+			info = &new_info;
+		} else {
+			indexbuf = info->index.resource;
+		}
 	}
 
 	if (ctx->in_blit) {
@@ -224,7 +233,8 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 		fd_context_all_dirty(ctx);
 
 	fd_batch_check_size(batch);
-	if (info->index_size && indexbuf != info->index.resource)
+
+	if (info == &new_info)
 		pipe_resource_reference(&indexbuf, NULL);
 }
 
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h
index f2163bb10d..b293f73b82 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.h
+++ b/src/gallium/drivers/freedreno/freedreno_draw.h
@@ -115,7 +115,8 @@ static inline void
 fd_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
 		enum pc_di_primtype primtype,
 		enum pc_di_vis_cull_mode vismode,
-		const struct pipe_draw_info *info)
+		const struct pipe_draw_info *info,
+		unsigned index_offset)
 {
 	struct pipe_resource *idx_buffer = NULL;
 	enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
@@ -128,7 +129,7 @@ fd_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring,
 		idx_buffer = info->index.resource;
 		idx_type = size2indextype(info->index_size);
 		idx_size = info->index_size * info->count;
-		idx_offset = info->start * info->index_size;
+		idx_offset = index_offset + info->start * info->index_size;
 		src_sel = DI_SRC_SEL_DMA;
 	} else {
 		idx_buffer = NULL;




More information about the mesa-commit mailing list