diff options
Diffstat (limited to 'mesalib/src/mesa/main/varray.c')
-rw-r--r-- | mesalib/src/mesa/main/varray.c | 128 |
1 files changed, 121 insertions, 7 deletions
diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 66a3ef119..46956efb5 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -784,13 +784,7 @@ static const GLfloat * get_current_attrib(struct gl_context *ctx, GLuint index, const char *function) { if (index == 0) { - /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES - * 2.0. Note that we cannot just check for API_OPENGL_CORE here because - * that will erroneously allow this usage in a 3.0 forward-compatible - * context too. - */ - if ((ctx->API != API_OPENGL_CORE || ctx->Version < 31) - && ctx->API != API_OPENGLES2) { + if (_mesa_attr_zero_aliases_vertex(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function); return NULL; } @@ -1446,6 +1440,126 @@ _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, 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); +} + + +void GLAPIENTRY _mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, GLboolean normalized, GLuint relativeOffset) { |