[Mesa-dev] [PATCH 2/2] r600g: Emit vertex buffers using the same method as constant buffers

Tom Stellard tstellar at gmail.com
Thu Jul 12 12:50:28 PDT 2012


---
 src/gallium/drivers/r600/evergreen_compute.c |    8 +++--
 src/gallium/drivers/r600/evergreen_state.c   |   45 ++++++++++++++++---------
 src/gallium/drivers/r600/r600_buffer.c       |    5 ++-
 src/gallium/drivers/r600/r600_hw_context.c   |    2 +-
 src/gallium/drivers/r600/r600_pipe.h         |   10 ++++-
 src/gallium/drivers/r600/r600_state.c        |    2 +-
 src/gallium/drivers/r600/r600_state_common.c |    9 ++++-
 7 files changed, 55 insertions(+), 26 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index b61ea8f..947a328 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -90,13 +90,15 @@ static void evergreen_cs_set_vertex_buffer(
 	struct pipe_resource * buffer)
 {
 	struct pipe_vertex_buffer *vb = &rctx->cs_vertex_buffer[vb_index];
+	struct r600_vertexbuf_state * state = &rctx->cs_vertex_buffer_state;
 	vb->stride = 1;
 	vb->buffer_offset = offset;
 	vb->buffer = buffer;
 	vb->user_buffer = NULL;
 
 	r600_inval_vertex_cache(rctx);
-	r600_atom_dirty(rctx, &rctx->cs_vertex_buffer_state);
+	state->dirty_mask |= 1 << vb_index;
+	r600_atom_dirty(rctx, &state->atom);
 }
 
 const struct u_resource_vtbl r600_global_buffer_vtbl =
@@ -367,8 +369,8 @@ static void compute_emit_cs(struct r600_context *ctx)
 	r600_context_pipe_state_emit(ctx, cb_state, RADEON_CP_PACKET3_COMPUTE_MODE);
 
 	/* Emit vertex buffer state */
-	ctx->cs_vertex_buffer_state.num_dw = 12 * ctx->nr_cs_vertex_buffers;
-	r600_emit_atom(ctx, &ctx->cs_vertex_buffer_state);
+	ctx->cs_vertex_buffer_state.atom.num_dw = 12 * ctx->nr_cs_vertex_buffers;
+	r600_emit_atom(ctx, &ctx->cs_vertex_buffer_state.atom);
 
 	for (i = 0; i < get_compute_resource_num(); i++) {
 		if (ctx->cs_shader->resources[i].enabled) {
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index ab78f58..592acfb 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1765,32 +1765,39 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_
 	r600_write_context_reg(cs, R_02800C_DB_RENDER_OVERRIDE, db_render_override);
 }
 
-static void evergreen_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom *atom,
-	struct pipe_vertex_buffer *vb, unsigned vb_count, unsigned resource_offset,
-	unsigned pkt_flags)
+static void evergreen_emit_vertex_buffers(struct r600_context *rctx,
+					  struct r600_vertexbuf_state *state,
+					  struct pipe_vertex_buffer *vertex_buffers,
+					  unsigned vb_count,
+					  unsigned resource_offset,
+					  unsigned pkt_flags)
 {
 	struct radeon_winsys_cs *cs = rctx->cs;
-	unsigned i;
-	uint64_t va;
+	uint32_t dirty_mask = state->dirty_mask;
 
-	for (i = 0; i < vb_count; i++) {
-		struct r600_resource *rbuffer = (struct r600_resource*)vb[i].buffer;
+	while (dirty_mask) {
+		struct pipe_vertex_buffer *vb;
+		struct r600_resource *rbuffer;
+		uint64_t va;
+		unsigned buffer_index = ffs(dirty_mask) - 1;
 
+		vb = &vertex_buffers[buffer_index];
+		rbuffer = (struct r600_resource*)vb->buffer;
 		if (!rbuffer) {
-			continue;
+			goto next;
 		}
 
 		va = r600_resource_va(&rctx->screen->screen, &rbuffer->b.b);
-		va += vb[i].buffer_offset;
+		va += vb->buffer_offset;
 
 		/* fetch resources start at index 992 */
 		r600_write_value(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags);
-		r600_write_value(cs, (resource_offset + i) * 8);
+		r600_write_value(cs, (resource_offset + buffer_index) * 8);
 		r600_write_value(cs, va); /* RESOURCEi_WORD0 */
-		r600_write_value(cs, rbuffer->buf->size - vb[i].buffer_offset - 1); /* RESOURCEi_WORD1 */
+		r600_write_value(cs, rbuffer->buf->size - vb->buffer_offset - 1); /* RESOURCEi_WORD1 */
 		r600_write_value(cs, /* RESOURCEi_WORD2 */
 				 S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
-				 S_030008_STRIDE(vb[i].stride) |
+				 S_030008_STRIDE(vb->stride) |
 				 S_030008_BASE_ADDRESS_HI(va >> 32UL));
 		r600_write_value(cs, /* RESOURCEi_WORD3 */
 				 S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
@@ -1804,18 +1811,24 @@ static void evergreen_emit_vertex_buffers(struct r600_context *rctx, struct r600
 
 		r600_write_value(cs, PKT3(PKT3_NOP, 0, 0) | pkt_flags);
 		r600_write_value(cs, r600_context_bo_reloc(rctx, rbuffer, RADEON_USAGE_READ));
+
+next:
+		dirty_mask &= ~(1 << buffer_index);
 	}
+	state->dirty_mask = 0;
 }
 
 static void evergreen_fs_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom * atom)
 {
-	evergreen_emit_vertex_buffers(rctx, atom, rctx->vertex_buffer,
+	evergreen_emit_vertex_buffers(rctx, &rctx->vertex_buffer_state,
+					rctx->vertex_buffer,
 					rctx->nr_vertex_buffers, 992, 0);
 }
 
 static void evergreen_cs_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom * atom)
 {
-	evergreen_emit_vertex_buffers(rctx, atom, rctx->cs_vertex_buffer,
+	evergreen_emit_vertex_buffers(rctx, &rctx->cs_vertex_buffer_state,
+					rctx->cs_vertex_buffer,
 					rctx->nr_cs_vertex_buffers, 816,
 					RADEON_CP_PACKET3_COMPUTE_MODE);
 }
@@ -1895,8 +1908,8 @@ void evergreen_init_state_functions(struct r600_context *rctx)
 	r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
 	r600_init_atom(&rctx->db_misc_state.atom, evergreen_emit_db_misc_state, 6, 0);
 	r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
-	r600_init_atom(&rctx->vertex_buffer_state, evergreen_fs_emit_vertex_buffers, 0, 0);
-	r600_init_atom(&rctx->cs_vertex_buffer_state, evergreen_cs_emit_vertex_buffers, 0, 0);
+	r600_init_atom(&rctx->vertex_buffer_state.atom, evergreen_fs_emit_vertex_buffers, 0, 0);
+	r600_init_atom(&rctx->cs_vertex_buffer_state.atom, evergreen_cs_emit_vertex_buffers, 0, 0);
 	r600_init_atom(&rctx->vs_constbuf_state.atom, evergreen_emit_vs_constant_buffer, 0, 0);
 	r600_init_atom(&rctx->ps_constbuf_state.atom, evergreen_emit_ps_constant_buffer, 0, 0);
 
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index 3d7d1f0..8e2deb1 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -107,8 +107,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
 			/* Vertex buffers. */
 			for (i = 0; i < rctx->nr_vertex_buffers; i++) {
 				if (rctx->vertex_buffer[i].buffer == &rbuffer->b.b) {
+					struct r600_vertexbuf_state * state =
+						&rctx->vertex_buffer_state;
+					state->dirty_mask |= 1 << i;
 					r600_inval_vertex_cache(rctx);
-					r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
+					r600_atom_dirty(rctx, &state->atom);
 				}
 			}
 			/* Streamout buffers. */
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index b236069..e80f39c 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -1282,7 +1282,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
 	/* Re-emit states. */
 	r600_atom_dirty(ctx, &ctx->cb_misc_state.atom);
 	r600_atom_dirty(ctx, &ctx->db_misc_state.atom);
-	r600_atom_dirty(ctx, &ctx->vertex_buffer_state);
+	r600_atom_dirty(ctx, &ctx->vertex_buffer_state.atom);
 
 	ctx->vs_constbuf_state.dirty_mask = ctx->vs_constbuf_state.enabled_mask;
 	ctx->ps_constbuf_state.dirty_mask = ctx->ps_constbuf_state.enabled_mask;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index ba63dcc..0581040 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -276,6 +276,12 @@ struct r600_constbuf_state
 	uint32_t			dirty_mask;
 };
 
+struct r600_vertexbuf_state
+{
+	struct r600_atom		atom;
+	uint32_t			dirty_mask;
+};
+
 struct r600_context {
 	struct pipe_context		context;
 	struct blitter_context		*blitter;
@@ -337,9 +343,9 @@ struct r600_context {
 	struct r600_cb_misc_state	cb_misc_state;
 	struct r600_db_misc_state	db_misc_state;
 	/** Vertex buffers for fetch shaders */
-	struct r600_atom		vertex_buffer_state;
+	struct r600_vertexbuf_state	vertex_buffer_state;
 	/** Vertex buffers for compute shaders */
-	struct r600_atom		cs_vertex_buffer_state;
+	struct r600_vertexbuf_state	cs_vertex_buffer_state;
 	struct r600_constbuf_state	vs_constbuf_state;
 	struct r600_constbuf_state	ps_constbuf_state;
 
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 6c0c0fe..2f4c157 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1847,7 +1847,7 @@ void r600_init_state_functions(struct r600_context *rctx)
 	r600_atom_dirty(rctx, &rctx->cb_misc_state.atom);
 	r600_init_atom(&rctx->db_misc_state.atom, r600_emit_db_misc_state, 4, 0);
 	r600_atom_dirty(rctx, &rctx->db_misc_state.atom);
-	r600_init_atom(&rctx->vertex_buffer_state, r600_emit_vertex_buffers, 0, 0);
+	r600_init_atom(&rctx->vertex_buffer_state.atom, r600_emit_vertex_buffers, 0, 0);
 	r600_init_atom(&rctx->vs_constbuf_state.atom, r600_emit_vs_constant_buffer, 0, 0);
 	r600_init_atom(&rctx->ps_constbuf_state.atom, r600_emit_ps_constant_buffer, 0, 0);
 
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index d952220..be3d101 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -407,13 +407,18 @@ void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count,
 			     const struct pipe_vertex_buffer *buffers)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
+	struct r600_vertexbuf_state * state = &rctx->vertex_buffer_state;
+	unsigned i;
 
 	util_copy_vertex_buffers(rctx->vertex_buffer, &rctx->nr_vertex_buffers, buffers, count);
 
 	r600_inval_vertex_cache(rctx);
-	rctx->vertex_buffer_state.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
+	state->atom.num_dw = (rctx->chip_class >= EVERGREEN ? 12 : 10) *
 					   rctx->nr_vertex_buffers;
-	r600_atom_dirty(rctx, &rctx->vertex_buffer_state);
+	for (i = 0 ; i < rctx->nr_vertex_buffers; i++) {
+		state->dirty_mask |= 1 << i;
+	}
+	r600_atom_dirty(rctx, &state->atom);
 }
 
 void *r600_create_vertex_elements(struct pipe_context *ctx,
-- 
1.7.7.6



More information about the mesa-dev mailing list