vbo: fix glVertexAttrib(index=0)
authorBrian Paul <brianp@vmware.com>
Sat, 19 Aug 2017 03:03:16 +0000 (21:03 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 24 Aug 2017 13:36:10 +0000 (07:36 -0600)
Depending on which extension or GL spec you read the behavior of
glVertexAttrib(index=0) either sets the current value for generic
attribute 0, or it emits a vertex just like glVertex().  I believe
it should do either, depending on context (see below).

The piglit gl-2.0-vertex-const-attr test declares two vertex attributes:
  attribute vec2 vertex;
  attribute vec4 attr;
and the GLSL linker assigns "vertex" to location 0 and "attr" to location 1.
The test passes.

But if the declarations were reversed such that "attr" was location 0 and
"vertex" was location 1, the test would fail to draw properly.

The problem is the call to glVertexAttrib(index=0) to set attr's value
was interpreted as glVertex() and did not set generic attribute[0]'s value.
Interesting, calling glVertex() outside glBegin/End (which is effectively
what the piglit test does) does not generate a GL error.

I believe the behavior of glVertexAttrib(index=0) should depend on
whether it's called inside or outside of glBegin/glEnd().  If inside
glBegin/End(), it should act like glVertex().  Else, it should behave
like glVertexAttrib(index > 0).  This seems to be what NVIDIA does.

This patch makes two changes:

1. Check if we're inside glBegin/End for glVertexAttrib()
2. Fix the vertex array binding for recalculate_input_bindings().  As it was,
   we were using &vbo->currval[VBO_ATTRIB_POS], but that's interpreted
   as a zero-stride attribute and doesn't make sense for array drawing.

No Piglit regressions.  Fixes updated gl-2.0-vertex-const-attr test and
passes new gl-2.0-vertex-attrib-0 test.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101941
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
src/mesa/vbo/vbo_attrib_tmp.h
src/mesa/vbo/vbo_exec_array.c

index 5718ac5a0924de855decf1e5ee59174d383e59f5..126e4ef0d6ebdaa436e7401b1c05c5f974065493 100644 (file)
@@ -524,15 +524,18 @@ TAG(MultiTexCoord4fv)(GLenum target, const GLfloat * v)
 
 /**
  * If index=0, does glVertexAttrib*() alias glVertex() to emit a vertex?
+ * It depends on a few things, including whether we're inside or outside
+ * of glBegin/glEnd.
  */
 static inline bool
 is_vertex_position(const struct gl_context *ctx, GLuint index)
 {
-   return index == 0 && _mesa_attr_zero_aliases_vertex(ctx);
+   return (index == 0 &&
+           _mesa_attr_zero_aliases_vertex(ctx) &&
+           _mesa_inside_begin_end(ctx));
 }
 
 
-
 static void GLAPIENTRY
 TAG(VertexAttrib1fARB)(GLuint index, GLfloat x)
 {
index edd55ce69e2a419a8dc9edd6026a5e131bcafd26..e3421fa9b513bb238bc87a6f8dc367c41b59b26b 100644 (file)
@@ -356,7 +356,7 @@ recalculate_input_bindings(struct gl_context *ctx)
          else if (array[VERT_ATTRIB_POS].Enabled)
             inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
          else {
-            inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
+            inputs[0] = &vbo->currval[VBO_ATTRIB_GENERIC0];
             const_inputs |= VERT_BIT_POS;
          }