From: Marek Olšák Date: Sat, 29 Jan 2011 15:22:08 +0000 (+0100) Subject: r600g: rework vertex format fallback X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=73a40d1383071fe25599509d218f4c40d049988d;p=mesa.git r600g: rework vertex format fallback 1) Only translate the [min_index, max_index] range. 2) Upload translated vertices via the uploader. --- diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 301888abc78..cf4211cb8d3 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 4a2c7fe935c..2df8188f0a2 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 5f63af59ccc..4b88a9bfd46 100644 --- a/src/gallium/drivers/r600/r600_translate.c +++ b/src/gallium/drivers/r600/r600_translate.c @@ -22,13 +22,16 @@ * * Authors: Dave Airlie */ + #include "translate/translate_cache.h" #include "translate/translate.h" #include #include +#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: