Mesa (master): r600g: rework vertex format fallback

Marek Olšák mareko at kemper.freedesktop.org
Sun Jan 30 02:30:41 UTC 2011


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Jan 29 16:22:08 2011 +0100

r600g: rework vertex format fallback

1) Only translate the [min_index, max_index] range.
2) Upload translated vertices via the uploader.

---

 src/gallium/drivers/r600/r600_pipe.h         |    3 +-
 src/gallium/drivers/r600/r600_state_common.c |    2 +-
 src/gallium/drivers/r600/r600_translate.c    |   97 ++++++++++++++------------
 3 files changed, 55 insertions(+), 47 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 301888a..cf4211c 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -251,7 +251,8 @@ unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
 					unsigned level, unsigned layer);
 
 /* r600_translate.c */
-void r600_begin_vertex_translate(struct r600_pipe_context *rctx);
+void r600_begin_vertex_translate(struct r600_pipe_context *rctx,
+                                 int min_index, int max_index);
 void r600_end_vertex_translate(struct r600_pipe_context *rctx);
 void r600_translate_index_buffer(struct r600_pipe_context *r600,
 				 struct pipe_resource **index_buffer,
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 4a2c7fe..2df8188 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -497,7 +497,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 	unsigned prim;
 
 	if (rctx->vertex_elements->incompatible_layout) {
-		r600_begin_vertex_translate(rctx);
+		r600_begin_vertex_translate(rctx, info->min_index, info->max_index);
 	}
 
 	if (rctx->any_user_vbs) {
diff --git a/src/gallium/drivers/r600/r600_translate.c b/src/gallium/drivers/r600/r600_translate.c
index 5f63af5..4b88a9b 100644
--- a/src/gallium/drivers/r600/r600_translate.c
+++ b/src/gallium/drivers/r600/r600_translate.c
@@ -22,13 +22,16 @@
  *
  * Authors: Dave Airlie <airlied at redhat.com>
  */
+
 #include "translate/translate_cache.h"
 #include "translate/translate.h"
 #include <pipebuffer/pb_buffer.h>
 #include <util/u_index_modify.h>
+#include "util/u_upload_mgr.h"
 #include "r600_pipe.h"
 
-void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
+void r600_begin_vertex_translate(struct r600_pipe_context *rctx,
+                                 int min_index, int max_index)
 {
 	struct pipe_context *pipe = &rctx->context;
 	struct translate_key key = {0};
@@ -37,18 +40,16 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
 	struct translate *tr;
 	struct r600_vertex_element *ve = rctx->vertex_elements;
 	boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
-	void *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
-	struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer;
-	struct pipe_resource *out_buffer;
-	unsigned i, num_verts;
+	uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
+	struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
+	struct pipe_resource *out_buffer = NULL;
+	unsigned i, num_verts, out_offset;
 	struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
-	void *tmp;
+	boolean flushed;
 
 	/* Initialize the translate key, i.e. the recipe how vertices should be
 	 * translated. */
 	for (i = 0; i < ve->count; i++) {
-		struct pipe_vertex_buffer *vb =
-			&rctx->vertex_buffer[ve->elements[i].vertex_buffer_index];
 		enum pipe_format output_format = ve->hw_format[i];
 		unsigned output_format_size = ve->hw_format_size[i];
 
@@ -81,10 +82,10 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
 		/* Add this vertex element. */
 		te = &key.element[key.nr_elements];
 		/*te->type;
-		  te->instance_divisor;*/
+		te->instance_divisor;*/
 		te->input_buffer = ve->elements[i].vertex_buffer_index;
 		te->input_format = ve->elements[i].src_format;
-		te->input_offset = vb->buffer_offset + ve->elements[i].src_offset;
+		te->input_offset = ve->elements[i].src_offset;
 		te->output_format = output_format;
 		te->output_offset = key.output_stride;
 
@@ -105,19 +106,22 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
 			vb_map[i] = pipe_buffer_map(pipe, vb->buffer,
 						    PIPE_TRANSFER_READ, &vb_transfer[i]);
 
-			tr->set_buffer(tr, i, vb_map[i], vb->stride, ~0);
+			tr->set_buffer(tr, i,
+				       vb_map[i] + vb->buffer_offset + vb->stride * min_index,
+				       vb->stride, ~0);
 		}
 	}
 
 	/* Create and map the output buffer. */
-	num_verts = rctx->vb_max_index + 1;
+	num_verts = max_index + 1 - min_index;
 
-	out_buffer = pipe_buffer_create(&rctx->screen->screen,
-					PIPE_BIND_VERTEX_BUFFER,
-					key.output_stride * num_verts);
+	u_upload_alloc(rctx->upload_vb,
+		       key.output_stride * min_index,
+		       key.output_stride * num_verts,
+		       &out_offset, &out_buffer, &flushed,
+		       (void**)&out_map);
 
-	out_map = pipe_buffer_map(pipe, out_buffer, PIPE_TRANSFER_WRITE,
-				  &out_transfer);
+	out_offset -= key.output_stride * min_index;
 
 	/* Translate. */
 	tr->run(tr, 0, num_verts, 0, out_map);
@@ -129,16 +133,10 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
 		}
 	}
 
-	pipe_buffer_unmap(pipe, out_transfer);
-
-	/* Setup the new vertex buffer in the first free slot. */
+	/* Find the first free slot. */
+	rctx->tran.vb_slot = ~0;
 	for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
-		struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[i];
-
-		if (!vb->buffer) {
-			pipe_resource_reference(&rctx->real_vertex_buffer[i], out_buffer);
-			vb->buffer_offset = 0;
-			vb->stride = key.output_stride;
+		if (!rctx->vertex_buffer[i].buffer) {
 			rctx->tran.vb_slot = i;
 
 			if (i >= rctx->nvertex_buffers) {
@@ -148,24 +146,31 @@ void r600_begin_vertex_translate(struct r600_pipe_context *rctx)
 		}
 	}
 
-	/* Save and replace vertex elements. */
-	for (i = 0; i < ve->count; i++) {
-		if (vb_translated[ve->elements[i].vertex_buffer_index]) {
-			te = &key.element[tr_elem_index[i]];
-			new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
-			new_velems[i].src_format = te->output_format;
-			new_velems[i].src_offset = te->output_offset;
-			new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
-		} else {
-			memcpy(&new_velems[i], &ve->elements[i],
-					sizeof(struct pipe_vertex_element));
+	if (rctx->tran.vb_slot != ~0) {
+		/* Setup the new vertex buffer. */
+		pipe_resource_reference(&rctx->real_vertex_buffer[rctx->tran.vb_slot], out_buffer);
+		rctx->vertex_buffer[rctx->tran.vb_slot].buffer_offset = out_offset;
+		rctx->vertex_buffer[rctx->tran.vb_slot].stride = key.output_stride;
+
+		/* Setup new vertex elements. */
+		for (i = 0; i < ve->count; i++) {
+			if (vb_translated[ve->elements[i].vertex_buffer_index]) {
+				te = &key.element[tr_elem_index[i]];
+				new_velems[i].instance_divisor = ve->elements[i].instance_divisor;
+				new_velems[i].src_format = te->output_format;
+				new_velems[i].src_offset = te->output_offset;
+				new_velems[i].vertex_buffer_index = rctx->tran.vb_slot;
+			} else {
+				memcpy(&new_velems[i], &ve->elements[i],
+				       sizeof(struct pipe_vertex_element));
+			}
 		}
-	}
 
-	rctx->tran.saved_velems = rctx->vertex_elements;
-	tmp = pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
-	pipe->bind_vertex_elements_state(pipe, tmp);
-	rctx->tran.new_velems = tmp;
+		rctx->tran.saved_velems = rctx->vertex_elements;
+		rctx->tran.new_velems =
+				pipe->create_vertex_elements_state(pipe, ve->count, new_velems);
+		pipe->bind_vertex_elements_state(pipe, rctx->tran.new_velems);
+	}
 
 	pipe_resource_reference(&out_buffer, NULL);
 }
@@ -177,6 +182,7 @@ void r600_end_vertex_translate(struct r600_pipe_context *rctx)
 	if (rctx->tran.new_velems == NULL) {
 		return;
 	}
+
 	/* Restore vertex elements. */
 	pipe->bind_vertex_elements_state(pipe, rctx->tran.saved_velems);
 	rctx->tran.saved_velems = NULL;
@@ -188,10 +194,11 @@ void r600_end_vertex_translate(struct r600_pipe_context *rctx)
 	rctx->nreal_vertex_buffers = rctx->nvertex_buffers;
 }
 
+/* XXX Use the uploader. */
 void r600_translate_index_buffer(struct r600_pipe_context *r600,
-					struct pipe_resource **index_buffer,
-					unsigned *index_size,
-					unsigned *start, unsigned count)
+				 struct pipe_resource **index_buffer,
+				 unsigned *index_size,
+				 unsigned *start, unsigned count)
 {
 	switch (*index_size) {
 	case 1:




More information about the mesa-commit mailing list