summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c53
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h1
-rw-r--r--src/mesa/drivers/dri/r300/r300_draw.c7
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c2
-rw-r--r--src/mesa/state_tracker/st_draw.c5
-rw-r--r--src/mesa/state_tracker/st_draw.h2
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c4
-rw-r--r--src/mesa/tnl/t_context.c2
-rw-r--r--src/mesa/tnl/t_draw.c18
-rw-r--r--src/mesa/tnl/tnl.h10
-rw-r--r--src/mesa/vbo/vbo.h6
-rw-r--r--src/mesa/vbo/vbo_exec_array.c158
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c1
-rw-r--r--src/mesa/vbo/vbo_rebase.c1
-rw-r--r--src/mesa/vbo/vbo_save_draw.c1
-rw-r--r--src/mesa/vbo/vbo_split_copy.c1
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c1
17 files changed, 156 insertions, 117 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 5152c3f3a5f..8c94c904c1f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -422,54 +422,31 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
return retval;
}
-static GLboolean brw_need_rebase( GLcontext *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_index_buffer *ib,
- GLuint min_index )
-{
- if (min_index == 0)
- return GL_FALSE;
-
- if (ib) {
- if (!vbo_all_varyings_in_vbos(arrays))
- return GL_TRUE;
- else
- return GL_FALSE;
- }
- else {
- /* Hmm. This isn't quite what I wanted. BRW can actually
- * handle the mixed case well enough that we shouldn't need to
- * rebase. However, it's probably not very common, nor hugely
- * expensive to do it this way:
- */
- if (!vbo_all_varyings_in_vbos(arrays))
- return GL_TRUE;
- else
- return GL_FALSE;
- }
-}
-
-
void brw_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index )
{
GLboolean retval;
- /* Decide if we want to rebase. If so we end up recursing once
- * only into this function.
- */
- if (brw_need_rebase( ctx, arrays, ib, min_index )) {
- vbo_rebase_prims( ctx, arrays,
- prim, nr_prims,
- ib, min_index, max_index,
- brw_draw_prims );
-
- return;
+ if (!vbo_all_varyings_in_vbos(arrays)) {
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ /* Decide if we want to rebase. If so we end up recursing once
+ * only into this function.
+ */
+ if (min_index != 0) {
+ vbo_rebase_prims(ctx, arrays,
+ prim, nr_prims,
+ ib, min_index, max_index,
+ brw_draw_prims );
+ return;
+ }
}
/* Make a first attempt at drawing:
diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h
index 9aebbdb1b86..2a14db217fc 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.h
+++ b/src/mesa/drivers/dri/i965/brw_draw.h
@@ -39,6 +39,7 @@ void brw_draw_prims( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index fcfd3099332..aedc6cfb2a1 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -462,6 +462,7 @@ static void r300DrawPrims(GLcontext *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -476,6 +477,12 @@ static void r300DrawPrims(GLcontext *ctx,
limits.max_indices = 65535;
limits.max_vb_size = 1024*1024;
+ /* This check should get folded into just the places that
+ * min/max index are really needed.
+ */
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
if (min_index) {
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
return;
diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 3bcccd0df46..d82b2a2035f 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -251,7 +251,7 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
rs->array[0].Ptr = (GLubyte *) v;
/* draw the point */
- st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);
+ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
}
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 914a507bef6..503a5f34a3f 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -533,6 +533,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -545,6 +546,10 @@ st_draw_vbo(GLcontext *ctx,
unsigned num_vbuffers, num_velements;
GLboolean userSpace;
+ /* Gallium probably doesn't want this in some cases. */
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index dcfe7e15361..3e0face656b 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -47,6 +47,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
@@ -56,6 +57,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 2712c131c0d..b2d682ef640 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -96,6 +96,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -114,6 +115,9 @@ st_feedback_draw_vbo(GLcontext *ctx,
st_validate_state(ctx->st);
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* must get these after state validation! */
vp = ctx->st->vp;
vs = &st->vp->state;
diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f69b1220461..f2771cde095 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -81,7 +81,7 @@ _tnl_CreateContext( GLcontext *ctx )
tnl->nr_blocks = 0;
/* plug in the VBO drawing function */
- vbo_set_draw_func(ctx, _tnl_draw_prims);
+ vbo_set_draw_func(ctx, _tnl_vbo_draw_prims);
_math_init_transformation();
_math_init_translate();
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 2ec65d53233..c64c2c20778 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -360,6 +360,20 @@ static void unmap_vbos( GLcontext *ctx,
}
+void _tnl_vbo_draw_prims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index)
+{
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+}
/* This is the main entrypoint into the slimmed-down software tnl
* module. In a regular swtnl driver, this can be plugged straight
@@ -393,7 +407,7 @@ void _tnl_draw_prims( GLcontext *ctx,
*/
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
min_index, max_index,
- _tnl_draw_prims );
+ _tnl_vbo_draw_prims );
return;
}
else if (max_index > max) {
@@ -411,7 +425,7 @@ void _tnl_draw_prims( GLcontext *ctx,
*/
vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
0, max_index,
- _tnl_draw_prims,
+ _tnl_vbo_draw_prims,
&limits );
}
else {
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
index 4d628aa9a60..9c66d3b0192 100644
--- a/src/mesa/tnl/tnl.h
+++ b/src/mesa/tnl/tnl.h
@@ -81,6 +81,16 @@ _tnl_draw_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index);
+void
+_tnl_vbo_draw_prims( GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index);
+
extern void
_mesa_load_tracked_matrices(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h
index 5362226c2f9..5986e93576c 100644
--- a/src/mesa/vbo/vbo.h
+++ b/src/mesa/vbo/vbo.h
@@ -69,6 +69,7 @@ typedef void (*vbo_draw_func)( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
@@ -112,7 +113,10 @@ void vbo_rebase_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index,
vbo_draw_func draw );
-
+void
+vbo_get_minmax_index(GLcontext *ctx, const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index);
void vbo_use_buffer_objects(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index f4b9b2f7443..4fb4845f6b6 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -41,15 +41,29 @@
/**
* Compute min and max elements for glDraw[Range]Elements() calls.
*/
-static void
-get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
- GLuint *min_index, GLuint *max_index)
+void
+vbo_get_minmax_index(GLcontext *ctx,
+ const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index)
{
GLuint i;
+ GLsizei count = prim->count;
+ const void *indices;
+
+ if (ib->obj->Name) {
+ const GLvoid *map = ctx->Driver.MapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ GL_READ_ONLY,
+ ib->obj);
+ indices = ADD_POINTERS(map, ib->ptr);
+ } else {
+ indices = ib->ptr;
+ }
- switch(type) {
+ switch (ib->type) {
case GL_UNSIGNED_INT: {
- const GLuint *ui_indices = (const GLuint *)indices;
+ const GLuint *ui_indices = (const GLuint *)ib->ptr;
GLuint max_ui = ui_indices[count-1];
GLuint min_ui = ui_indices[0];
for (i = 0; i < count; i++) {
@@ -88,6 +102,12 @@ get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
assert(0);
break;
}
+
+ if (ib->obj->Name != 0) {
+ ctx->Driver.UnmapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ ib->obj);
+ }
}
@@ -500,7 +520,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
prim[0].indexed = 0;
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
- start, start + count - 1 );
+ GL_TRUE, start, start + count - 1 );
#if 0
print_draw_arrays(ctx, exec, mode, start, count);
@@ -566,53 +586,19 @@ dump_element_buffer(GLcontext *ctx, GLenum type)
ctx->Array.ElementArrayBufferObj);
}
-
-static void GLAPIENTRY
-vbo_exec_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type, const GLvoid *indices)
+/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+static void
+vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
+ GLboolean index_bounds_valid,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
{
- GET_CURRENT_CONTEXT(ctx);
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_exec_context *exec = &vbo->exec;
struct _mesa_index_buffer ib;
struct _mesa_prim prim[1];
- if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
- type, indices ))
- return;
-
- if (end >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
- "type 0x%x, indices=%p)\n"
- "\tindex=%u is out of bounds (max=%u) "
- "Element Buffer %u (size %d)",
- start, end, count, type, indices, end,
- ctx->Array.ArrayObj->_MaxElement - 1,
- ctx->Array.ElementArrayBufferObj->Name,
- ctx->Array.ElementArrayBufferObj->Size);
-
- if (0)
- dump_element_buffer(ctx, type);
-
- if (0)
- _mesa_print_arrays(ctx);
- return;
- }
- else if (0) {
- _mesa_printf("glDraw[Range]Elements"
- "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
- start, end, type, count,
- ctx->Array.ElementArrayBufferObj->Name);
- }
-
-#if 0
- check_draw_elements_data(ctx, count, type, indices);
-#else
- (void) check_draw_elements_data;
-#endif
-
FLUSH_CURRENT( ctx, 0 );
if (ctx->NewState)
@@ -623,13 +609,13 @@ vbo_exec_DrawRangeElements(GLenum mode,
return;
}
- bind_arrays( ctx );
-
if (ctx->NewState)
_mesa_update_state( ctx );
+ bind_arrays( ctx );
+
ib.count = count;
- ib.type = type;
+ ib.type = type;
ib.obj = ctx->Array.ElementArrayBufferObj;
ib.ptr = indices;
@@ -673,44 +659,68 @@ vbo_exec_DrawRangeElements(GLenum mode,
* for the latter case elsewhere.
*/
- vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end );
+ vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
+ index_bounds_valid, start, end );
}
-
static void GLAPIENTRY
-vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
+vbo_exec_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type, const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
- GLuint min_index = 0;
- GLuint max_index = 0;
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
+ type, indices ))
return;
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(bad shader)");
+ if (end >= ctx->Array.ArrayObj->_MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
+ "type 0x%x, indices=%p)\n"
+ "\tindex=%u is out of bounds (max=%u) "
+ "Element Buffer %u (size %d)",
+ start, end, count, type, indices, end,
+ ctx->Array.ArrayObj->_MaxElement - 1,
+ ctx->Array.ElementArrayBufferObj->Name,
+ ctx->Array.ElementArrayBufferObj->Size);
+
+ if (0)
+ dump_element_buffer(ctx, type);
+
+ if (0)
+ _mesa_print_arrays(ctx);
return;
}
+ else if (0) {
+ _mesa_printf("glDraw[Range]Elements"
+ "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
+ start, end, type, count,
+ ctx->Array.ElementArrayBufferObj->Name);
+ }
- if (ctx->Array.ElementArrayBufferObj->Name) {
- const GLvoid *map = ctx->Driver.MapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- GL_READ_ONLY,
- ctx->Array.ElementArrayBufferObj);
+#if 0
+ check_draw_elements_data(ctx, count, type, indices);
+#else
+ (void) check_draw_elements_data;
+#endif
+
+ vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
+ count, type, indices);
+}
- get_minmax_index(count, type, ADD_POINTERS(map, indices),
- &min_index, &max_index);
- ctx->Driver.UnmapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- ctx->Array.ElementArrayBufferObj);
- }
- else {
- get_minmax_index(count, type, indices, &min_index, &max_index);
- }
+static void GLAPIENTRY
+vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ return;
- vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices);
+ vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+ count, type, indices);
}
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 18419928b26..a988424d212 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -378,6 +378,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
exec->vtx.prim,
exec->vtx.prim_count,
NULL,
+ GL_TRUE,
0,
exec->vtx.vert_count - 1);
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index ea87dede646..3bf7ef580fc 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -208,6 +208,7 @@ void vbo_rebase_prims( GLcontext *ctx,
prim,
nr_prims,
ib,
+ GL_TRUE,
0,
max_index - min_index );
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 5110648c282..d834fa1f2e7 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -279,6 +279,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
node->prim,
node->prim_count,
NULL,
+ GL_TRUE,
0, /* Node is a VBO, so this is ok */
node->count - 1);
}
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index d7ffebf6076..3f8a222805d 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -194,6 +194,7 @@ flush( struct copy_context *copy )
copy->dstprim,
copy->dstprim_nr,
&copy->dstib,
+ GL_TRUE,
0,
copy->dstbuf_nr );
diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c
index 9628227e7c4..da84eaa6ead 100644
--- a/src/mesa/vbo/vbo_split_inplace.c
+++ b/src/mesa/vbo/vbo_split_inplace.c
@@ -85,6 +85,7 @@ static void flush_vertex( struct split_context *split )
split->dstprim,
split->dstprim_nr,
NULL,
+ GL_TRUE,
min_index,
max_index);