mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
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 <yuanhan.liu@linux.intel.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
459a44460e
commit
42d4972bf0
8 changed files with 53 additions and 17 deletions
|
|
@ -586,7 +586,7 @@ void brw_draw_prims( struct gl_context *ctx,
|
|||
|
||||
if (!vbo_all_varyings_in_vbos(arrays)) {
|
||||
if (!index_bounds_valid)
|
||||
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
|
||||
vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);
|
||||
|
||||
/* Decide if we want to rebase. If so we end up recursing once
|
||||
* only into this function.
|
||||
|
|
|
|||
|
|
@ -437,7 +437,8 @@ TAG(vbo_render_prims)(struct gl_context *ctx,
|
|||
struct nouveau_render_state *render = to_render_state(ctx);
|
||||
|
||||
if (!index_bounds_valid)
|
||||
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
||||
vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
|
||||
nr_prims);
|
||||
|
||||
vbo_choose_render_mode(ctx, arrays);
|
||||
vbo_choose_attrs(ctx, arrays);
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type,
|
|||
ib.ptr = indices;
|
||||
ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
|
||||
|
||||
vbo_get_minmax_index(ctx, &prim, &ib, &min, &max);
|
||||
vbo_get_minmax_indices(ctx, &prim, &ib, &min, &max, 1);
|
||||
|
||||
if ((int)(min + basevertex) < 0 ||
|
||||
max + basevertex > ctx->Array.ArrayObj->_MaxElement) {
|
||||
|
|
|
|||
|
|
@ -990,7 +990,8 @@ st_draw_vbo(struct gl_context *ctx,
|
|||
/* Gallium probably doesn't want this in some cases. */
|
||||
if (!index_bounds_valid)
|
||||
if (!all_varyings_in_vbos(arrays))
|
||||
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
||||
vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
|
||||
nr_prims);
|
||||
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
num_instances = MAX2(num_instances, prims[i].num_instances);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
|
|||
st_validate_state(st);
|
||||
|
||||
if (!index_bounds_valid)
|
||||
vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
|
||||
vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims);
|
||||
|
||||
/* must get these after state validation! */
|
||||
vp = st->vp;
|
||||
|
|
|
|||
|
|
@ -418,7 +418,7 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx,
|
|||
struct gl_transform_feedback_object *tfb_vertcount)
|
||||
{
|
||||
if (!index_bounds_valid)
|
||||
vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
|
||||
vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);
|
||||
|
||||
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,9 +127,9 @@ int
|
|||
vbo_sizeof_ib_type(GLenum type);
|
||||
|
||||
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);
|
||||
vbo_get_minmax_indices(struct gl_context *ctx, const struct _mesa_prim *prim,
|
||||
const struct _mesa_index_buffer *ib,
|
||||
GLuint *min_index, GLuint *max_index, GLuint nr_prims);
|
||||
|
||||
void vbo_use_buffer_objects(struct gl_context *ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue