diff options
author | Yuanhan Liu <[email protected]> | 2011-12-31 14:22:46 +0800 |
---|---|---|
committer | Yuanhan Liu <[email protected]> | 2012-01-12 10:47:41 +0800 |
commit | 42d4972bf0b147b0241c2be7e6579fd64cf2c216 (patch) | |
tree | 923e2f914bb758aced9e692d0391f4fbf83f9ed7 /src/mesa/vbo/vbo_exec_array.c | |
parent | 459a44460e4d31d69d7ff04c1000917ca7870ff3 (diff) |
vbo: introduce vbo_get_minmax_indices function
Introduce vbo_get_minmax_indices() function to handle the min/max index
computation for nr_prims(>= 1). The old code just compute the first
prim's min/max index; this would results an error rendering if user
called functions like glMultiDrawElements(). This patch servers as
fixing this issue.
As when nr_prims = 1, we can pass 1 to paramter nr_prims, thus I made
vbo_get_minmax_index() static.
v2: per Roland's suggestion, put the indices address compuation into
vbo_get_minmax_index() instead.
Also do comination if possible to reduce map/unmap count
v3: per Brian's suggestion, use a pointer for start_prim to avoid
structure copy per loop.
Signed-off-by: Yuanhan Liu <[email protected]>
Reviewed-by: Roland Scheidegger <[email protected]>
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/mesa/vbo/vbo_exec_array.c')
-rw-r--r-- | src/mesa/vbo/vbo_exec_array.c | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index fec49d35e38..263e429ace2 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -99,24 +99,23 @@ vbo_sizeof_ib_type(GLenum type) * If primitive restart is enabled, we need to ignore restart * indexes when computing min/max. */ -void +static void vbo_get_minmax_index(struct gl_context *ctx, const struct _mesa_prim *prim, const struct _mesa_index_buffer *ib, - GLuint *min_index, GLuint *max_index) + GLuint *min_index, GLuint *max_index, + const GLuint count) { const GLboolean restart = ctx->Array.PrimitiveRestart; const GLuint restartIndex = ctx->Array.RestartIndex; - const GLuint count = prim->count; const void *indices; GLuint i; + indices = (void *)ib->ptr + prim->start * vbo_sizeof_ib_type(ib->type); if (_mesa_is_bufferobj(ib->obj)) { - indices = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) ib->ptr, - count * vbo_sizeof_ib_type(ib->type), - GL_MAP_READ_BIT, ib->obj); - } else { - indices = ib->ptr; + GLsizeiptr size = MIN2(count * vbo_sizeof_ib_type(ib->type), ib->obj->Size); + indices = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) indices, size, + GL_MAP_READ_BIT, ib->obj); } switch (ib->type) { @@ -196,6 +195,41 @@ vbo_get_minmax_index(struct gl_context *ctx, } } +/** + * Compute min and max elements for nr_prims + */ +void +vbo_get_minmax_indices(struct gl_context *ctx, + const struct _mesa_prim *prims, + const struct _mesa_index_buffer *ib, + GLuint *min_index, + GLuint *max_index, + GLuint nr_prims) +{ + GLuint tmp_min, tmp_max; + GLuint i; + GLuint count; + + *min_index = ~0; + *max_index = 0; + + for (i = 0; i < nr_prims; i++) { + const struct _mesa_prim *start_prim; + + start_prim = &prims[i]; + count = start_prim->count; + /* Do combination if possible to reduce map/unmap count */ + while ((i + 1 < nr_prims) && + (prims[i].start + prims[i].count == prims[i+1].start)) { + count += prims[i+1].count; + i++; + } + vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count); + *min_index = MIN2(*min_index, tmp_min); + *max_index = MAX2(*max_index, tmp_max); + } +} + /** * Check that element 'j' of the array has reasonable data. |