diff options
author | Marek Olšák <maraeo@gmail.com> | 2010-12-26 04:29:44 +0100 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2011-01-07 16:23:49 +0100 |
commit | be1af4394e060677b7db6bbb8e3301e38a3363da (patch) | |
tree | b344b38efd1e18a52a1be8a1dc21150d68cd63eb /src/gallium/drivers | |
parent | 2a7380e9c3a040356599a5b7740aa24e067fc1f5 (diff) |
r300g: derive user buffer sizes at draw time
This only uploads the [min_index, max_index] range instead of [0, userbuf size],
which greatly speeds up user buffer uploads.
This is also a prerequisite for atomizing vertex arrays in st/mesa.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 11 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 103 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_render_translate.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_screen_buffer.c | 41 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_screen_buffer.h | 10 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 38 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_transfer.c | 1 |
9 files changed, 144 insertions, 104 deletions
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 7ba8e710554..91263ad7bcd 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -90,6 +90,7 @@ static void r300_release_referenced_objects(struct r300_context *r300) /* Vertex buffers. */ for (i = 0; i < r300->vertex_buffer_count; i++) { pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL); + pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL); } /* If there are any queries pending or not destroyed, remove them now. */ diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 52556ec2a66..1a14d2b79e5 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -440,9 +440,6 @@ struct r300_translate_context { /* Translate cache for incompatible vertex offset/stride/format fallback. */ struct translate_cache *translate_cache; - /* The vertex buffer slot containing the translated buffer. */ - unsigned vb_slot; - /* Saved and new vertex element state. */ void *saved_velems, *new_velems; }; @@ -558,12 +555,15 @@ struct r300_context { struct r300_atom *first_dirty, *last_dirty; /* Vertex buffers for Gallium. */ + /* May contain user buffers. */ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + /* Contains only non-user buffers. */ + struct pipe_resource *valid_vertex_buffer[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; int vertex_buffer_max_index; + boolean any_user_vbs; /* Vertex elements for Gallium. */ struct r300_vertex_element_state *velems; - bool any_user_vbs; struct pipe_index_buffer index_buffer; @@ -683,7 +683,8 @@ void r300_resume_query(struct r300_context *r300, void r300_stop_query(struct r300_context *r300); /* r300_render_translate.c */ -void r300_begin_vertex_translate(struct r300_context *r300); +void r300_begin_vertex_translate(struct r300_context *r300, + int min_index, int max_index); void r300_end_vertex_translate(struct r300_context *r300); void r300_translate_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index f5e9f738374..41a12708cee 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -854,6 +854,7 @@ static void r300_update_vertex_arrays_cb(struct r300_context *r300, unsigned pac void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed) { struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; + struct pipe_resource **valid_vbuf = r300->valid_vertex_buffer; struct pipe_vertex_element *velem = r300->velems->velem; struct r300_buffer *buf; int i; @@ -897,7 +898,7 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde } for (i = 0; i < vertex_array_count; i++) { - buf = r300_buffer(vbuf[velem[i].vertex_buffer_index].buffer); + buf = r300_buffer(valid_vbuf[velem[i].vertex_buffer_index]); OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0); } END_CS; @@ -1224,9 +1225,7 @@ boolean r300_emit_buffer_validate(struct r300_context *r300, struct r300_textures_state *texstate = (struct r300_textures_state*)r300->textures_state.state; struct r300_texture* tex; - struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->velems->velem; - struct pipe_resource *pbuf; + struct pipe_resource **vbuf = r300->valid_vertex_buffer; unsigned i; /* Clean out BOs. */ @@ -1265,13 +1264,12 @@ boolean r300_emit_buffer_validate(struct r300_context *r300, r300_buffer(r300->vbo)->domain, 0); /* ...vertex buffers for HWTCL path... */ if (do_validate_vertex_buffers) { - for (i = 0; i < r300->velems->count; i++) { - pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!pbuf) + for (i = 0; i < r300->vertex_buffer_count; i++) { + if (!vbuf[i]) continue; - r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->cs_buf, - r300_buffer(pbuf)->domain, 0); + r300->rws->cs_add_buffer(r300->cs, r300_buffer(vbuf[i])->cs_buf, + r300_buffer(vbuf[i])->domain, 0); } } /* ...and index buffer for HWTCL path. */ diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 89f7892875e..dfa3045d649 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -236,12 +236,6 @@ static boolean r300_emit_states(struct r300_context *r300, /* Validate buffers and emit dirty state if needed. */ if (first_draw) { - /* upload buffers first */ - if (r300->screen->caps.has_tcl && r300->any_user_vbs) { - r300_upload_user_buffers(r300); - r300->any_user_vbs = false; - } - if (r300->validate_buffers) { if (!r300_emit_buffer_validate(r300, validate_vbos, index_buffer)) { @@ -256,7 +250,7 @@ static boolean r300_emit_states(struct r300_context *r300, if (r300->any_user_vbs) r300->upload_vb_validated = TRUE; if (r300->index_buffer.buffer && - r300_buffer_is_user_buffer(r300->index_buffer.buffer)) { + r300_is_user_buffer(r300->index_buffer.buffer)) { r300->upload_ib_validated = TRUE; } } @@ -308,7 +302,7 @@ static boolean immd_is_good_idea(struct r300_context *r300, unsigned count) { struct pipe_vertex_element* velem; - struct pipe_vertex_buffer* vbuf; + struct pipe_resource *buf; boolean checked[PIPE_MAX_ATTRIBS] = {0}; unsigned vertex_element_count = r300->velems->count; unsigned i, vbi; @@ -332,14 +326,13 @@ static boolean immd_is_good_idea(struct r300_context *r300, vbi = velem->vertex_buffer_index; if (!checked[vbi]) { - vbuf = &r300->vertex_buffer[vbi]; + buf = r300->valid_vertex_buffer[vbi]; - if (!(r300_buffer(vbuf->buffer)->domain & R300_DOMAIN_GTT)) { + if (!(r300_buffer(buf)->domain & R300_DOMAIN_GTT)) { return FALSE; } - if (r300_buffer_is_referenced(&r300->context, - vbuf->buffer, + if (r300_buffer_is_referenced(&r300->context, buf, R300_REF_CS | R300_REF_HW)) { /* It's a very bad idea to map it... */ return FALSE; @@ -398,7 +391,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, /* Map the buffer. */ if (!transfer[vbi]) { map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context, - vbuf->buffer, + r300->valid_vertex_buffer[vbi], PIPE_TRANSFER_READ, &transfer[vbi]); map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start; @@ -430,7 +423,6 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, vbi = r300->velems->velem[i].vertex_buffer_index; if (transfer[vbi]) { - vbuf = &r300->vertex_buffer[vbi]; pipe_buffer_unmap(&r300->context, transfer[vbi]); transfer[vbi] = NULL; } @@ -486,8 +478,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, return; } - maxIndex = MIN2(maxIndex, r300->vertex_buffer_max_index); - DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", count, minIndex, maxIndex); @@ -555,8 +545,6 @@ static void r300_emit_draw_elements(struct r300_context *r300, /* This is the fast-path drawing & emission for HW TCL. */ static void r300_draw_range_elements(struct pipe_context* pipe, - struct pipe_resource* indexBuffer, - unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, @@ -565,6 +553,8 @@ static void r300_draw_range_elements(struct pipe_context* pipe, unsigned count) { struct r300_context* r300 = r300_context(pipe); + struct pipe_resource *indexBuffer = r300->index_buffer.buffer; + unsigned indexSize = r300->index_buffer.index_size; struct pipe_resource* orgIndexBuffer = indexBuffer; boolean alt_num_verts = r300->screen->caps.is_r500 && count > 65536 && @@ -584,7 +574,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe, /* Fallback for misaligned ushort indices. */ if (indexSize == 2 && (start & 1) && - !r300_buffer_is_user_buffer(indexBuffer)) { + !r300_is_user_buffer(indexBuffer)) { struct pipe_transfer *transfer; struct pipe_resource *userbuf; @@ -598,7 +588,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe, * The start index will be aligned simply from the fact that * every sub-buffer in u_upload_mgr is aligned. */ userbuf = pipe->screen->user_buffer_create(pipe->screen, - ptr, count * 2, + ptr, 0, PIPE_BIND_INDEX_BUFFER); indexBuffer = userbuf; r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count); @@ -606,7 +596,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe, } pipe_buffer_unmap(pipe, transfer); } else { - if (r300_buffer_is_user_buffer(indexBuffer)) + if (r300_is_user_buffer(indexBuffer)) r300_upload_index_buffer(r300, &indexBuffer, indexSize, &start, count); } @@ -694,7 +684,8 @@ static void r300_draw_vbo(struct pipe_context* pipe, unsigned count = info->count; boolean translate = FALSE; boolean indexed = info->indexed && r300->index_buffer.buffer; - unsigned start_indexed = 0; + unsigned min_index = 0; + unsigned max_index = r300->vertex_buffer_max_index; if (r300->skip_rendering) { return; @@ -704,43 +695,61 @@ static void r300_draw_vbo(struct pipe_context* pipe, return; } - /* Index buffer range checking. */ if (indexed) { - assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); - - /* Compute start for draw_elements, taking the offset into account. */ - start_indexed = + int real_min_index, real_max_index; + /* Compute the start for draw_elements, taking the offset into account. */ + unsigned start_indexed = info->start + (r300->index_buffer.offset / r300->index_buffer.index_size); + assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); + + /* Index buffer range checking. */ if ((start_indexed + count) * r300->index_buffer.index_size > r300->index_buffer.buffer->width0) { fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n"); return; } - } - /* Set up fallback for incompatible vertex layout if needed. */ - if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { - r300_begin_vertex_translate(r300); - translate = TRUE; - } + min_index = MAX2(min_index, info->min_index); + max_index = MIN2(max_index, info->max_index); + real_min_index = (int)min_index - info->index_bias; + real_max_index = (int)max_index - info->index_bias; - if (indexed) { - r300_draw_range_elements(pipe, - r300->index_buffer.buffer, - r300->index_buffer.index_size, - info->index_bias, - info->min_index, - info->max_index, - info->mode, - start_indexed, - count); + if (max_index >= (1 << 24) - 1) { + fprintf(stderr, "r300: Invalid max_index: %i. Skipping rendering...\n", max_index); + return; + } + + /* Set up the fallback for an incompatible vertex layout if needed. */ + if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { + r300_begin_vertex_translate(r300, real_min_index, real_max_index); + translate = TRUE; + } + + /* Upload vertex buffers. */ + if (r300->any_user_vbs) { + r300_upload_user_buffers(r300, real_min_index, real_max_index); + } + + r300_draw_range_elements(pipe, info->index_bias, min_index, max_index, + info->mode, start_indexed, count); } else { - r300_draw_arrays(pipe, - info->mode, - info->start, - count); + min_index = MAX2(min_index, info->start); + max_index = MIN2(max_index, info->start + count - 1); + + /* Set up the fallback for an incompatible vertex layout if needed. */ + if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) { + r300_begin_vertex_translate(r300, min_index, max_index); + translate = TRUE; + } + + /* Upload vertex buffers. */ + if (r300->any_user_vbs) { + r300_upload_user_buffers(r300, min_index, max_index); + } + + r300_draw_arrays(pipe, info->mode, info->start, count); } if (translate) { diff --git a/src/gallium/drivers/r300/r300_render_translate.c b/src/gallium/drivers/r300/r300_render_translate.c index 26e00a2cad9..c48062c8084 100644 --- a/src/gallium/drivers/r300/r300_render_translate.c +++ b/src/gallium/drivers/r300/r300_render_translate.c @@ -31,7 +31,10 @@ #include "translate/translate.h" #include "util/u_index_modify.h" -void r300_begin_vertex_translate(struct r300_context *r300) +/* XXX Optimization: use min_index and translate only that range. */ +/* XXX Use the uploader. */ +void r300_begin_vertex_translate(struct r300_context *r300, + int min_index, int max_index) { struct pipe_context *pipe = &r300->context; struct translate_key key = {0}; @@ -44,6 +47,7 @@ void r300_begin_vertex_translate(struct r300_context *r300) struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}, *out_transfer; struct pipe_resource *out_buffer; unsigned i, num_verts; + unsigned slot; /* Initialize the translate key, i.e. the recipe how vertices should be * translated. */ @@ -108,12 +112,12 @@ void r300_begin_vertex_translate(struct r300_context *r300) 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, vb->max_index); + tr->set_buffer(tr, i, vb_map[i], vb->stride, max_index); } } /* Create and map the output buffer. */ - num_verts = r300->vertex_buffer_max_index + 1; + num_verts = max_index + 1; out_buffer = pipe_buffer_create(&r300->screen->screen, PIPE_BIND_VERTEX_BUFFER, @@ -135,19 +139,23 @@ void r300_begin_vertex_translate(struct r300_context *r300) pipe_buffer_unmap(pipe, out_transfer); /* Setup the new vertex buffer in the first free slot. */ + slot = ~0; for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { struct pipe_vertex_buffer *vb = &r300->vertex_buffer[i]; if (!vb->buffer) { - pipe_resource_reference(&vb->buffer, out_buffer); + pipe_resource_reference(&r300->valid_vertex_buffer[i], out_buffer); vb->buffer_offset = 0; - vb->max_index = num_verts - 1; vb->stride = key.output_stride; - r300->tran.vb_slot = i; + slot = i; + /* XXX probably need to preserve the real count for u_blitter_save_*. */ + r300->vertex_buffer_count = MAX2(r300->vertex_buffer_count, i+1); r300->validate_buffers = TRUE; break; } } + /* XXX This may fail. */ + assert(slot != ~0); /* Save and replace vertex elements. */ { @@ -161,7 +169,7 @@ void r300_begin_vertex_translate(struct r300_context *r300) new_velems[i].instance_divisor = ve->velem[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 = r300->tran.vb_slot; + new_velems[i].vertex_buffer_index = slot; } else { memcpy(&new_velems[i], &ve->velem[i], sizeof(struct pipe_vertex_element)); @@ -183,12 +191,9 @@ void r300_end_vertex_translate(struct r300_context *r300) /* Restore vertex elements. */ pipe->bind_vertex_elements_state(pipe, r300->tran.saved_velems); pipe->delete_vertex_elements_state(pipe, r300->tran.new_velems); - - /* Delete the now-unused VBO. */ - pipe_resource_reference(&r300->vertex_buffer[r300->tran.vb_slot].buffer, - NULL); } +/* XXX Use the uploader. */ void r300_translate_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, unsigned *index_size, unsigned index_offset, diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index d2cfaad8a57..e3cf45479fd 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -40,7 +40,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context, struct r300_context *r300 = r300_context(context); struct r300_buffer *rbuf = r300_buffer(buf); - if (r300_buffer_is_user_buffer(buf)) + if (r300_is_user_buffer(buf)) return PIPE_UNREFERENCED; if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain)) @@ -81,20 +81,36 @@ void r300_upload_index_buffer(struct r300_context *r300, } } -void r300_upload_user_buffers(struct r300_context *r300) +void r300_upload_user_buffers(struct r300_context *r300, + int min_index, int max_index) { int i, nr = r300->velems->count; + unsigned count = max_index + 1 - min_index; boolean flushed; for (i = 0; i < nr; i++) { - struct pipe_vertex_buffer *vb = - &r300->vertex_buffer[r300->velems->velem[i].vertex_buffer_index]; + unsigned index = r300->velems->velem[i].vertex_buffer_index; + struct pipe_vertex_buffer *vb = &r300->vertex_buffer[index]; + struct r300_buffer *userbuf = r300_buffer(vb->buffer); + + if (userbuf && userbuf->user_buffer) { + unsigned first, size; + + if (vb->stride) { + first = vb->stride * min_index; + size = vb->stride * count; + } else { + first = 0; + size = r300->velems->hw_format_size[i]; + } + + u_upload_data(r300->upload_vb, first, size, + userbuf->user_buffer + first, + &vb->buffer_offset, + &r300->valid_vertex_buffer[index], + &flushed); - if (r300_buffer_is_user_buffer(vb->buffer)) { - u_upload_data(r300->upload_vb, - 0, vb->buffer->width0, - r300_buffer(vb->buffer)->user_buffer, - &vb->buffer_offset, &vb->buffer, &flushed); + vb->buffer_offset -= first; r300->vertex_arrays_dirty = TRUE; @@ -102,6 +118,8 @@ void r300_upload_user_buffers(struct r300_context *r300) r300->upload_vb_validated = FALSE; r300->validate_buffers = TRUE; } + } else { + assert(r300->valid_vertex_buffer[index]); } } } @@ -280,8 +298,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, } struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, + void *ptr, unsigned size, unsigned bind) { struct r300_screen *r300screen = r300_screen(screen); @@ -298,7 +315,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE; rbuf->b.b.bind = bind; - rbuf->b.b.width0 = bytes; + rbuf->b.b.width0 = ~0; rbuf->b.b.height0 = 1; rbuf->b.b.depth0 = 1; rbuf->b.b.array_size = 1; diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h index 70ffcf506c6..58dec8539b6 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -61,7 +61,8 @@ struct r300_buffer /* Functions. */ -void r300_upload_user_buffers(struct r300_context *r300); +void r300_upload_user_buffers(struct r300_context *r300, + int min_index, int max_index); void r300_upload_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, @@ -72,9 +73,8 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ); struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, - unsigned usage); + void *ptr, unsigned size, + unsigned bind); unsigned r300_buffer_is_referenced(struct pipe_context *context, struct pipe_resource *buf, @@ -87,7 +87,7 @@ static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer) return (struct r300_buffer *)buffer; } -static INLINE boolean r300_buffer_is_user_buffer(struct pipe_resource *buffer) +static INLINE boolean r300_is_user_buffer(struct pipe_resource *buffer) { return r300_buffer(buffer)->user_buffer ? true : false; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 01af633622a..b55262a9522 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1465,7 +1465,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); - struct pipe_vertex_buffer *vbo; + const struct pipe_vertex_buffer *vbo; unsigned i, max_index = (1 << 24) - 1; boolean any_user_buffer = FALSE; boolean any_nonuser_buffer = FALSE; @@ -1474,7 +1474,6 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, /* There must be at least one vertex buffer set, otherwise it locks up. */ if (!count) { dummy_vb.buffer = r300->dummy_vb; - dummy_vb.max_index = r300->dummy_vb->width0 / 4; buffers = &dummy_vb; count = 1; } @@ -1501,16 +1500,18 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, } for (i = 0; i < count; i++) { - /* Why, yes, I AM casting away constness. How did you know? */ - vbo = (struct pipe_vertex_buffer*)&buffers[i]; + vbo = &buffers[i]; /* Skip NULL buffers */ - if (!buffers[i].buffer) { + if (!vbo->buffer) { continue; } - if (r300_buffer_is_user_buffer(vbo->buffer)) { + /* User buffers have no info about maximum index, + * we will have to compute it in draw_vbo. */ + if (r300_is_user_buffer(vbo->buffer)) { any_user_buffer = TRUE; + continue; } any_nonuser_buffer = TRUE; @@ -1519,12 +1520,12 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, if (!vbo->stride) continue; - if (vbo->max_index == ~0) { - vbo->max_index = - (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; + /* Update the maximum index. */ + { + unsigned vbo_max_index = + (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride; + max_index = MIN2(max_index, vbo_max_index); } - - max_index = MIN2(vbo->max_index, max_index); } r300->any_user_vbs = any_user_buffer; @@ -1541,16 +1542,25 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, /* Common code. */ for (i = 0; i < count; i++) { + vbo = &buffers[i]; + /* Reference our buffer. */ - pipe_resource_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer); + pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer); + if (vbo->buffer && r300_is_user_buffer(vbo->buffer)) { + pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL); + } else { + pipe_resource_reference(&r300->valid_vertex_buffer[i], vbo->buffer); + } } for (; i < r300->vertex_buffer_count; i++) { /* Dereference any old buffers. */ pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL); + pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL); } memcpy(r300->vertex_buffer, buffers, - sizeof(struct pipe_vertex_buffer) * count); + sizeof(struct pipe_vertex_buffer) * count); + r300->vertex_buffer_count = count; } @@ -1564,7 +1574,7 @@ static void r300_set_index_buffer(struct pipe_context* pipe, memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer)); if (r300->screen->caps.has_tcl && - !r300_buffer_is_user_buffer(ib->buffer)) { + !r300_is_user_buffer(ib->buffer)) { r300->validate_buffers = TRUE; r300->upload_ib_validated = FALSE; } diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 3b95af79bcf..ae93fab554e 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -120,7 +120,6 @@ r300_texture_get_transfer(struct pipe_context *ctx, base.format = texture->format; base.width0 = box->width; base.height0 = box->height; - /* XXX: was depth0 = 0 */ base.depth0 = 1; base.array_size = 1; base.last_level = 0; |