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