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