GLboolean _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei numInstances, GLint basevertex) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { if (count < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElementsInstanced(count=%d)", count); return GL_FALSE; } if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElementsInstanced(mode = 0x%x)", mode); return GL_FALSE; } if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElementsInstanced(type=0x%x)", type); return GL_FALSE; } if (numInstances <= 0) { if (numInstances < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElementsInstanced(numInstances=%d)", numInstances); return GL_FALSE; } if (!check_valid_to_render(ctx, "glDrawElementsInstanced")) return GL_FALSE; /* Vertex buffer object tests */ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawElementsInstanced 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; }
/** * 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; }
size_t r_index(SEXP x, size_t len) { int tmp; if (TYPEOF(x) == INTSXP) { tmp = (int)INTEGER(x)[0]; } else if (TYPEOF(x) == REALSXP) { tmp = (int)REAL(x)[0]; } else { Rf_error("Invalid type for index"); } return check_index_bounds(tmp, len); }
/** * Error checking for glDrawRangeElements(). Includes parameter checking * and VBO bounds checking. * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { if (count < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); return GL_FALSE; } if (mode > GL_POLYGON) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); return GL_FALSE; } if (end < start) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); return GL_FALSE; } if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" ); return GL_FALSE; } if (!check_valid_to_render(ctx, "glDrawRangeElements")) return GL_FALSE; /* Vertex buffer object tests */ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements 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; }
size_t * r_indices(SEXP x, size_t len) { const size_t ni = length(x); size_t *idx = (size_t*) R_alloc(ni, sizeof(size_t)); for (size_t i = 0; i < ni; ++i) { int tmp; if (TYPEOF(x) == INTSXP) { tmp = (int)INTEGER(x)[i]; } else if (TYPEOF(x) == REALSXP) { tmp = (int)(REAL(x)[i]); } else { Rf_error("Invalid type for index"); } idx[i] = check_index_bounds(tmp, len); } return idx; }