1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26 #include <stdbool.h> 27 #include "glheader.h" 28 #include "context.h" 29 #include "debug_output.h" 30 #include "get.h" 31 #include "enums.h" 32 #include "extensions.h" 33 #include "mtypes.h" 34 #include "macros.h" 35 36 /** 37 * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query. 38 */ 39 static const GLubyte * 40 shading_language_version(struct gl_context *ctx) 41 { 42 switch (ctx->API) { 43 case API_OPENGL_COMPAT: 44 case API_OPENGL_CORE: 45 switch (ctx->Const.GLSLVersion) { 46 case 120: 47 return (const GLubyte *) "1.20"; 48 case 130: 49 return (const GLubyte *) "1.30"; 50 case 140: 51 return (const GLubyte *) "1.40"; 52 case 150: 53 return (const GLubyte *) "1.50"; 54 case 330: 55 return (const GLubyte *) "3.30"; 56 case 400: 57 return (const GLubyte *) "4.00"; 58 case 410: 59 return (const GLubyte *) "4.10"; 60 case 420: 61 return (const GLubyte *) "4.20"; 62 case 430: 63 return (const GLubyte *) "4.30"; 64 case 440: 65 return (const GLubyte *) "4.40"; 66 case 450: 67 return (const GLubyte *) "4.50"; 68 default: 69 _mesa_problem(ctx, 70 "Invalid GLSL version in shading_language_version()"); 71 return (const GLubyte *) 0; 72 } 73 break; 74 75 case API_OPENGLES2: 76 switch (ctx->Version) { 77 case 20: 78 return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; 79 case 30: 80 return (const GLubyte *) "OpenGL ES GLSL ES 3.00"; 81 case 31: 82 return (const GLubyte *) "OpenGL ES GLSL ES 3.10"; 83 case 32: 84 return (const GLubyte *) "OpenGL ES GLSL ES 3.20"; 85 default: 86 _mesa_problem(ctx, 87 "Invalid OpenGL ES version in shading_language_version()"); 88 return (const GLubyte *) 0; 89 } 90 case API_OPENGLES: 91 /* fall-through */ 92 93 default: 94 _mesa_problem(ctx, "Unexpected API value in shading_language_version()"); 95 return (const GLubyte *) 0; 96 } 97 } 98 99 100 /** 101 * Query string-valued state. The return value should _not_ be freed by 102 * the caller. 103 * 104 * \param name the state variable to query. 105 * 106 * \sa glGetString(). 107 * 108 * Tries to get the string from dd_function_table::GetString, otherwise returns 109 * the hardcoded strings. 110 */ 111 const GLubyte * GLAPIENTRY 112 _mesa_GetString( GLenum name ) 113 { 114 GET_CURRENT_CONTEXT(ctx); 115 static const char *vendor = "Brian Paul"; 116 static const char *renderer = "Mesa"; 117 118 if (!ctx) 119 return NULL; 120 121 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); 122 123 /* this is a required driver function */ 124 assert(ctx->Driver.GetString); 125 { 126 /* Give the driver the chance to handle this query */ 127 const GLubyte *str = ctx->Driver.GetString(ctx, name); 128 if (str) 129 return str; 130 } 131 132 switch (name) { 133 case GL_VENDOR: 134 return (const GLubyte *) vendor; 135 case GL_RENDERER: 136 return (const GLubyte *) renderer; 137 case GL_VERSION: 138 return (const GLubyte *) ctx->VersionString; 139 case GL_EXTENSIONS: 140 if (ctx->API == API_OPENGL_CORE) { 141 _mesa_error(ctx, GL_INVALID_ENUM, "glGetString(GL_EXTENSIONS)"); 142 return (const GLubyte *) 0; 143 } 144 return (const GLubyte *) ctx->Extensions.String; 145 case GL_SHADING_LANGUAGE_VERSION: 146 if (ctx->API == API_OPENGLES) 147 break; 148 return shading_language_version(ctx); 149 case GL_PROGRAM_ERROR_STRING_ARB: 150 if (ctx->API == API_OPENGL_COMPAT && 151 (ctx->Extensions.ARB_fragment_program || 152 ctx->Extensions.ARB_vertex_program)) { 153 return (const GLubyte *) ctx->Program.ErrorString; 154 } 155 break; 156 default: 157 break; 158 } 159 160 _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); 161 return (const GLubyte *) 0; 162 } 163 164 165 /** 166 * GL3 167 */ 168 const GLubyte * GLAPIENTRY 169 _mesa_GetStringi(GLenum name, GLuint index) 170 { 171 GET_CURRENT_CONTEXT(ctx); 172 173 if (!ctx) 174 return NULL; 175 176 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); 177 178 switch (name) { 179 case GL_EXTENSIONS: 180 if (index >= _mesa_get_extension_count(ctx)) { 181 _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index); 182 return (const GLubyte *) 0; 183 } 184 return _mesa_get_enabled_extension(ctx, index); 185 default: 186 _mesa_error(ctx, GL_INVALID_ENUM, "glGetStringi"); 187 return (const GLubyte *) 0; 188 } 189 } 190 191 192 193 /** 194 * Return pointer-valued state, such as a vertex array pointer. 195 * 196 * \param pname names state to be queried 197 * \param params returns the pointer value 198 * 199 * \sa glGetPointerv(). 200 * 201 * Tries to get the specified pointer via dd_function_table::GetPointerv, 202 * otherwise gets the specified pointer from the current context. 203 */ 204 void GLAPIENTRY 205 _mesa_GetPointerv( GLenum pname, GLvoid **params ) 206 { 207 GET_CURRENT_CONTEXT(ctx); 208 const GLuint clientUnit = ctx->Array.ActiveTexture; 209 const char *callerstr; 210 211 if (_mesa_is_desktop_gl(ctx)) 212 callerstr = "glGetPointerv"; 213 else 214 callerstr = "glGetPointervKHR"; 215 216 if (!params) 217 return; 218 219 if (MESA_VERBOSE & VERBOSE_API) 220 _mesa_debug(ctx, "%s %s\n", callerstr, _mesa_enum_to_string(pname)); 221 222 switch (pname) { 223 case GL_VERTEX_ARRAY_POINTER: 224 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 225 goto invalid_pname; 226 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Ptr; 227 break; 228 case GL_NORMAL_ARRAY_POINTER: 229 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 230 goto invalid_pname; 231 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr; 232 break; 233 case GL_COLOR_ARRAY_POINTER: 234 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 235 goto invalid_pname; 236 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr; 237 break; 238 case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT: 239 if (ctx->API != API_OPENGL_COMPAT) 240 goto invalid_pname; 241 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr; 242 break; 243 case GL_FOG_COORDINATE_ARRAY_POINTER_EXT: 244 if (ctx->API != API_OPENGL_COMPAT) 245 goto invalid_pname; 246 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_FOG].Ptr; 247 break; 248 case GL_INDEX_ARRAY_POINTER: 249 if (ctx->API != API_OPENGL_COMPAT) 250 goto invalid_pname; 251 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr; 252 break; 253 case GL_TEXTURE_COORD_ARRAY_POINTER: 254 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 255 goto invalid_pname; 256 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr; 257 break; 258 case GL_EDGE_FLAG_ARRAY_POINTER: 259 if (ctx->API != API_OPENGL_COMPAT) 260 goto invalid_pname; 261 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr; 262 break; 263 case GL_FEEDBACK_BUFFER_POINTER: 264 if (ctx->API != API_OPENGL_COMPAT) 265 goto invalid_pname; 266 *params = ctx->Feedback.Buffer; 267 break; 268 case GL_SELECTION_BUFFER_POINTER: 269 if (ctx->API != API_OPENGL_COMPAT) 270 goto invalid_pname; 271 *params = ctx->Select.Buffer; 272 break; 273 case GL_POINT_SIZE_ARRAY_POINTER_OES: 274 if (ctx->API != API_OPENGLES) 275 goto invalid_pname; 276 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr; 277 break; 278 case GL_DEBUG_CALLBACK_FUNCTION_ARB: 279 case GL_DEBUG_CALLBACK_USER_PARAM_ARB: 280 *params = _mesa_get_debug_state_ptr(ctx, pname); 281 break; 282 default: 283 goto invalid_pname; 284 } 285 286 return; 287 288 invalid_pname: 289 _mesa_error( ctx, GL_INVALID_ENUM, "%s", callerstr); 290 return; 291 } 292 293 294 /** 295 * Returns the current GL error code, or GL_NO_ERROR. 296 * \return current error code 297 * 298 * Returns __struct gl_contextRec::ErrorValue. 299 */ 300 GLenum GLAPIENTRY 301 _mesa_GetError( void ) 302 { 303 GET_CURRENT_CONTEXT(ctx); 304 GLenum e = ctx->ErrorValue; 305 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 306 307 if (MESA_VERBOSE & VERBOSE_API) 308 _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_enum_to_string(e)); 309 310 ctx->ErrorValue = (GLenum) GL_NO_ERROR; 311 ctx->ErrorDebugCount = 0; 312 return e; 313 } 314