[Mesa-dev] [PATCH] mesa/vbo: Treat attribute 0 and vertex as the same

Ian Romanick idr at freedesktop.org
Fri Oct 14 15:00:43 PDT 2011


On 10/14/2011 08:41 AM, Brian Paul wrote:
> On 10/13/2011 05:34 PM, Ian Romanick wrote:
>> From: Ian Romanick<ian.d.romanick at intel.com>
>>
>> This is supported by the pseudo-code on pages 27 and 28 (pages 41 and
>> 42 of the PDF) of the OpenGL 2.1 spec. The last part of the
>> implementation of ArrayElement is:
>>
>> if (generic attribute array 0 enabled) {
>> if (generic vertex attribute 0 array normalization flag is set, and
>> type is not FLOAT or DOUBLE)
>> VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element
>> i);
>> else
>> VertexAttrib[size][type]v(0, generic vertex attribute 0 array element i);
>> } else if (vertex array enabled) {
>> Vertex[size][type]v(vertex array element i);
>> }
>>
>> Page 23 (page 37 of the PDF) of the same spec says:
>>
>> "Setting generic vertex attribute zero specifies a vertex; the
>> four vertex coordinates are taken from the values of attribute
>> zero. A Vertex2, Vertex3, or Vertex4 command is completely
>> equivalent to the corresponding VertexAttrib* command with an
>> index of zero."
>>
>> Fixes piglit test attribute0.
>>
>> NOTE: This is a candidate for stable branches.
>>
>> Signed-off-by: Ian Romanick<ian.d.romanick at intel.com>
>> ---
>> src/mesa/vbo/vbo_exec_array.c | 3 ++-
>> 1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/src/mesa/vbo/vbo_exec_array.c
>> b/src/mesa/vbo/vbo_exec_array.c
>> index 18719d5..ceb6a64 100644
>> --- a/src/mesa/vbo/vbo_exec_array.c
>> +++ b/src/mesa/vbo/vbo_exec_array.c
>> @@ -538,7 +538,7 @@ recalculate_input_bindings(struct gl_context *ctx)
>> }
>> }
>>
>> - for (i = 0; i< MAX_VERTEX_GENERIC_ATTRIBS; i++) {
>> + for (i = 1; i< MAX_VERTEX_GENERIC_ATTRIBS; i++) {
>> if (exec->array.generic_array[i]->Enabled)
>> inputs[VERT_ATTRIB_GENERIC0 + i] = exec->array.generic_array[i];
>> else {
>> @@ -547,6 +547,7 @@ recalculate_input_bindings(struct gl_context *ctx)
>> }
>> }
>>
>> + inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
>> ctx->NewState |= _NEW_ARRAY;
>> break;
>> }
>
> Tested-by: Brian Paul <brianp at vmware.com>
>
>
> This looks good to me. I hacked the attribute0 test to do some
> additional experiments and it worked as expected.
>
> There's two interesting points (IMHO) to note regarding generic
> attribute 0 that I don't think are spelled out in the specs. Please
> correct me if I'm wrong.
>
> 1. If a vertex shader uses gl_Vertex then the first generic attribute
> that's allocated will be 1. But if the gl_Vertex is not used, the first
> generic attribute that's allocated is 0. If quering
> GL_MAX_VERTEX_ATTRIBS returns 16, you really only have 15 generic
> attribs available if gl_Vertex is used.

Right.  If gl_Vertex is used, generic attribute slot 0 will not be 
assigned.  Mesa's linker has some checks for this case when assigning 
attribute locations.

> 2. If gl_Vertex is not used in the vertex shader, you can only draw with
> vertex arrays - you can't use glBegin/End rendering. Section 2.7 of the
> OpenGL 2.1 spec it says that glVertexAttrib(0, ...) specifies a vertex

You can still use glBegin/End.  glVertexAttrib(0, ...) and glVertex are 
supposed to be synonyms.  In fact, glBegin/End is the whole reason for 
attribute 0 being special.  If we had just:

1. Required that vertex arrays be used when gl_Vertex was not used.

2. Allowed vertex array rendering when any generic attribute was enabled 
(prior to 3.0 GL_VERTEX_ARRAY had to be enabled).

We could have avoided all of this attribute 0 craziness.  Alas.

> so if you have a vertex shader like this:
>
> attribute vec4 vertex;
> attribute vec4 color;
> void main() {
> gl_Position = vertex;
> gl_FrontColor = color;
> }
>
> and draw like this:
>
> vertPos = glGetAttribLocation(prog, "vertex");
> colPos = glGetAttribLocation(prog, "color");
> glBegin(GL_TRIANGLE_STRIP);
> for (i = 0; i < n; i++) {
> glVertexAttrib3fv(colAttr, colors[i]);
> glVertexAttrib2fv(vertAttr, verts[i]);
> }
> glEnd();
>
> It may or may not work depending on whether "vertex" is in location 0 or 1.

To make this work, the app would have to use glBindAttribLocation(prog, 
0, "vertex") to ensure that vertex was bound to generic attribute 0. 
Then vertAttr would be 0, and it would "just work."


More information about the mesa-dev mailing list