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#include "version.h" 36 37/** 38 * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query. 39 */ 40static const GLubyte * 41shading_language_version(struct gl_context *ctx) 42{ 43 switch (ctx->API) { 44 case API_OPENGL_COMPAT: 45 case API_OPENGL_CORE: 46 switch (ctx->Const.GLSLVersion) { 47 case 120: 48 return (const GLubyte *) "1.20"; 49 case 130: 50 return (const GLubyte *) "1.30"; 51 case 140: 52 return (const GLubyte *) "1.40"; 53 case 150: 54 return (const GLubyte *) "1.50"; 55 case 330: 56 return (const GLubyte *) "3.30"; 57 case 400: 58 return (const GLubyte *) "4.00"; 59 case 410: 60 return (const GLubyte *) "4.10"; 61 case 420: 62 return (const GLubyte *) "4.20"; 63 case 430: 64 return (const GLubyte *) "4.30"; 65 case 440: 66 return (const GLubyte *) "4.40"; 67 case 450: 68 return (const GLubyte *) "4.50"; 69 case 460: 70 return (const GLubyte *) "4.60"; 71 default: 72 _mesa_problem(ctx, 73 "Invalid GLSL version in shading_language_version()"); 74 return (const GLubyte *) 0; 75 } 76 break; 77 78 case API_OPENGLES2: 79 switch (ctx->Version) { 80 case 20: 81 return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; 82 case 30: 83 return (const GLubyte *) "OpenGL ES GLSL ES 3.00"; 84 case 31: 85 return (const GLubyte *) "OpenGL ES GLSL ES 3.10"; 86 case 32: 87 return (const GLubyte *) "OpenGL ES GLSL ES 3.20"; 88 default: 89 _mesa_problem(ctx, 90 "Invalid OpenGL ES version in shading_language_version()"); 91 return (const GLubyte *) 0; 92 } 93 case API_OPENGLES: 94 /* fall-through */ 95 96 default: 97 _mesa_problem(ctx, "Unexpected API value in shading_language_version()"); 98 return (const GLubyte *) 0; 99 } 100} 101 102 103/** 104 * Query string-valued state. The return value should _not_ be freed by 105 * the caller. 106 * 107 * \param name the state variable to query. 108 * 109 * \sa glGetString(). 110 * 111 * Tries to get the string from dd_function_table::GetString, otherwise returns 112 * the hardcoded strings. 113 */ 114const GLubyte * GLAPIENTRY 115_mesa_GetString( GLenum name ) 116{ 117 GET_CURRENT_CONTEXT(ctx); 118 static const char *vendor = "Brian Paul"; 119 static const char *renderer = "Mesa"; 120 121 if (!ctx) 122 return NULL; 123 124 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); 125 126 /* this is a required driver function */ 127 assert(ctx->Driver.GetString); 128 { 129 /* Give the driver the chance to handle this query */ 130 const GLubyte *str = ctx->Driver.GetString(ctx, name); 131 if (str) 132 return str; 133 } 134 135 switch (name) { 136 case GL_VENDOR: 137 return (const GLubyte *) vendor; 138 case GL_RENDERER: 139 return (const GLubyte *) renderer; 140 case GL_VERSION: 141 return (const GLubyte *) ctx->VersionString; 142 case GL_EXTENSIONS: 143 if (ctx->API == API_OPENGL_CORE) { 144 _mesa_error(ctx, GL_INVALID_ENUM, "glGetString(GL_EXTENSIONS)"); 145 return (const GLubyte *) 0; 146 } 147 if (!ctx->Extensions.String) 148 ctx->Extensions.String = _mesa_make_extension_string(ctx); 149 return (const GLubyte *) ctx->Extensions.String; 150 case GL_SHADING_LANGUAGE_VERSION: 151 if (ctx->API == API_OPENGLES) 152 break; 153 return shading_language_version(ctx); 154 case GL_PROGRAM_ERROR_STRING_ARB: 155 if (ctx->API == API_OPENGL_COMPAT && 156 (ctx->Extensions.ARB_fragment_program || 157 ctx->Extensions.ARB_vertex_program)) { 158 return (const GLubyte *) ctx->Program.ErrorString; 159 } 160 break; 161 default: 162 break; 163 } 164 165 _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); 166 return (const GLubyte *) 0; 167} 168 169 170/** 171 * GL3 172 */ 173const GLubyte * GLAPIENTRY 174_mesa_GetStringi(GLenum name, GLuint index) 175{ 176 GET_CURRENT_CONTEXT(ctx); 177 178 if (!ctx) 179 return NULL; 180 181 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); 182 183 switch (name) { 184 case GL_EXTENSIONS: 185 if (index >= _mesa_get_extension_count(ctx)) { 186 _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index); 187 return (const GLubyte *) 0; 188 } 189 return _mesa_get_enabled_extension(ctx, index); 190 case GL_SHADING_LANGUAGE_VERSION: 191 { 192 char *version; 193 int num; 194 if (!_mesa_is_desktop_gl(ctx) || ctx->Version < 43) { 195 _mesa_error(ctx, GL_INVALID_ENUM, 196 "glGetStringi(GL_SHADING_LANGUAGE_VERSION): " 197 "supported only in GL4.3 and later"); 198 return (const GLubyte *) 0; 199 } 200 num = _mesa_get_shading_language_version(ctx, index, &version); 201 if (index >= num) { 202 _mesa_error(ctx, GL_INVALID_VALUE, 203 "glGetStringi(GL_SHADING_LANGUAGE_VERSION, index=%d)", 204 index); 205 return (const GLubyte *) 0; 206 } 207 return (const GLubyte *) version; 208 } 209 default: 210 _mesa_error(ctx, GL_INVALID_ENUM, "glGetStringi"); 211 return (const GLubyte *) 0; 212 } 213} 214 215 216 217/** 218 * Return pointer-valued state, such as a vertex array pointer. 219 * 220 * \param pname names state to be queried 221 * \param params returns the pointer value 222 * 223 * \sa glGetPointerv(). 224 * 225 * Tries to get the specified pointer via dd_function_table::GetPointerv, 226 * otherwise gets the specified pointer from the current context. 227 */ 228void GLAPIENTRY 229_mesa_GetPointerv( GLenum pname, GLvoid **params ) 230{ 231 GET_CURRENT_CONTEXT(ctx); 232 const GLuint clientUnit = ctx->Array.ActiveTexture; 233 const char *callerstr; 234 235 if (_mesa_is_desktop_gl(ctx)) 236 callerstr = "glGetPointerv"; 237 else 238 callerstr = "glGetPointervKHR"; 239 240 if (!params) 241 return; 242 243 if (MESA_VERBOSE & VERBOSE_API) 244 _mesa_debug(ctx, "%s %s\n", callerstr, _mesa_enum_to_string(pname)); 245 246 switch (pname) { 247 case GL_VERTEX_ARRAY_POINTER: 248 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 249 goto invalid_pname; 250 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS].Ptr; 251 break; 252 case GL_NORMAL_ARRAY_POINTER: 253 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 254 goto invalid_pname; 255 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr; 256 break; 257 case GL_COLOR_ARRAY_POINTER: 258 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 259 goto invalid_pname; 260 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr; 261 break; 262 case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT: 263 if (ctx->API != API_OPENGL_COMPAT) 264 goto invalid_pname; 265 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr; 266 break; 267 case GL_FOG_COORDINATE_ARRAY_POINTER_EXT: 268 if (ctx->API != API_OPENGL_COMPAT) 269 goto invalid_pname; 270 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_FOG].Ptr; 271 break; 272 case GL_INDEX_ARRAY_POINTER: 273 if (ctx->API != API_OPENGL_COMPAT) 274 goto invalid_pname; 275 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr; 276 break; 277 case GL_TEXTURE_COORD_ARRAY_POINTER: 278 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 279 goto invalid_pname; 280 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr; 281 break; 282 case GL_EDGE_FLAG_ARRAY_POINTER: 283 if (ctx->API != API_OPENGL_COMPAT) 284 goto invalid_pname; 285 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr; 286 break; 287 case GL_FEEDBACK_BUFFER_POINTER: 288 if (ctx->API != API_OPENGL_COMPAT) 289 goto invalid_pname; 290 *params = ctx->Feedback.Buffer; 291 break; 292 case GL_SELECTION_BUFFER_POINTER: 293 if (ctx->API != API_OPENGL_COMPAT) 294 goto invalid_pname; 295 *params = ctx->Select.Buffer; 296 break; 297 case GL_POINT_SIZE_ARRAY_POINTER_OES: 298 if (ctx->API != API_OPENGLES) 299 goto invalid_pname; 300 *params = (GLvoid *) ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr; 301 break; 302 case GL_DEBUG_CALLBACK_FUNCTION_ARB: 303 case GL_DEBUG_CALLBACK_USER_PARAM_ARB: 304 *params = _mesa_get_debug_state_ptr(ctx, pname); 305 break; 306 default: 307 goto invalid_pname; 308 } 309 310 return; 311 312invalid_pname: 313 _mesa_error( ctx, GL_INVALID_ENUM, "%s", callerstr); 314 return; 315} 316 317 318/** 319 * Returns the current GL error code, or GL_NO_ERROR. 320 * \return current error code 321 * 322 * Returns __struct gl_contextRec::ErrorValue. 323 */ 324GLenum GLAPIENTRY 325_mesa_GetError( void ) 326{ 327 GET_CURRENT_CONTEXT(ctx); 328 GLenum e = ctx->ErrorValue; 329 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 330 331 /* From Issue (3) of the KHR_no_error spec: 332 * 333 * "Should glGetError() always return NO_ERROR or have undefined 334 * results? 335 * 336 * RESOLVED: It should for all errors except OUT_OF_MEMORY." 337 */ 338 if (_mesa_is_no_error_enabled(ctx) && e != GL_OUT_OF_MEMORY) { 339 e = GL_NO_ERROR; 340 } 341 342 if (MESA_VERBOSE & VERBOSE_API) 343 _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_enum_to_string(e)); 344 345 ctx->ErrorValue = (GLenum) GL_NO_ERROR; 346 ctx->ErrorDebugCount = 0; 347 return e; 348} 349