summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-07-15 10:46:33 -0600
committerBrian Paul <brianp@vmware.com>2010-07-15 10:49:56 -0600
commit3fde89e4395d260821f4e76a0fe36c265c148a73 (patch)
treed366371a57affc51819c83c0f09abdf671b66d02
parent0eaccb30de9bc638dabb1edbd2c831bacba3cf36 (diff)
st/mesa: fix quad strip trimming bug
The translate_prim() function tries to convert quad strips into tri strips. This is normally OK but we have to check for an odd number of vertices so that we don't accidentally draw an extra triangle. The mesa-demos/src/samples/prim.c demo exercises that. With this fix the stray yellow triangle is no longer drawn. Use the u_trim_pipe_prim() function to make sure that prims have the right number of vertices and avoid calling gallium drawing functions when the prim has a degenerate number of vertices. Plus add comments, clean-up formatting, etc. NOTE: This is a candidate for the 7.8 branch.
-rw-r--r--src/mesa/state_tracker/st_draw.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index eed8e2aa5d8b..7fdaff45f76b 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -57,6 +57,7 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "util/u_prim.h"
#include "draw/draw_context.h"
#include "cso_cache/cso_context.h"
@@ -517,10 +518,21 @@ check_uniforms(GLcontext *ctx)
}
-static unsigned translate_prim( GLcontext *ctx,
- unsigned prim )
+/**
+ * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
+ * the corresponding Gallium type.
+ */
+static unsigned
+translate_prim(const GLcontext *ctx, unsigned prim)
{
+ /* GL prims should match Gallium prims, spot-check a few */
+ assert(GL_POINTS == PIPE_PRIM_POINTS);
+ assert(GL_QUADS == PIPE_PRIM_QUADS);
+ assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
+
/* Avoid quadstrips if it's easy to do so:
+ * Note: it's imporant to do the correct trimming if we change the prim type!
+ * We do that wherever this function is called.
*/
if (prim == GL_QUAD_STRIP &&
ctx->Light.ShadeModel != GL_FLAT &&
@@ -531,6 +543,8 @@ static unsigned translate_prim( GLcontext *ctx,
return prim;
}
+
+
/**
* This function gets plugged into the VBO module and is called when
* we have something to render.
@@ -639,7 +653,6 @@ st_draw_vbo(GLcontext *ctx,
struct gl_buffer_object *bufobj = ib->obj;
struct pipe_resource *indexBuf = NULL;
unsigned indexSize, indexOffset, i;
- unsigned prim;
switch (ib->type) {
case GL_UNSIGNED_INT:
@@ -678,27 +691,40 @@ st_draw_vbo(GLcontext *ctx,
* need a bit of work...
*/
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
- pipe->draw_range_elements(pipe, indexBuf, indexSize, 0,
- min_index, max_index, prim,
- prims[i].start + indexOffset, prims[i].count);
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ pipe->draw_range_elements(pipe, indexBuf, indexSize, 0,
+ min_index, max_index, prim,
+ prims[i].start + indexOffset, vcount);
+ }
}
}
else {
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
- if (prims[i].num_instances == 1) {
- pipe->draw_elements(pipe, indexBuf, indexSize, 0, prim,
- prims[i].start + indexOffset,
- prims[i].count);
- }
- else {
- pipe->draw_elements_instanced(pipe, indexBuf, indexSize, 0, prim,
- prims[i].start + indexOffset,
- prims[i].count,
- 0, prims[i].num_instances);
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ if (prims[i].num_instances == 1) {
+ pipe->draw_elements(pipe, indexBuf,
+ indexSize,
+ 0, /* indexBias */
+ prim,
+ prims[i].start + indexOffset,
+ vcount);
+ }
+ else {
+ pipe->draw_elements_instanced(pipe, indexBuf,
+ indexSize,
+ 0, /* indexBias */
+ prim,
+ prims[i].start + indexOffset,
+ vcount,
+ 0, /* startInstance */
+ prims[i].num_instances);
+ }
}
}
}
@@ -708,18 +734,22 @@ st_draw_vbo(GLcontext *ctx,
else {
/* non-indexed */
GLuint i;
- GLuint prim;
for (i = 0; i < nr_prims; i++) {
- prim = translate_prim( ctx, prims[i].mode );
+ unsigned vcount = prims[i].count;
+ unsigned prim = translate_prim(ctx, prims[i].mode);
- if (prims[i].num_instances == 1) {
- pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count);
- }
- else {
- pipe->draw_arrays_instanced(pipe, prim, prims[i].start,
- prims[i].count,
- 0, prims[i].num_instances);
+ if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+ if (prims[i].num_instances == 1) {
+ pipe->draw_arrays(pipe, prim, prims[i].start, vcount);
+ }
+ else {
+ pipe->draw_arrays_instanced(pipe, prim,
+ prims[i].start,
+ vcount,
+ 0, /* startInstance */
+ prims[i].num_instances);
+ }
}
}
}