X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fapi_validate.c;h=7d9893385828649568e97df830014d7a4ff20bc4;hb=f51f6805f5dacb89b6583cbe134ee0b374ddfec7;hp=9b80600dedac4138fc867f3f164623f7292b0272;hpb=f4b4ae8c241943b8ca65e7a00f272fe23ed73727;p=mesa.git diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 9b80600deda..7d989338582 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -54,107 +54,68 @@ index_bytes(GLenum type, GLsizei count) } -/** - * Find the max index in the given element/index buffer - */ -GLuint -_mesa_max_buffer_index(struct gl_context *ctx, GLuint count, GLenum type, - const void *indices, - struct gl_buffer_object *elementBuf) -{ - const GLubyte *map = NULL; - GLuint max = 0; - GLuint i; - - if (_mesa_is_bufferobj(elementBuf)) { - /* elements are in a user-defined buffer object. need to map it */ - map = ctx->Driver.MapBufferRange(ctx, 0, elementBuf->Size, - GL_MAP_READ_BIT, elementBuf, - MAP_INTERNAL); - /* Actual address is the sum of pointers */ - indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices); - } - - if (type == GL_UNSIGNED_INT) { - for (i = 0; i < count; i++) - if (((GLuint *) indices)[i] > max) - max = ((GLuint *) indices)[i]; - } - else if (type == GL_UNSIGNED_SHORT) { - for (i = 0; i < count; i++) - if (((GLushort *) indices)[i] > max) - max = ((GLushort *) indices)[i]; - } - else { - ASSERT(type == GL_UNSIGNED_BYTE); - for (i = 0; i < count; i++) - if (((GLubyte *) indices)[i] > max) - max = ((GLubyte *) indices)[i]; - } - - if (map) { - ctx->Driver.UnmapBuffer(ctx, elementBuf, MAP_INTERNAL); - } - - return max; -} - - /** * Check if OK to draw arrays/elements. */ -static GLboolean +static bool check_valid_to_render(struct gl_context *ctx, const char *function) { if (!_mesa_valid_to_render(ctx, function)) { - return GL_FALSE; + return false; } switch (ctx->API) { case API_OPENGLES2: /* For ES2, we can draw if we have a vertex program/shader). */ if (!ctx->VertexProgram._Current) - return GL_FALSE; + return false; break; case API_OPENGLES: /* For OpenGL ES, only draw if we have vertex positions */ if (!ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled) - return GL_FALSE; + return false; break; case API_OPENGL_CORE: - if (ctx->Array.VAO == ctx->Array.DefaultVAO) - return GL_FALSE; + /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5 + * Core Profile spec says: + * + * "An INVALID_OPERATION error is generated if no vertex array + * object is bound (see section 10.3.1)." + */ + if (ctx->Array.VAO == ctx->Array.DefaultVAO) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no VAO bound)", function); + return false; + } /* fallthrough */ - case API_OPENGL_COMPAT: - { - const struct gl_shader_program *vsProg = - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - GLboolean haveVertexShader = (vsProg && vsProg->LinkStatus); - GLboolean haveVertexProgram = ctx->VertexProgram._Enabled; - if (haveVertexShader || haveVertexProgram) { - /* Draw regardless of whether or not we have any vertex arrays. - * (Ex: could draw a point using a constant vertex pos) - */ - return GL_TRUE; - } - else { - /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic - * array [0]). - */ - return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled || - ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); - } + case API_OPENGL_COMPAT: { + const struct gl_shader_program *const vsProg = + ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; + const bool haveVertexShader = (vsProg && vsProg->LinkStatus); + const bool haveVertexProgram = ctx->VertexProgram._Enabled; + + if (haveVertexShader || haveVertexProgram) { + /* Draw regardless of whether or not we have any vertex arrays. + * (Ex: could draw a point using a constant vertex pos) + */ + return true; + } else { + /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic + * array [0]). + */ + return (ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Enabled || + ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled); } break; + } default: - assert(!"Invalid API value in check_valid_to_render()"); + unreachable("Invalid API value in check_valid_to_render()"); } - return GL_TRUE; + return true; } @@ -356,18 +317,12 @@ valid_elements_type(struct gl_context *ctx, GLenum type, const char *name) } } -/** - * 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) +static bool +validate_DrawElements_common(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, + const char *caller) { - FLUSH_CURRENT(ctx, 0); - /* From the GLES3 specification, section 2.14.2 (Transform Feedback * Primitive Capture): * @@ -377,44 +332,60 @@ _mesa_validate_DrawElements(struct gl_context *ctx, */ 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; + "%s(transform feedback active)", caller); + return false; } if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); - return GL_FALSE; + _mesa_error(ctx, GL_INVALID_VALUE, "%s(count)", caller); + return false; } - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElements")) { - return GL_FALSE; + if (!_mesa_valid_prim_mode(ctx, mode, caller)) { + return false; } - if (!valid_elements_type(ctx, type, "glDrawElements")) - return GL_FALSE; + if (!valid_elements_type(ctx, type, caller)) + return false; - if (!check_valid_to_render(ctx, "glDrawElements")) - return GL_FALSE; + if (!check_valid_to_render(ctx, caller)) + return false; /* Vertex buffer object tests */ if (_mesa_is_bufferobj(ctx->Array.VAO->IndexBufferObj)) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, "glDrawElements index out of buffer bounds"); - return GL_FALSE; + _mesa_warning(ctx, "%s index out of buffer bounds", caller); + return false; } } else { /* not using a VBO */ if (!indices) - return GL_FALSE; + return false; } if (count == 0) - return GL_FALSE; + return false; - return GL_TRUE; + return 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) +{ + FLUSH_CURRENT(ctx, 0); + + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElements"); } @@ -427,7 +398,7 @@ GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, - GLuint primcount, const GLint *basevertex) + GLuint primcount) { unsigned i; @@ -485,62 +456,17 @@ GLboolean _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex) + const GLvoid *indices) { 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) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); - return GL_FALSE; - } - - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawRangeElements")) { - return GL_FALSE; - } - if (end < start) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(endArray.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); - return GL_FALSE; - } - } - else { - /* not using a VBO */ - if (!indices) - return GL_FALSE; - } - - if (count == 0) - return GL_FALSE; - - return GL_TRUE; + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawRangeElements"); } @@ -550,8 +476,7 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean -_mesa_validate_DrawArrays(struct gl_context *ctx, - GLenum mode, GLint start, GLsizei count) +_mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count) { struct gl_transform_feedback_object *xfb_obj = ctx->TransformFeedback.CurrentObject; @@ -667,67 +592,19 @@ _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint fi GLboolean _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances, - GLint basevertex) + const GLvoid *indices, GLsizei numInstances) { 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 (numInstances < 0) { _mesa_error(ctx, GL_INVALID_VALUE, - "glDrawElementsInstanced(count=%d)", count); + "glDrawElementsInstanced(numInstances=%d)", numInstances); return GL_FALSE; } - if (!_mesa_valid_prim_mode(ctx, mode, "glDrawElementsInstanced")) { - return GL_FALSE; - } - - if (!valid_elements_type(ctx, type, "glDrawElementsInstanced")) - 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.VAO->IndexBufferObj)) { - /* use indices in the buffer object */ - /* make sure count doesn't go outside buffer bounds */ - if (index_bytes(type, count) > ctx->Array.VAO->IndexBufferObj->Size) { - _mesa_warning(ctx, - "glDrawElementsInstanced index out of buffer bounds"); - return GL_FALSE; - } - } - else { - /* not using a VBO */ - if (!indices) - return GL_FALSE; - } - - if (count == 0) - return GL_FALSE; - - return GL_TRUE; + return validate_DrawElements_common(ctx, mode, count, type, indices, + "glDrawElementsInstanced") + && (numInstances > 0); } @@ -749,17 +626,17 @@ _mesa_validate_DrawTransformFeedback(struct gl_context *ctx, return GL_FALSE; } - if (!obj->EndedAnytime) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback*"); - return GL_FALSE; - } - if (stream >= ctx->Const.MaxVertexStreams) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedbackStream*(index>=MaxVertexStream)"); return GL_FALSE; } + if (!obj->EndedAnytime) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback*"); + return GL_FALSE; + } + if (numInstances <= 0) { if (numInstances < 0) _mesa_error(ctx, GL_INVALID_VALUE,