/** * Specify a buffer object to receive vertex shader results. * As above, but start at offset = 0. * Called from the glBindBufferBase() function. */ void _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, GLuint index, struct gl_buffer_object *bufObj) { struct gl_transform_feedback_object *obj; GLsizeiptr size; obj = ctx->TransformFeedback.CurrentObject; if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindBufferBase(transform feedback active)"); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); return; } /* default size is the buffer size rounded down to nearest * multiple of four. */ size = bufObj->Size & ~0x3; bind_buffer_range(ctx, index, bufObj, 0, size); }
/** * Specify a buffer object to receive vertex shader results, plus the * offset in the buffer to start placing results. * This function is part of GL_EXT_transform_feedback, but not GL3. */ void GLAPIENTRY _mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, GLintptr offset) { struct gl_transform_feedback_object *obj; struct gl_buffer_object *bufObj; GET_CURRENT_CONTEXT(ctx); GLsizeiptr size; if (target != GL_TRANSFORM_FEEDBACK_BUFFER) { _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferOffsetEXT(target)"); return; } obj = ctx->TransformFeedback.CurrentObject; if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindBufferOffsetEXT(transform feedback active)"); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferOffsetEXT(index=%d)", index); return; } if (offset & 0x3) { /* must be multiple of four */ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferOffsetEXT(offset=%d)", (int) offset); return; } if (buffer == 0) { bufObj = ctx->Shared->NullBufferObj; } else { bufObj = _mesa_lookup_bufferobj(ctx, buffer); } if (!bufObj) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindBufferOffsetEXT(invalid buffer=%u)", buffer); return; } /* default size is the buffer size rounded down to nearest * multiple of four. */ size = (bufObj->Size - offset) & ~0x3; bind_buffer_range(ctx, index, bufObj, offset, size); }
/** * Specify a buffer object to receive transform feedback results. * As above, but start at offset = 0. * Called from the glBindBufferBase() and glTransformFeedbackBufferBase() * functions. */ void _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj, GLuint index, struct gl_buffer_object *bufObj, bool dsa) { if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)", dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase"); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)", dsa ? "glTransformFeedbackBufferBase" : "glBindBufferBase", index); return; } bind_buffer_range(ctx, obj, index, bufObj, 0, 0, dsa); }
/** * Specify a buffer object to receive vertex shader results. Plus, * specify the starting offset to place the results, and max size. * Called from the glBindBufferRange() function. */ void _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx, GLuint index, struct gl_buffer_object *bufObj, GLintptr offset, GLsizeiptr size) { struct gl_transform_feedback_object *obj; obj = ctx->TransformFeedback.CurrentObject; if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindBufferRange(transform feedback active)"); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); return; } if (size & 0x3) { /* must a multiple of four */ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)", (int) size); return; } if (offset & 0x3) { /* must be multiple of four */ _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(offset=%d)", (int) offset); return; } bind_buffer_range(ctx, index, bufObj, offset, size); }
/** * Specify a buffer object to receive transform feedback results. Plus, * specify the starting offset to place the results, and max size. * Called from the glBindBufferRange() and glTransformFeedbackBufferRange * functions. */ void _mesa_bind_buffer_range_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj, GLuint index, struct gl_buffer_object *bufObj, GLintptr offset, GLsizeiptr size, bool dsa) { const char *gl_methd_name; if (dsa) gl_methd_name = "glTransformFeedbackBufferRange"; else gl_methd_name = "glBindBufferRange"; if (obj->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)", gl_methd_name); return; } if (index >= ctx->Const.MaxTransformFeedbackBuffers) { /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is * generated if index is greater than or equal to the number of binding * points for transform feedback, as described in section 6.7.1." */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d out of bounds)", gl_methd_name, index); return; } if (size & 0x3) { /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be a multiple of " "four)", gl_methd_name, (int) size); return; } if (offset & 0x3) { /* OpenGL 4.5 core profile, 6.7, pdf page 103: multiple of 4 */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be a multiple " "of four)", gl_methd_name, (int) offset); return; } if (offset < 0) { /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is * generated by BindBufferRange if offset is negative." * * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error * is generated by TransformFeedbackBufferRange if offset is negative." */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d must be >= 0)", gl_methd_name, (int) offset); return; } if (size <= 0 && (dsa || bufObj != ctx->Shared->NullBufferObj)) { /* OpenGL 4.5 core profile, 6.1, pdf page 82: "An INVALID_VALUE error is * generated by BindBufferRange if buffer is non-zero and size is less * than or equal to zero." * * OpenGL 4.5 core profile, 13.2, pdf page 445: "An INVALID_VALUE error * is generated by TransformFeedbackBufferRange if size is less than or * equal to zero." */ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d must be > 0)", gl_methd_name, (int) size); return; } bind_buffer_range(ctx, obj, index, bufObj, offset, size, dsa); }