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