mesa: extract helper function from _mesa_GetPointerv
[mesa.git] / src / mesa / main / getstring.c
index 1145d0f49f8eff788966a84906c8942bd0a59717..57299f37d45b70a21293c435764c7ce0ef642704 100644 (file)
  */
 
 
-
+#include <stdbool.h>
 #include "glheader.h"
 #include "context.h"
+#include "debug_output.h"
 #include "get.h"
 #include "enums.h"
 #include "extensions.h"
 #include "mtypes.h"
-
+#include "macros.h"
+#include "version.h"
+#include "spirv_extensions.h"
 
 /**
  * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query.
@@ -41,14 +44,7 @@ shading_language_version(struct gl_context *ctx)
    switch (ctx->API) {
    case API_OPENGL_COMPAT:
    case API_OPENGL_CORE:
-      if (!ctx->Extensions.ARB_shader_objects) {
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetString");
-         return (const GLubyte *) 0;
-      }
-
       switch (ctx->Const.GLSLVersion) {
-      case 110:
-         return (const GLubyte *) "1.10";
       case 120:
          return (const GLubyte *) "1.20";
       case 130:
@@ -65,6 +61,14 @@ shading_language_version(struct gl_context *ctx)
          return (const GLubyte *) "4.10";
       case 420:
          return (const GLubyte *) "4.20";
+      case 430:
+         return (const GLubyte *) "4.30";
+      case 440:
+         return (const GLubyte *) "4.40";
+      case 450:
+         return (const GLubyte *) "4.50";
+      case 460:
+         return (const GLubyte *) "4.60";
       default:
          _mesa_problem(ctx,
                        "Invalid GLSL version in shading_language_version()");
@@ -73,10 +77,20 @@ shading_language_version(struct gl_context *ctx)
       break;
 
    case API_OPENGLES2:
-      return (ctx->Version < 30)
-         ? (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"
-         : (const GLubyte *) "OpenGL ES GLSL ES 3.0";
-
+      switch (ctx->Version) {
+      case 20:
+         return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16";
+      case 30:
+         return (const GLubyte *) "OpenGL ES GLSL ES 3.00";
+      case 31:
+         return (const GLubyte *) "OpenGL ES GLSL ES 3.10";
+      case 32:
+         return (const GLubyte *) "OpenGL ES GLSL ES 3.20";
+      default:
+         _mesa_problem(ctx,
+                       "Invalid OpenGL ES version in shading_language_version()");
+         return (const GLubyte *) 0;
+      }
    case API_OPENGLES:
       /* fall-through */
 
@@ -110,11 +124,15 @@ _mesa_GetString( GLenum name )
 
    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
 
+   if (ctx->Const.VendorOverride && name == GL_VENDOR) {
+      return (const GLubyte *) ctx->Const.VendorOverride;
+   }
+
    /* this is a required driver function */
    assert(ctx->Driver.GetString);
    {
       /* Give the driver the chance to handle this query */
-      const GLubyte *str = (*ctx->Driver.GetString)(ctx, name);
+      const GLubyte *str = ctx->Driver.GetString(ctx, name);
       if (str)
          return str;
    }
@@ -131,6 +149,8 @@ _mesa_GetString( GLenum name )
             _mesa_error(ctx, GL_INVALID_ENUM, "glGetString(GL_EXTENSIONS)");
             return (const GLubyte *) 0;
          }
+         if (!ctx->Extensions.String)
+            ctx->Extensions.String = _mesa_make_extension_string(ctx);
          return (const GLubyte *) ctx->Extensions.String;
       case GL_SHADING_LANGUAGE_VERSION:
          if (ctx->API == API_OPENGLES)
@@ -172,27 +192,47 @@ _mesa_GetStringi(GLenum name, GLuint index)
          return (const GLubyte *) 0;
       }
       return _mesa_get_enabled_extension(ctx, index);
+   case GL_SHADING_LANGUAGE_VERSION:
+      {
+         char *version;
+         int num;
+         if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 43) {
+            _mesa_error(ctx, GL_INVALID_ENUM,
+                        "glGetStringi(GL_SHADING_LANGUAGE_VERSION): "
+                        "supported only in GL4.3 and later");
+            return (const GLubyte *) 0;
+         }
+         num = _mesa_get_shading_language_version(ctx, index, &version);
+         if (index >= num) {
+            _mesa_error(ctx, GL_INVALID_VALUE,
+                        "glGetStringi(GL_SHADING_LANGUAGE_VERSION, index=%d)",
+                        index);
+            return (const GLubyte *) 0;
+         }
+         return (const GLubyte *) version;
+      }
+   case GL_SPIR_V_EXTENSIONS:
+      if (!ctx->Extensions.ARB_spirv_extensions) {
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetStringi");
+         return (const GLubyte *) 0;
+      }
+
+      if (index >= _mesa_get_spirv_extension_count(ctx)) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index);
+         return (const GLubyte *) 0;
+      }
+      return _mesa_get_enabled_spirv_extension(ctx, index);
+
    default:
-      _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" );
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetStringi");
       return (const GLubyte *) 0;
    }
 }
 
 
-
-/**
- * Return pointer-valued state, such as a vertex array pointer.
- *
- * \param pname  names state to be queried
- * \param params  returns the pointer value
- *
- * \sa glGetPointerv().
- *
- * Tries to get the specified pointer via dd_function_table::GetPointerv,
- * otherwise gets the specified pointer from the current context.
- */
-void GLAPIENTRY
-_mesa_GetPointerv( GLenum pname, GLvoid **params )
+void
+_get_vao_pointerv(GLenum pname, struct gl_vertex_array_object* vao,
+                  GLvoid **params, const char* callerstr )
 {
    GET_CURRENT_CONTEXT(ctx);
    const GLuint clientUnit = ctx->Array.ActiveTexture;
@@ -201,48 +241,48 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params )
       return;
 
    if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));
+      _mesa_debug(ctx, "%s %s\n", callerstr, _mesa_enum_to_string(pname));
 
    switch (pname) {
       case GL_VERTEX_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_POS].Ptr;
          break;
       case GL_NORMAL_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
          break;
       case GL_COLOR_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr;
          break;
       case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
          if (ctx->API != API_OPENGL_COMPAT)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr;
          break;
       case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
          if (ctx->API != API_OPENGL_COMPAT)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_FOG].Ptr;
          break;
       case GL_INDEX_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
          break;
       case GL_TEXTURE_COORD_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr;
          break;
       case GL_EDGE_FLAG_ARRAY_POINTER:
          if (ctx->API != API_OPENGL_COMPAT)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
          break;
       case GL_FEEDBACK_BUFFER_POINTER:
          if (ctx->API != API_OPENGL_COMPAT)
@@ -257,17 +297,11 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params )
       case GL_POINT_SIZE_ARRAY_POINTER_OES:
          if (ctx->API != API_OPENGLES)
             goto invalid_pname;
-         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
+         *params = (GLvoid *) vao->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
          break;
       case GL_DEBUG_CALLBACK_FUNCTION_ARB:
-         if (!_mesa_is_desktop_gl(ctx))
-            goto invalid_pname;
-         *params = (GLvoid *) ctx->Debug.Callback;
-         break;
       case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
-         if (!_mesa_is_desktop_gl(ctx))
-            goto invalid_pname;
-         *params = ctx->Debug.CallbackData;
+         *params = _mesa_get_debug_state_ptr(ctx, pname);
          break;
       default:
          goto invalid_pname;
@@ -276,45 +310,94 @@ _mesa_GetPointerv( GLenum pname, GLvoid **params )
    return;
 
 invalid_pname:
-   _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
+   _mesa_error( ctx, GL_INVALID_ENUM, "%s", callerstr);
    return;
 }
 
 
 /**
- * Returns the current GL error code, or GL_NO_ERROR.
- * \return current error code
+ * Return pointer-valued state, such as a vertex array pointer.
  *
- * Returns __struct gl_contextRec::ErrorValue.
+ * \param pname  names state to be queried
+ * \param params  returns the pointer value
+ *
+ * \sa glGetPointerv().
+ *
+ * Tries to get the specified pointer via dd_function_table::GetPointerv,
+ * otherwise gets the specified pointer from the current context.
  */
-GLenum GLAPIENTRY
-_mesa_GetError( void )
+void GLAPIENTRY
+_mesa_GetPointerv( GLenum pname, GLvoid **params )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLenum e = ctx->ErrorValue;
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+   const char *callerstr;
+
+   if (_mesa_is_desktop_gl(ctx))
+      callerstr = "glGetPointerv";
+   else
+      callerstr = "glGetPointervKHR";
+
+   if (!params)
+      return;
+
+   _get_vao_pointerv(pname, ctx->Array.VAO, params, callerstr);
+}
+
+
+void GLAPIENTRY
+_mesa_GetPointerIndexedvEXT( GLenum pname, GLuint index, GLvoid **params )
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (!params)
+      return;
 
    if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
+      _mesa_debug(ctx, "%s %s\n", "glGetPointerIndexedvEXT", _mesa_enum_to_string(pname));
 
-   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
-   ctx->ErrorDebugCount = 0;
-   return e;
+   switch (pname) {
+      case GL_TEXTURE_COORD_ARRAY_POINTER:
+         *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(index)].Ptr;
+         break;
+      default:
+         goto invalid_pname;
+   }
+
+   return;
+
+invalid_pname:
+   _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerIndexedvEXT");
+   return;
 }
 
 /**
- * Returns an error code specified by GL_ARB_robustness, or GL_NO_ERROR.
- * \return current context status
+ * Returns the current GL error code, or GL_NO_ERROR.
+ * \return current error code
+ *
+ * Returns __struct gl_contextRec::ErrorValue.
  */
 GLenum GLAPIENTRY
-_mesa_GetGraphicsResetStatusARB( void )
+_mesa_GetError( void )
 {
    GET_CURRENT_CONTEXT(ctx);
-   GLenum status = ctx->ResetStatus;
+   GLenum e = ctx->ErrorValue;
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+   /* From Issue (3) of the KHR_no_error spec:
+    *
+    *    "Should glGetError() always return NO_ERROR or have undefined
+    *    results?
+    *
+    *    RESOLVED: It should for all errors except OUT_OF_MEMORY."
+    */
+   if (_mesa_is_no_error_enabled(ctx) && e != GL_OUT_OF_MEMORY) {
+      e = GL_NO_ERROR;
+   }
 
    if (MESA_VERBOSE & VERBOSE_API)
-      _mesa_debug(ctx, "glGetGraphicsResetStatusARB"
-                       "(always returns GL_NO_ERROR)\n");
+      _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_enum_to_string(e));
 
-   return status;
+   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+   ctx->ErrorDebugCount = 0;
+   return e;
 }