/** * Error checking for glMultiDrawElements(). Includes parameter checking * and VBO bounds checking. * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLuint primcount, const GLint *basevertex) { unsigned i; FLUSH_CURRENT(ctx, 0); for (i = 0; i < primcount; i++) { if (count[i] <= 0) { if (count[i] < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawElements(count)" ); return GL_FALSE; } } if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawElements")) { return GL_FALSE; } if (!valid_elements_type(ctx, type, "glMultiDrawElements")) return GL_FALSE; if (!check_valid_to_render(ctx, "glMultiDrawElements")) return GL_FALSE; /* Vertex buffer object tests */ if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ for (i = 0; i < primcount; i++) { if (index_bytes(type, count[i]) > ctx->Array.ArrayObj->ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glMultiDrawElements index out of buffer bounds"); return GL_FALSE; } } } else { /* not using a VBO */ for (i = 0; i < primcount; i++) { if (!indices[i]) return GL_FALSE; } } for (i = 0; i < primcount; i++) { if (!check_index_bounds(ctx, count[i], type, indices[i], basevertex ? basevertex[i] : 0)) return GL_FALSE; } return GL_TRUE; }
/** * Error checking for glDrawElements(). Includes parameter checking * and VBO bounds checking. * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_DrawElements(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) { FLUSH_CURRENT(ctx, 0); /* From the GLES3 specification, section 2.14.2 (Transform Feedback * Primitive Capture): * * The error INVALID_OPERATION is also generated by DrawElements, * DrawElementsInstanced, and DrawRangeElements while transform feedback * is active and not paused, regardless of mode. */ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(transform feedback active)"); return GL_FALSE; } if (count <= 0) { if (count < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); return GL_FALSE; } if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElements")) { return GL_FALSE; } if (!valid_elements_type(ctx, type, "glDrawElements")) return GL_FALSE; if (!check_valid_to_render(ctx, "glDrawElements")) return GL_FALSE; /* Vertex buffer object tests */ if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj)) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ArrayObj->ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); return GL_FALSE; } } else { /* not using a VBO */ if (!indices) return GL_FALSE; } if (!check_index_bounds(ctx, count, type, indices, basevertex)) return GL_FALSE; return GL_TRUE; }
static bool validate_DrawElements_common(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, const char *caller) { /* From the GLES3 specification, section 2.14.2 (Transform Feedback * Primitive Capture): * * The error INVALID_OPERATION is also generated by DrawElements, * DrawElementsInstanced, and DrawRangeElements while transform feedback * is active and not paused, regardless of mode. */ if (_mesa_is_gles3(ctx) && !ctx->Extensions.OES_geometry_shader && _mesa_is_xfb_active_and_unpaused(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)", caller); return false; } if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller); return false; } if (!_mesa_valid_prim_mode(ctx, mode, caller)) { return false; } if (!valid_elements_type(ctx, type, caller)) return false; if (!check_valid_to_render(ctx, caller)) return false; /* Not using a VBO for indices, so avoid NULL pointer derefs later. */ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) return false; if (count == 0) return false; return true; }
static inline GLboolean valid_draw_indirect_elements(struct gl_context *ctx, GLenum mode, GLenum type, const GLvoid *indirect, GLsizeiptr size, const char *name) { if (!valid_elements_type(ctx, type, name)) return GL_FALSE; /* * Unlike regular DrawElementsInstancedBaseVertex commands, the indices * may not come from a client array and must come from an index buffer. * If no element array buffer is bound, an INVALID_OPERATION error is * generated. */ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no buffer bound to GL_ELEMENT_ARRAY_BUFFER)", name); return GL_FALSE; } return valid_draw_indirect(ctx, mode, indirect, size, name); }
/** * Error checking for glMultiDrawElements(). Includes parameter checking * and VBO bounds checking. * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, GLuint primcount) { unsigned i; FLUSH_CURRENT(ctx, 0); for (i = 0; i < primcount; i++) { if (count[i] < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glMultiDrawElements(count)" ); return GL_FALSE; } } if (!_mesa_valid_prim_mode(ctx, mode, "glMultiDrawElements")) { return GL_FALSE; } if (!valid_elements_type(ctx, type, "glMultiDrawElements")) return GL_FALSE; if (!check_valid_to_render(ctx, "glMultiDrawElements")) return GL_FALSE; /* Not using a VBO for indices, so avoid NULL pointer derefs later. */ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { for (i = 0; i < primcount; i++) { if (!indices[i]) return GL_FALSE; } } return GL_TRUE; }
static bool validate_DrawElements_common(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, const char *caller) { /* Section 2.14.2 (Transform Feedback Primitive Capture) of the OpenGL ES * 3.1 spec says: * * The error INVALID_OPERATION is also generated by DrawElements, * DrawElementsInstanced, and DrawRangeElements while transform feedback * is active and not paused, regardless of mode. * * The OES_geometry_shader_spec says: * * Issues: * * ... * * (13) Does this extension change how transform feedback operates * compared to unextended OpenGL ES 3.0 or 3.1? * * RESOLVED: Yes... Since we no longer require being able to predict how * much geometry will be generated, we also lift the restriction that * only DrawArray* commands are supported and also support the * DrawElements* commands for transform feedback. * * This should also be reflected in the body of the spec, but that appears * to have been overlooked. The body of the spec only explicitly allows * the indirect versions. */ if (_mesa_is_gles3(ctx) && !ctx->Extensions.OES_geometry_shader && _mesa_is_xfb_active_and_unpaused(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(transform feedback active)", caller); return false; } if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller); return false; } if (!_mesa_valid_prim_mode(ctx, mode, caller)) { return false; } if (!valid_elements_type(ctx, type, caller)) return false; if (!check_valid_to_render(ctx, caller)) return false; /* Not using a VBO for indices, so avoid NULL pointer derefs later. */ if (!_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj) && indices == NULL) return false; if (count == 0) return false; return true; }