mesa: don't always enable OES_standard_derivatives
[mesa.git] / src / mesa / main / api_validate.c
index 631bceecfee2b0b3749b648ae9e082a43a83f78c..6f025080038c534f43e49876cacf9c45d1b7dbb8 100644 (file)
@@ -22,6 +22,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+#include <stdbool.h>
 #include "glheader.h"
 #include "api_validate.h"
 #include "bufferobj.h"
@@ -31,6 +32,7 @@
 #include "mtypes.h"
 #include "enums.h"
 #include "vbo/vbo.h"
+#include <stdbool.h>
 
 
 /**
@@ -108,26 +110,22 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
    }
 
    switch (ctx->API) {
-#if FEATURE_es2_glsl
    case API_OPENGLES2:
       /* For ES2, we can draw if any vertex array is enabled (and we
        * should always have a vertex program/shader). */
       if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current)
         return GL_FALSE;
       break;
-#endif
 
-#if FEATURE_ES1
    case API_OPENGLES:
       /* For OpenGL ES, only draw if we have vertex positions
        */
       if (!ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled)
         return GL_FALSE;
       break;
-#endif
 
-#if FEATURE_GL
    case API_OPENGL:
+   case API_OPENGL_CORE:
       {
          const struct gl_shader_program *vsProg =
             ctx->Shader.CurrentVertexProgram;
@@ -148,10 +146,9 @@ check_valid_to_render(struct gl_context *ctx, const char *function)
          }
       }
       break;
-#endif
 
    default:
-      ASSERT_NO_FEATURE();
+      assert(!"Invalid API value in check_valid_to_render()");
    }
 
    return GL_TRUE;
@@ -207,12 +204,36 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type,
 GLboolean
 _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
 {
-   if (ctx->Extensions.ARB_geometry_shader4 &&
-       mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
-      return GL_FALSE;
+   bool valid_enum;
+
+   switch (mode) {
+   case GL_POINTS:
+   case GL_LINES:
+   case GL_LINE_LOOP:
+   case GL_LINE_STRIP:
+   case GL_TRIANGLES:
+   case GL_TRIANGLE_STRIP:
+   case GL_TRIANGLE_FAN:
+      valid_enum = true;
+      break;
+   case GL_QUADS:
+   case GL_QUAD_STRIP:
+   case GL_POLYGON:
+      valid_enum = (ctx->API == API_OPENGL);
+      break;
+   case GL_LINES_ADJACENCY:
+   case GL_LINE_STRIP_ADJACENCY:
+   case GL_TRIANGLES_ADJACENCY:
+   case GL_TRIANGLE_STRIP_ADJACENCY:
+      valid_enum = _mesa_is_desktop_gl(ctx)
+         && ctx->Extensions.ARB_geometry_shader4;
+      break;
+   default:
+      valid_enum = false;
+      break;
    }
-   else if (mode > GL_POLYGON) {
+
+   if (!valid_enum) {
       _mesa_error(ctx, GL_INVALID_ENUM, "%s(mode=%x)", name, mode);
       return GL_FALSE;
    }
@@ -261,6 +282,26 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name)
    return GL_TRUE;
 }
 
+/**
+ * Verify that the element type is valid.
+ *
+ * Generates \c GL_INVALID_ENUM and returns \c false if it is not.
+ */
+static bool
+valid_elements_type(struct gl_context *ctx, GLenum type, const char *name)
+{
+   switch (type) {
+   case GL_UNSIGNED_BYTE:
+   case GL_UNSIGNED_SHORT:
+   case GL_UNSIGNED_INT:
+      return true;
+
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", name,
+                  _mesa_lookup_enum_by_nr(type));
+      return false;
+   }
+}
 
 /**
  * Error checking for glDrawElements().  Includes parameter checking
@@ -272,7 +313,8 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
                            GLenum mode, GLsizei count, GLenum type,
                            const GLvoid *indices, GLint basevertex)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    if (count <= 0) {
       if (count < 0)
@@ -284,13 +326,8 @@ _mesa_validate_DrawElements(struct gl_context *ctx,
       return GL_FALSE;
    }
 
-   if (type != GL_UNSIGNED_INT &&
-       type != GL_UNSIGNED_BYTE &&
-       type != GL_UNSIGNED_SHORT)
-   {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
+   if (!valid_elements_type(ctx, type, "glDrawElements"))
       return GL_FALSE;
-   }
 
    if (!check_valid_to_render(ctx, "glDrawElements"))
       return GL_FALSE;
@@ -330,7 +367,8 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx,
 {
    unsigned i;
 
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    for (i = 0; i < primcount; i++) {
       if (count[i] <= 0) {
@@ -345,13 +383,8 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx,
       return GL_FALSE;
    }
 
-   if (type != GL_UNSIGNED_INT &&
-       type != GL_UNSIGNED_BYTE &&
-       type != GL_UNSIGNED_SHORT)
-   {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glMultiDrawElements(type)" );
+   if (!valid_elements_type(ctx, type, "glMultiDrawElements"))
       return GL_FALSE;
-   }
 
    if (!check_valid_to_render(ctx, "glMultiDrawElements"))
       return GL_FALSE;
@@ -398,7 +431,8 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
                                 GLsizei count, GLenum type,
                                 const GLvoid *indices, GLint basevertex)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    if (count <= 0) {
       if (count < 0)
@@ -415,12 +449,8 @@ _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode,
       return GL_FALSE;
    }
 
-   if (type != GL_UNSIGNED_INT &&
-       type != GL_UNSIGNED_BYTE &&
-       type != GL_UNSIGNED_SHORT) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" );
+   if (!valid_elements_type(ctx, type, "glDrawRangeElements"))
       return GL_FALSE;
-   }
 
    if (!check_valid_to_render(ctx, "glDrawRangeElements"))
       return GL_FALSE;
@@ -456,7 +486,8 @@ GLboolean
 _mesa_validate_DrawArrays(struct gl_context *ctx,
                          GLenum mode, GLint start, GLsizei count)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    if (count <= 0) {
       if (count < 0)
@@ -484,7 +515,8 @@ GLboolean
 _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first,
                                    GLsizei count, GLsizei numInstances)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    if (count <= 0) {
       if (count < 0)
@@ -528,7 +560,8 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
                                      const GLvoid *indices, GLsizei numInstances,
                                      GLint basevertex)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
    if (count <= 0) {
       if (count < 0)
@@ -541,13 +574,8 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
       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);
+   if (!valid_elements_type(ctx, type, "glDrawElementsInstanced"))
       return GL_FALSE;
-   }
 
    if (numInstances <= 0) {
       if (numInstances < 0)
@@ -582,34 +610,47 @@ _mesa_validate_DrawElementsInstanced(struct gl_context *ctx,
 }
 
 
-#if FEATURE_EXT_transform_feedback
-
 GLboolean
 _mesa_validate_DrawTransformFeedback(struct gl_context *ctx,
                                      GLenum mode,
-                                     struct gl_transform_feedback_object *obj)
+                                     struct gl_transform_feedback_object *obj,
+                                     GLuint stream,
+                                     GLsizei numInstances)
 {
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, GL_FALSE);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+   FLUSH_CURRENT(ctx, 0);
 
-   if (!_mesa_valid_prim_mode(ctx, mode, "glDrawTransformFeedback")) {
+   if (!_mesa_valid_prim_mode(ctx, mode, "glDrawTransformFeedback*(mode)")) {
       return GL_FALSE;
    }
 
    if (!obj) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback(name)");
+      _mesa_error(ctx, GL_INVALID_VALUE, "glDrawTransformFeedback*(name)");
       return GL_FALSE;
    }
 
    if (!obj->EndedAnytime) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawTransformFeedback");
+      _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 (numInstances <= 0) {
+      if (numInstances < 0)
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDrawTransformFeedback*Instanced(numInstances=%d)",
+                     numInstances);
       return GL_FALSE;
    }
 
-   if (!check_valid_to_render(ctx, "glDrawTransformFeedback")) {
+   if (!check_valid_to_render(ctx, "glDrawTransformFeedback*")) {
       return GL_FALSE;
    }
 
    return GL_TRUE;
 }
-
-#endif