mesa: Implement glBindVertexBuffers
v2: Use the user provided offset and stride when the buffer ID is zero. Reviewed-by: Brian Paul <brianp@vmware.com> (v1) Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v1) Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> (v2)
This commit is contained in:
parent
f0c36cf4fa
commit
63995b902a
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue