diff options
author | Fredrik Höglund <[email protected]> | 2013-11-15 20:01:07 +0100 |
---|---|---|
committer | Fredrik Höglund <[email protected]> | 2014-05-02 03:00:41 +0200 |
commit | 63995b902a5288b778b303f63eb9d884a2dfbdb6 (patch) | |
tree | f1aa8c4b11923fc1a87c842b5ba2946cd19acd00 /src/mesa/main/varray.c | |
parent | f0c36cf4faebb98e54bdb12f0cde5357c7bcc49b (diff) |
mesa: Implement glBindVertexBuffers
v2: Use the user provided offset and stride when the buffer ID is zero.
Reviewed-by: Brian Paul <[email protected]> (v1)
Reviewed-by: Ian Romanick <[email protected]> (v1)
Reviewed-by: Kenneth Graunke <[email protected]> (v2)
Diffstat (limited to 'src/mesa/main/varray.c')
-rw-r--r-- | src/mesa/main/varray.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index d7dc2325879..46956efb5a8 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -1443,6 +1443,119 @@ void GLAPIENTRY _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides) { + GET_CURRENT_CONTEXT(ctx); + struct gl_vertex_array_object * const vao = ctx->Array.VAO; + GLuint i; + + ASSERT_OUTSIDE_BEGIN_END(ctx); + + /* The ARB_vertex_attrib_binding spec says: + * + * "An INVALID_OPERATION error is generated if no + * vertex array object is bound." + */ + if (ctx->API == API_OPENGL_CORE && + ctx->Array.VAO == ctx->Array.DefaultVAO) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindVertexBuffers(No array object bound)"); + return; + } + + /* The ARB_multi_bind spec says: + * + * "An INVALID_OPERATION error is generated if <first> + <count> + * is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS." + */ + if (first + count > ctx->Const.MaxVertexAttribBindings) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindVertexBuffers(first=%u + count=%d > the value of " + "GL_MAX_VERTEX_ATTRIB_BINDINGS=%u)", + first, count, ctx->Const.MaxVertexAttribBindings); + return; + } + + if (!buffers) { + /** + * The ARB_multi_bind spec says: + * + * "If <buffers> is NULL, each affected vertex buffer binding point + * from <first> through <first>+<count>-1 will be reset to have no + * bound buffer object. In this case, the offsets and strides + * associated with the binding points are set to default values, + * ignoring <offsets> and <strides>." + */ + struct gl_buffer_object *vbo = ctx->Shared->NullBufferObj; + + for (i = 0; i < count; i++) + bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(first + i), vbo, 0, 16); + + return; + } + + /* Note that the error semantics for multi-bind commands differ from + * those of other GL commands. + * + * The Issues section in the ARB_multi_bind spec says: + * + * "(11) Typically, OpenGL specifies that if an error is generated by + * a command, that command has no effect. This is somewhat + * unfortunate for multi-bind commands, because it would require + * a first pass to scan the entire list of bound objects for + * errors and then a second pass to actually perform the + * bindings. Should we have different error semantics? + * + * RESOLVED: Yes. In this specification, when the parameters for + * one of the <count> binding points are invalid, that binding + * point is not updated and an error will be generated. However, + * other binding points in the same command will be updated if + * their parameters are valid and no other error occurs." + */ + + _mesa_begin_bufferobj_lookups(ctx); + + for (i = 0; i < count; i++) { + struct gl_buffer_object *vbo; + + /* The ARB_multi_bind spec says: + * + * "An INVALID_VALUE error is generated if any value in + * <offsets> or <strides> is negative (per binding)." + */ + if (offsets[i] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glBindVertexBuffer(offsets[%u]=%lldd < 0)", + i, (long long int) offsets[i]); + continue; + } + + if (strides[i] < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glBindVertexBuffer(strides[%u]=%lld < 0)", + i, (long long int) strides[i]); + continue; + } + + if (buffers[i]) { + struct gl_vertex_buffer_binding *binding = + &vao->VertexBinding[VERT_ATTRIB_GENERIC(first + i)]; + + if (buffers[i] == binding->BufferObj->Name) + vbo = binding->BufferObj; + else + vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, + "glBindVertexBuffers"); + + if (!vbo) + continue; + } else { + vbo = ctx->Shared->NullBufferObj; + } + + bind_vertex_buffer(ctx, VERT_ATTRIB_GENERIC(first + i), vbo, + offsets[i], strides[i]); + } + + _mesa_end_bufferobj_lookups(ctx); } |