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; }
GLboolean _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first, GLsizei count, GLsizei numInstances) { struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; FLUSH_CURRENT(ctx, 0); if (count < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArraysInstanced(count=%d)", count); return GL_FALSE; } if (first < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArraysInstanced(start=%d)", first); return GL_FALSE; } if (!_mesa_valid_prim_mode(ctx, mode, "glDrawArraysInstanced")) { return GL_FALSE; } if (numInstances <= 0) { if (numInstances < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArraysInstanced(numInstances=%d)", numInstances); return GL_FALSE; } if (!check_valid_to_render(ctx, "glDrawArraysInstanced(invalid to render)")) return GL_FALSE; /* From the GLES3 specification, section 2.14.2 (Transform Feedback * Primitive Capture): * * The error INVALID_OPERATION is generated by DrawArrays and * DrawArraysInstanced if recording the vertices of a primitive to the * buffer objects being used for transform feedback purposes would result * in either exceeding the limits of any buffer object’s size, or in * exceeding the end position offset + size − 1, as set by * BindBufferRange. * * This is in contrast to the behaviour of desktop GL, where the extra * primitives are silently dropped from the transform feedback buffer. */ if (_mesa_is_gles3(ctx) && _mesa_is_xfb_active_and_unpaused(ctx)) { size_t prim_count = vbo_count_tessellated_primitives(mode, count, numInstances); if (xfb_obj->GlesRemainingPrims < prim_count) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArraysInstanced(exceeds transform feedback size)"); return GL_FALSE; } xfb_obj->GlesRemainingPrims -= prim_count; } if (count == 0) return GL_FALSE; return GL_TRUE; }