From 2ab18d63cb71d988265eeab431e4363081978144 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 09:25:51 -0400 Subject: mesa: Track the OpenGL API we're implementing in the context This introduces a new way to create or initialize a context: _mesa_create_context_for_api and _mesa_initialize_context_for_api which in addition to the current arguments take an api enum to indicate which OpenGL API the context should implement. At this point the API field in GLcontext isn't used anywhere, but later commits will key certain functionality off of it. The _mesa_create_context and _mesa_initialize_context functions are kept in place as wrappers around the *_for_api versions, passing in API_OPENGL to get the same behavior as before. --- src/mesa/main/context.c | 52 ++++++++++++++++++++++++++++++++++++++----------- src/mesa/main/context.h | 15 ++++++++++++++ src/mesa/main/mtypes.h | 9 +++++++++ 3 files changed, 65 insertions(+), 11 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 1707e229c9..87e5a88fad 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -791,6 +791,7 @@ alloc_dispatch_table(void) * for debug flags. * * \param ctx the context to initialize + * \param api the GL API type to create the context for * \param visual describes the visual attributes for this context * \param share_list points to context to share textures, display lists, * etc with, or NULL @@ -799,11 +800,12 @@ alloc_dispatch_table(void) * \param driverContext pointer to driver-specific context data */ GLboolean -_mesa_initialize_context(GLcontext *ctx, - const GLvisual *visual, - GLcontext *share_list, - const struct dd_function_table *driverFunctions, - void *driverContext) +_mesa_initialize_context_for_api(GLcontext *ctx, + gl_api api, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) { struct gl_shared_state *shared; @@ -814,6 +816,7 @@ _mesa_initialize_context(GLcontext *ctx, /* misc one-time initializations */ one_time_init(ctx); + ctx->API = api; ctx->Visual = *visual; ctx->DrawBuffer = NULL; ctx->ReadBuffer = NULL; @@ -892,6 +895,20 @@ _mesa_initialize_context(GLcontext *ctx, return GL_TRUE; } +GLboolean +_mesa_initialize_context(GLcontext *ctx, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + return _mesa_initialize_context_for_api(ctx, + API_OPENGL, + visual, + share_list, + driverFunctions, + driverContext); +} /** * Allocate and initialize a GLcontext structure. @@ -899,6 +916,7 @@ _mesa_initialize_context(GLcontext *ctx, * we need to at least call driverFunctions->NewTextureObject to initialize * the rendering context. * + * \param api the GL API type to create the context for * \param visual a GLvisual pointer (we copy the struct contents) * \param share_list another context to share display lists with or NULL * \param driverFunctions points to the dd_function_table into which the @@ -908,10 +926,11 @@ _mesa_initialize_context(GLcontext *ctx, * \return pointer to a new __GLcontextRec or NULL if error. */ GLcontext * -_mesa_create_context(const GLvisual *visual, - GLcontext *share_list, - const struct dd_function_table *driverFunctions, - void *driverContext) +_mesa_create_context_for_api(gl_api api, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) { GLcontext *ctx; @@ -922,8 +941,8 @@ _mesa_create_context(const GLvisual *visual, if (!ctx) return NULL; - if (_mesa_initialize_context(ctx, visual, share_list, - driverFunctions, driverContext)) { + if (_mesa_initialize_context_for_api(ctx, api, visual, share_list, + driverFunctions, driverContext)) { return ctx; } else { @@ -932,6 +951,17 @@ _mesa_create_context(const GLvisual *visual, } } +GLcontext * +_mesa_create_context(const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) +{ + return _mesa_create_context_for_api(API_OPENGL, visual, + share_list, + driverFunctions, + driverContext); +} /** * Free the data associated with the given context. diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index 09bf1777da..e9405c8bc2 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -112,6 +112,21 @@ _mesa_initialize_context( GLcontext *ctx, const struct dd_function_table *driverFunctions, void *driverContext ); +extern GLcontext * +_mesa_create_context_for_api(gl_api api, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext); + +extern GLboolean +_mesa_initialize_context_for_api(GLcontext *ctx, + gl_api api, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext); + extern void _mesa_initialize_context_extra(GLcontext *ctx); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 349d5f51e6..e5e099acc3 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2869,6 +2869,14 @@ struct gl_dlist_state } Current; }; +/** + * Enum for the OpenGL APIs we know about and may support. + */ +typedef enum { + API_OPENGL, + API_OPENGLES, + API_OPENGLES2, +} gl_api; /** * Mesa rendering context. @@ -2887,6 +2895,7 @@ struct __GLcontextRec /** \name API function pointer tables */ /*@{*/ + gl_api API; struct _glapi_table *Save; /**< Display list save functions */ struct _glapi_table *Exec; /**< Execute functions */ struct _glapi_table *CurrentDispatch; /**< == Save or Exec !! */ -- cgit v1.2.3 From 38d771c0539a087db42d8d940bb2e920bb64598c Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 09:32:11 -0400 Subject: st/mesa: Use API-aware context constructor The mesa state tracker is currently the only place where we create a context and expect it to implement GLES1/2. Use the API-aware constructor to communicate this to core mesa. --- src/mesa/state_tracker/st_context.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/mesa') diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 5fcb6b9dcf..48fc86cd52 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -199,7 +199,16 @@ struct st_context *st_create_context(struct pipe_context *pipe, memset(&funcs, 0, sizeof(funcs)); st_init_driver_functions(&funcs); - ctx = _mesa_create_context(visual, shareCtx, &funcs, NULL); +#if FEATURE_ES1 + ctx = _mesa_create_context_for_api(API_OPENGLES, + visual, shareCtx, &funcs, NULL); +#elif FEATURE_ES2 + ctx = _mesa_create_context_for_api(API_OPENGLES2, + visual, shareCtx, &funcs, NULL); +#else + ctx = _mesa_create_context_for_api(API_OPENGL, + visual, shareCtx, &funcs, NULL); +#endif /* XXX: need a capability bit in gallium to query if the pipe * driver prefers DP4 or MUL/MAD for vertex transformation. -- cgit v1.2.3 From 218ceb3e1874a5a28f36a8df3ca0e881cdf213d5 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 11:07:45 -0400 Subject: mesa: Move API specific context intialization into context.c --- src/mesa/es/main/specials_es1.c | 21 --------------------- src/mesa/es/main/specials_es2.c | 10 ---------- src/mesa/main/context.c | 28 +++++++++++++++++++++++++--- src/mesa/main/context.h | 3 --- 4 files changed, 25 insertions(+), 37 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/es/main/specials_es1.c b/src/mesa/es/main/specials_es1.c index 92e24a03fe..88f77177c8 100644 --- a/src/mesa/es/main/specials_es1.c +++ b/src/mesa/es/main/specials_es1.c @@ -195,24 +195,3 @@ _es_GetString(GLenum name) return _mesa_GetString(name); } } - - -void -_mesa_initialize_context_extra(GLcontext *ctx) -{ - GLuint i; - - /** - * GL_OES_texture_cube_map says - * "Initially all texture generation modes are set to REFLECTION_MAP_OES" - */ - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; - texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; - } -} diff --git a/src/mesa/es/main/specials_es2.c b/src/mesa/es/main/specials_es2.c index 046cda6fc1..75ceaff2c2 100644 --- a/src/mesa/es/main/specials_es2.c +++ b/src/mesa/es/main/specials_es2.c @@ -167,13 +167,3 @@ _es_GetString(GLenum name) return _mesa_GetString(name); } } - - -void -_mesa_initialize_context_extra(GLcontext *ctx) -{ - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - - ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */ -} diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 87e5a88fad..25288a4e9c 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -808,6 +808,7 @@ _mesa_initialize_context_for_api(GLcontext *ctx, void *driverContext) { struct gl_shared_state *shared; + int i; /*ASSERT(driverContext);*/ assert(driverFunctions->NewTextureObject); @@ -886,9 +887,30 @@ _mesa_initialize_context_for_api(GLcontext *ctx, ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; } -#if FEATURE_extra_context_init - _mesa_initialize_context_extra(ctx); -#endif + switch (ctx->API) { + case API_OPENGL: + break; + case API_OPENGLES: + /** + * GL_OES_texture_cube_map says + * "Initially all texture generation modes are set to REFLECTION_MAP_OES" + */ + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; + } + break; + case API_OPENGLES2: + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; + ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */ + break; + } ctx->FirstTimeCurrent = GL_TRUE; diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index e9405c8bc2..c9f4d433a5 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -127,9 +127,6 @@ _mesa_initialize_context_for_api(GLcontext *ctx, const struct dd_function_table *driverFunctions, void *driverContext); -extern void -_mesa_initialize_context_extra(GLcontext *ctx); - extern void _mesa_free_context_data( GLcontext *ctx ); -- cgit v1.2.3 From 29107d4e07144f41614f053aa1fc49ccf225fedf Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Wed, 21 Apr 2010 16:14:18 -0400 Subject: mesa: Compute GL version according to API --- src/mesa/es/main/specials_es1.c | 29 --------- src/mesa/es/main/specials_es2.c | 30 ---------- src/mesa/main/version.c | 128 +++++++++++++++++++++++++++++++++------- 3 files changed, 107 insertions(+), 80 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/es/main/specials_es1.c b/src/mesa/es/main/specials_es1.c index 88f77177c8..37a5943490 100644 --- a/src/mesa/es/main/specials_es1.c +++ b/src/mesa/es/main/specials_es1.c @@ -32,33 +32,6 @@ extern const GLubyte * GLAPIENTRY _es_GetString(GLenum name); -static const GLubyte * -compute_es_version(void) -{ - GET_CURRENT_CONTEXT(ctx); - static const char es_1_0[] = "OpenGL ES-CM 1.0"; - static const char es_1_1[] = "OpenGL ES-CM 1.1"; - /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ - const GLboolean ver_1_0 = (ctx->Extensions.ARB_multisample && - ctx->Extensions.ARB_multitexture && - ctx->Extensions.ARB_texture_compression && - ctx->Extensions.EXT_texture_env_add && - ctx->Extensions.ARB_texture_env_combine && - ctx->Extensions.ARB_texture_env_dot3); - /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ - const GLboolean ver_1_1 = (ver_1_0 && - ctx->Extensions.EXT_point_parameters && - ctx->Extensions.SGIS_generate_mipmap && - ctx->Extensions.ARB_vertex_buffer_object); - if (ver_1_1) - return (const GLubyte *) es_1_1; - - if (!ver_1_0) - _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); - return (const GLubyte *) es_1_0; -} - - static size_t append_extension(char **str, const char *ext) { @@ -187,8 +160,6 @@ const GLubyte * GLAPIENTRY _es_GetString(GLenum name) { switch (name) { - case GL_VERSION: - return compute_es_version(); case GL_EXTENSIONS: return compute_es_extensions(); default: diff --git a/src/mesa/es/main/specials_es2.c b/src/mesa/es/main/specials_es2.c index 75ceaff2c2..24fecb837f 100644 --- a/src/mesa/es/main/specials_es2.c +++ b/src/mesa/es/main/specials_es2.c @@ -32,34 +32,6 @@ const GLubyte * GLAPIENTRY _es_GetString(GLenum name); -static const GLubyte * -compute_es_version(void) -{ - GET_CURRENT_CONTEXT(ctx); - static const char es_2_0[] = "OpenGL ES 2.0"; - /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ - const GLboolean ver_2_0 = (ctx->Extensions.ARB_multisample && - ctx->Extensions.ARB_multitexture && - ctx->Extensions.ARB_texture_compression && - ctx->Extensions.ARB_texture_cube_map && - ctx->Extensions.ARB_texture_mirrored_repeat && - ctx->Extensions.EXT_blend_color && - ctx->Extensions.EXT_blend_func_separate && - ctx->Extensions.EXT_blend_minmax && - ctx->Extensions.EXT_blend_subtract && - ctx->Extensions.EXT_stencil_wrap && - ctx->Extensions.ARB_vertex_buffer_object && - ctx->Extensions.ARB_shader_objects && - ctx->Extensions.ARB_vertex_shader && - ctx->Extensions.ARB_fragment_shader && - ctx->Extensions.ARB_texture_non_power_of_two && - ctx->Extensions.EXT_blend_equation_separate); - if (!ver_2_0) - _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); - return (const GLubyte *) es_2_0; -} - - static size_t append_extension(char **str, const char *ext) { @@ -157,8 +129,6 @@ const GLubyte * GLAPIENTRY _es_GetString(GLenum name) { switch (name) { - case GL_VERSION: - return compute_es_version(); case GL_SHADING_LANGUAGE_VERSION: return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; case GL_EXTENSIONS: diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c index a39b680650..dea3019d0b 100644 --- a/src/mesa/main/version.c +++ b/src/mesa/main/version.c @@ -32,8 +32,11 @@ * Return major and minor version numbers. */ static void -compute_version(const GLcontext *ctx, GLuint *major, GLuint *minor) +compute_version(GLcontext *ctx) { + GLuint major, minor; + static const int max = 100; + const GLboolean ver_1_3 = (ctx->Extensions.ARB_multisample && ctx->Extensions.ARB_multitexture && ctx->Extensions.ARB_texture_border_clamp && @@ -85,31 +88,111 @@ compute_version(const GLcontext *ctx, GLuint *major, GLuint *minor) ctx->Extensions.EXT_pixel_buffer_object && ctx->Extensions.EXT_texture_sRGB); if (ver_2_1) { - *major = 2; - *minor = 1; + major = 2; + minor = 1; } else if (ver_2_0) { - *major = 2; - *minor = 0; + major = 2; + minor = 0; } else if (ver_1_5) { - *major = 1; - *minor = 5; + major = 1; + minor = 5; } else if (ver_1_4) { - *major = 1; - *minor = 4; + major = 1; + minor = 4; } else if (ver_1_3) { - *major = 1; - *minor = 3; + major = 1; + minor = 3; } else { - *major = 1; - *minor = 2; + major = 1; + minor = 2; + } + + ctx->VersionMajor = major; + ctx->VersionMinor = minor; + ctx->VersionString = (char *) malloc(max); + if (ctx->VersionString) { + _mesa_snprintf(ctx->VersionString, max, + "%u.%u Mesa " MESA_VERSION_STRING, + ctx->VersionMajor, ctx->VersionMinor); } } +static void +compute_version_es1(GLcontext *ctx) +{ + static const int max = 100; + + /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ + const GLboolean ver_1_0 = (ctx->Extensions.ARB_multisample && + ctx->Extensions.ARB_multitexture && + ctx->Extensions.ARB_texture_compression && + ctx->Extensions.EXT_texture_env_add && + ctx->Extensions.ARB_texture_env_combine && + ctx->Extensions.ARB_texture_env_dot3); + /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ + const GLboolean ver_1_1 = (ver_1_0 && + ctx->Extensions.EXT_point_parameters && + ctx->Extensions.SGIS_generate_mipmap && + ctx->Extensions.ARB_vertex_buffer_object); + + if (ver_1_1) { + ctx->VersionMajor = 1; + ctx->VersionMinor = 1; + } else if (ver_1_0) { + ctx->VersionMajor = 1; + ctx->VersionMinor = 0; + } else { + _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); + } + + ctx->VersionString = (char *) malloc(max); + if (ctx->VersionString) { + _mesa_snprintf(ctx->VersionString, max, + "OpenGL ES-CM 1.%d Mesa " MESA_VERSION_STRING, + ctx->VersionMinor); + } +} + +static void +compute_version_es2(GLcontext *ctx) +{ + static const int max = 100; + + /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ + const GLboolean ver_2_0 = (ctx->Extensions.ARB_multisample && + ctx->Extensions.ARB_multitexture && + ctx->Extensions.ARB_texture_compression && + ctx->Extensions.ARB_texture_cube_map && + ctx->Extensions.ARB_texture_mirrored_repeat && + ctx->Extensions.EXT_blend_color && + ctx->Extensions.EXT_blend_func_separate && + ctx->Extensions.EXT_blend_minmax && + ctx->Extensions.EXT_blend_subtract && + ctx->Extensions.EXT_stencil_wrap && + ctx->Extensions.ARB_vertex_buffer_object && + ctx->Extensions.ARB_shader_objects && + ctx->Extensions.ARB_vertex_shader && + ctx->Extensions.ARB_fragment_shader && + ctx->Extensions.ARB_texture_non_power_of_two && + ctx->Extensions.EXT_blend_equation_separate); + if (ver_2_0) { + ctx->VersionMajor = 2; + ctx->VersionMinor = 0; + } else { + _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); + } + + ctx->VersionString = (char *) malloc(max); + if (ctx->VersionString) { + _mesa_snprintf(ctx->VersionString, max, + "OpenGL ES 2.0 Mesa " MESA_VERSION_STRING); + } +} /** * Set the context's VersionMajor, VersionMinor, VersionString fields. @@ -118,13 +201,16 @@ compute_version(const GLcontext *ctx, GLuint *major, GLuint *minor) void _mesa_compute_version(GLcontext *ctx) { - static const int max = 100; - - compute_version(ctx, &ctx->VersionMajor, &ctx->VersionMinor); - - ctx->VersionString = (char *) malloc(max); - if (ctx->VersionString) { - _mesa_snprintf(ctx->VersionString, max, "%u.%u Mesa " MESA_VERSION_STRING, - ctx->VersionMajor, ctx->VersionMinor); + switch (ctx->API) { + case API_OPENGL: + compute_version(ctx); + break; + case API_OPENGLES: + compute_version_es1(ctx); + break; + case API_OPENGLES2: + compute_version_es2(ctx); + break; } + } -- cgit v1.2.3 From 04bf868ad9f0034ce7b726eadd2ffac346441a68 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 08:34:42 -0400 Subject: main: Report GL_SHADING_LANGUAGE_VERSION according to API --- src/mesa/es/main/specials_es2.c | 2 -- src/mesa/main/getstring.c | 37 +++++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/es/main/specials_es2.c b/src/mesa/es/main/specials_es2.c index 24fecb837f..ac499473a3 100644 --- a/src/mesa/es/main/specials_es2.c +++ b/src/mesa/es/main/specials_es2.c @@ -129,8 +129,6 @@ const GLubyte * GLAPIENTRY _es_GetString(GLenum name) { switch (name) { - case GL_SHADING_LANGUAGE_VERSION: - return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; case GL_EXTENSIONS: return compute_es_extensions(); default: diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index 51dd5f7795..e3a60fa6eb 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -30,6 +30,30 @@ #include "enums.h" #include "extensions.h" +static const GLubyte * +shading_laguage_version(GLcontext *ctx) +{ + switch (ctx->API) { +#if FEATURE_ARB_shading_language_100 + case API_OPENGL: + if (ctx->Extensions.ARB_shading_language_120) + return (const GLubyte *) "1.20"; + else if (ctx->Extensions.ARB_shading_language_100) + return (const GLubyte *) "1.10"; + goto error; +#endif + + case API_OPENGLES2: + return (const GLubyte *) "OpenGL ES GLSL ES 1.0.16"; + + case API_OPENGLES: + default: + error: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); + return (const GLubyte *) 0; + } +} + /** * Query string-valued state. The return value should _not_ be freed by @@ -74,13 +98,9 @@ _mesa_GetString( GLenum name ) if (!ctx->Extensions.String) ctx->Extensions.String = _mesa_make_extension_string(ctx); return (const GLubyte *) ctx->Extensions.String; -#if FEATURE_ARB_shading_language_100 - case GL_SHADING_LANGUAGE_VERSION_ARB: - if (ctx->Extensions.ARB_shading_language_120) - return (const GLubyte *) "1.20"; - else if (ctx->Extensions.ARB_shading_language_100) - return (const GLubyte *) "1.10"; - goto error; +#if FEATURE_ARB_shading_language_100 || FEATURE_ES2 + case GL_SHADING_LANGUAGE_VERSION: + return shading_laguage_version(ctx); #endif #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program || \ FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program @@ -92,9 +112,6 @@ _mesa_GetString( GLenum name ) return (const GLubyte *) ctx->Program.ErrorString; } /* FALL-THROUGH */ -#endif -#if FEATURE_ARB_shading_language_100 - error: #endif default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); -- cgit v1.2.3 From 18f7e118a5c6dfc04502e6e91ae492bfa33d3cc9 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 08:27:51 -0400 Subject: es2: Move over es2 code to compute extensions --- src/mesa/main/extensions.c | 109 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 106 insertions(+), 3 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 208069c1db..30a51abbe7 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -495,7 +495,6 @@ _mesa_enable_2_1_extensions(GLcontext *ctx) } - /** * Either enable or disable the named extension. * \return GL_TRUE for success, GL_FALSE if invalid extension name @@ -681,8 +680,8 @@ _mesa_init_extensions( GLcontext *ctx ) * Construct the GL_EXTENSIONS string. Called the first time that * glGetString(GL_EXTENSIONS) is called. */ -GLubyte * -_mesa_make_extension_string( GLcontext *ctx ) +static GLubyte * +compute_extensions( GLcontext *ctx ) { const char *extraExt = get_extension_override(ctx); GLuint extStrLen = 0; @@ -727,6 +726,110 @@ _mesa_make_extension_string( GLcontext *ctx ) return (GLubyte *) s; } +static size_t +append_extension(char **str, const char *ext) +{ + char *s = *str; + size_t len = strlen(ext); + + if (s) { + memcpy(s, ext, len); + s[len++] = ' '; + s[len] = '\0'; + + *str += len; + } + else { + len++; + } + + return len; +} + + +static size_t +make_extension_string_es2(const GLcontext *ctx, char *str) +{ + size_t len = 0; + + len += append_extension(&str, "GL_OES_compressed_paletted_texture"); + + if (ctx->Extensions.ARB_framebuffer_object) { + len += append_extension(&str, "GL_OES_depth24"); + len += append_extension(&str, "GL_OES_depth32"); + len += append_extension(&str, "GL_OES_fbo_render_mipmap"); + len += append_extension(&str, "GL_OES_rgb8_rgba8"); + len += append_extension(&str, "GL_OES_stencil1"); + len += append_extension(&str, "GL_OES_stencil4"); + } + + if (ctx->Extensions.EXT_vertex_array) + len += append_extension(&str, "GL_OES_element_index_uint"); + if (ctx->Extensions.ARB_vertex_buffer_object) + len += append_extension(&str, "GL_OES_mapbuffer"); + + if (ctx->Extensions.EXT_texture3D) + len += append_extension(&str, "GL_OES_texture_3D"); + if (ctx->Extensions.ARB_texture_non_power_of_two) + len += append_extension(&str, "GL_OES_texture_npot"); + if (ctx->Extensions.EXT_texture_filter_anisotropic) + len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); + + len += append_extension(&str, "GL_EXT_texture_type_2_10_10_10_REV"); + if (ctx->Extensions.ARB_depth_texture) + len += append_extension(&str, "GL_OES_depth_texture"); + if (ctx->Extensions.EXT_packed_depth_stencil) + len += append_extension(&str, "GL_OES_packed_depth_stencil"); + if (ctx->Extensions.ARB_fragment_shader) + len += append_extension(&str, "GL_OES_standard_derivatives"); + + if (ctx->Extensions.EXT_texture_compression_s3tc) + len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); + if (ctx->Extensions.EXT_blend_minmax) + len += append_extension(&str, "GL_EXT_blend_minmax"); + if (ctx->Extensions.EXT_multi_draw_arrays) + len += append_extension(&str, "GL_EXT_multi_draw_arrays"); + +#if FEATURE_OES_EGL_image + if (ctx->Extensions.OES_EGL_image) + len += append_extension(&str, "GL_OES_EGL_image"); +#endif + + return len; +} + +static GLubyte * +compute_extensions_es2(GLcontext *ctx) +{ + if (!ctx->Extensions.String) { + char *s; + unsigned int len; + + len = make_extension_string_es2(ctx, NULL); + s = (char *) malloc(len + 1); + if (!s) + return NULL; + make_extension_string_es2(ctx, s); + ctx->Extensions.String = (const GLubyte *) s; + } + + return ctx->Extensions.String; +} + +GLubyte * +_mesa_make_extension_string(GLcontext *ctx) +{ + switch (ctx->API) { + case API_OPENGL: + return compute_extensions(ctx); + case API_OPENGLES2: + return compute_extensions_es2(ctx); + case API_OPENGLES: + default: + assert(0); + return NULL; + } +} /** * Return number of enabled extensions. -- cgit v1.2.3 From ade150d66724259119012420068fa930807311c2 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 11:41:41 -0400 Subject: mesa: Compute extension string according to API We can now stop special casing glGetString() and drop specials_es*.c. --- src/mesa/es/main/APIspec.xml | 4 +- src/mesa/es/main/specials_es1.c | 168 ---------------------------------------- src/mesa/es/main/specials_es2.c | 137 -------------------------------- src/mesa/es/sources.mak | 2 - src/mesa/main/extensions.c | 126 ++++++++++++++++++++++++++---- 5 files changed, 113 insertions(+), 324 deletions(-) delete mode 100644 src/mesa/es/main/specials_es1.c delete mode 100644 src/mesa/es/main/specials_es2.c (limited to 'src/mesa') diff --git a/src/mesa/es/main/APIspec.xml b/src/mesa/es/main/APIspec.xml index 17665d8df5..7e77eb74d5 100644 --- a/src/mesa/es/main/APIspec.xml +++ b/src/mesa/es/main/APIspec.xml @@ -3955,7 +3955,7 @@ - + @@ -4178,7 +4178,7 @@ - + diff --git a/src/mesa/es/main/specials_es1.c b/src/mesa/es/main/specials_es1.c deleted file mode 100644 index 37a5943490..0000000000 --- a/src/mesa/es/main/specials_es1.c +++ /dev/null @@ -1,168 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - **************************************************************************/ - - -#include "main/mtypes.h" -#include "main/context.h" -#include "main/imports.h" -#include "main/get.h" - - -extern const GLubyte * GLAPIENTRY _es_GetString(GLenum name); - - -static size_t -append_extension(char **str, const char *ext) -{ - char *s = *str; - size_t len = strlen(ext); - - if (s) { - memcpy(s, ext, len); - s[len++] = ' '; - s[len] = '\0'; - - *str += len; - } - else { - len++; - } - - return len; -} - - -static size_t -make_extension_string(const GLcontext *ctx, char *str) -{ - size_t len = 0; - - /* Core additions */ - len += append_extension(&str, "GL_OES_byte_coordinates"); - len += append_extension(&str, "GL_OES_fixed_point"); - len += append_extension(&str, "GL_OES_single_precision"); - len += append_extension(&str, "GL_OES_matrix_get"); - - /* 1.1 required extensions */ - len += append_extension(&str, "GL_OES_read_format"); - len += append_extension(&str, "GL_OES_compressed_paletted_texture"); - len += append_extension(&str, "GL_OES_point_size_array"); - len += append_extension(&str, "GL_OES_point_sprite"); - - /* 1.1 deprecated extensions */ - len += append_extension(&str, "GL_OES_query_matrix"); - -#if FEATURE_OES_draw_texture - if (ctx->Extensions.OES_draw_texture) - len += append_extension(&str, "GL_OES_draw_texture"); -#endif - - if (ctx->Extensions.EXT_blend_equation_separate) - len += append_extension(&str, "GL_OES_blend_equation_separate"); - if (ctx->Extensions.EXT_blend_func_separate) - len += append_extension(&str, "GL_OES_blend_func_separate"); - if (ctx->Extensions.EXT_blend_subtract) - len += append_extension(&str, "GL_OES_blend_subtract"); - - if (ctx->Extensions.EXT_stencil_wrap) - len += append_extension(&str, "GL_OES_stencil_wrap"); - - if (ctx->Extensions.ARB_texture_cube_map) - len += append_extension(&str, "GL_OES_texture_cube_map"); - if (ctx->Extensions.ARB_texture_env_crossbar) - len += append_extension(&str, "GL_OES_texture_env_crossbar"); - if (ctx->Extensions.ARB_texture_mirrored_repeat) - len += append_extension(&str, "GL_OES_texture_mirrored_repeat"); - - if (ctx->Extensions.ARB_framebuffer_object) { - len += append_extension(&str, "GL_OES_framebuffer_object"); - len += append_extension(&str, "GL_OES_depth24"); - len += append_extension(&str, "GL_OES_depth32"); - len += append_extension(&str, "GL_OES_fbo_render_mipmap"); - len += append_extension(&str, "GL_OES_rgb8_rgba8"); - len += append_extension(&str, "GL_OES_stencil1"); - len += append_extension(&str, "GL_OES_stencil4"); - len += append_extension(&str, "GL_OES_stencil8"); - } - - if (ctx->Extensions.EXT_vertex_array) - len += append_extension(&str, "GL_OES_element_index_uint"); - if (ctx->Extensions.ARB_vertex_buffer_object) - len += append_extension(&str, "GL_OES_mapbuffer"); - if (ctx->Extensions.EXT_texture_filter_anisotropic) - len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); - - /* some applications check this for NPOT support */ - if (ctx->Extensions.ARB_texture_non_power_of_two) - len += append_extension(&str, "GL_ARB_texture_non_power_of_two"); - - if (ctx->Extensions.EXT_texture_compression_s3tc) - len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); - if (ctx->Extensions.EXT_texture_lod_bias) - len += append_extension(&str, "GL_EXT_texture_lod_bias"); - if (ctx->Extensions.EXT_blend_minmax) - len += append_extension(&str, "GL_EXT_blend_minmax"); - if (ctx->Extensions.EXT_multi_draw_arrays) - len += append_extension(&str, "GL_EXT_multi_draw_arrays"); - -#if FEATURE_OES_EGL_image - if (ctx->Extensions.OES_EGL_image) - len += append_extension(&str, "GL_OES_EGL_image"); -#endif - - return len; -} - - -static const GLubyte * -compute_es_extensions(void) -{ - GET_CURRENT_CONTEXT(ctx); - - if (!ctx->Extensions.String) { - char *s; - unsigned int len; - - len = make_extension_string(ctx, NULL); - s = (char *) malloc(len + 1); - if (!s) - return NULL; - make_extension_string(ctx, s); - ctx->Extensions.String = (const GLubyte *) s; - } - - return ctx->Extensions.String; -} - - -const GLubyte * GLAPIENTRY -_es_GetString(GLenum name) -{ - switch (name) { - case GL_EXTENSIONS: - return compute_es_extensions(); - default: - return _mesa_GetString(name); - } -} diff --git a/src/mesa/es/main/specials_es2.c b/src/mesa/es/main/specials_es2.c deleted file mode 100644 index ac499473a3..0000000000 --- a/src/mesa/es/main/specials_es2.c +++ /dev/null @@ -1,137 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - **************************************************************************/ - - -#include "main/mtypes.h" -#include "main/context.h" -#include "main/imports.h" -#include "main/get.h" - - -const GLubyte * GLAPIENTRY _es_GetString(GLenum name); - - -static size_t -append_extension(char **str, const char *ext) -{ - char *s = *str; - size_t len = strlen(ext); - - if (s) { - memcpy(s, ext, len); - s[len++] = ' '; - s[len] = '\0'; - - *str += len; - } - else { - len++; - } - - return len; -} - - -static size_t -make_extension_string(const GLcontext *ctx, char *str) -{ - size_t len = 0; - - len += append_extension(&str, "GL_OES_compressed_paletted_texture"); - - if (ctx->Extensions.ARB_framebuffer_object) { - len += append_extension(&str, "GL_OES_depth24"); - len += append_extension(&str, "GL_OES_depth32"); - len += append_extension(&str, "GL_OES_fbo_render_mipmap"); - len += append_extension(&str, "GL_OES_rgb8_rgba8"); - len += append_extension(&str, "GL_OES_stencil1"); - len += append_extension(&str, "GL_OES_stencil4"); - } - - if (ctx->Extensions.EXT_vertex_array) - len += append_extension(&str, "GL_OES_element_index_uint"); - if (ctx->Extensions.ARB_vertex_buffer_object) - len += append_extension(&str, "GL_OES_mapbuffer"); - - if (ctx->Extensions.EXT_texture3D) - len += append_extension(&str, "GL_OES_texture_3D"); - if (ctx->Extensions.ARB_texture_non_power_of_two) - len += append_extension(&str, "GL_OES_texture_npot"); - if (ctx->Extensions.EXT_texture_filter_anisotropic) - len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); - - len += append_extension(&str, "GL_EXT_texture_type_2_10_10_10_REV"); - if (ctx->Extensions.ARB_depth_texture) - len += append_extension(&str, "GL_OES_depth_texture"); - if (ctx->Extensions.EXT_packed_depth_stencil) - len += append_extension(&str, "GL_OES_packed_depth_stencil"); - if (ctx->Extensions.ARB_fragment_shader) - len += append_extension(&str, "GL_OES_standard_derivatives"); - - if (ctx->Extensions.EXT_texture_compression_s3tc) - len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); - if (ctx->Extensions.EXT_blend_minmax) - len += append_extension(&str, "GL_EXT_blend_minmax"); - if (ctx->Extensions.EXT_multi_draw_arrays) - len += append_extension(&str, "GL_EXT_multi_draw_arrays"); - -#if FEATURE_OES_EGL_image - if (ctx->Extensions.OES_EGL_image) - len += append_extension(&str, "GL_OES_EGL_image"); -#endif - - return len; -} - - -static const GLubyte * -compute_es_extensions(void) -{ - GET_CURRENT_CONTEXT(ctx); - - if (!ctx->Extensions.String) { - char *s; - unsigned int len; - - len = make_extension_string(ctx, NULL); - s = (char *) malloc(len + 1); - if (!s) - return NULL; - make_extension_string(ctx, s); - ctx->Extensions.String = (const GLubyte *) s; - } - - return ctx->Extensions.String; -} - -const GLubyte * GLAPIENTRY -_es_GetString(GLenum name) -{ - switch (name) { - case GL_EXTENSIONS: - return compute_es_extensions(); - default: - return _mesa_GetString(name); - } -} diff --git a/src/mesa/es/sources.mak b/src/mesa/es/sources.mak index 55bb31b80d..b08069bce5 100644 --- a/src/mesa/es/sources.mak +++ b/src/mesa/es/sources.mak @@ -5,7 +5,6 @@ include $(MESA)/sources.mak LOCAL_ES1_SOURCES := \ main/api_exec_es1.c \ main/get_es1.c \ - main/specials_es1.c \ main/drawtex.c \ main/es_cpaltex.c \ main/es_enable.c \ @@ -31,7 +30,6 @@ LOCAL_ES1_INCLUDES := \ LOCAL_ES2_SOURCES := \ main/api_exec_es2.c \ main/get_es2.c \ - main/specials_es2.c \ main/es_cpaltex.c \ main/es_fbo.c \ main/stubs.c \ diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 30a51abbe7..4c8d4ccfa2 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -727,9 +727,9 @@ compute_extensions( GLcontext *ctx ) } static size_t -append_extension(char **str, const char *ext) +append_extension(GLubyte **str, const char *ext) { - char *s = *str; + GLubyte *s = *str; size_t len = strlen(ext); if (s) { @@ -748,7 +748,104 @@ append_extension(char **str, const char *ext) static size_t -make_extension_string_es2(const GLcontext *ctx, char *str) +make_extension_string_es1(const GLcontext *ctx, GLubyte *str) +{ + size_t len = 0; + + /* Core additions */ + len += append_extension(&str, "GL_OES_byte_coordinates"); + len += append_extension(&str, "GL_OES_fixed_point"); + len += append_extension(&str, "GL_OES_single_precision"); + len += append_extension(&str, "GL_OES_matrix_get"); + + /* 1.1 required extensions */ + len += append_extension(&str, "GL_OES_read_format"); + len += append_extension(&str, "GL_OES_compressed_paletted_texture"); + len += append_extension(&str, "GL_OES_point_size_array"); + len += append_extension(&str, "GL_OES_point_sprite"); + + /* 1.1 deprecated extensions */ + len += append_extension(&str, "GL_OES_query_matrix"); + +#if FEATURE_OES_draw_texture + if (ctx->Extensions.OES_draw_texture) + len += append_extension(&str, "GL_OES_draw_texture"); +#endif + + if (ctx->Extensions.EXT_blend_equation_separate) + len += append_extension(&str, "GL_OES_blend_equation_separate"); + if (ctx->Extensions.EXT_blend_func_separate) + len += append_extension(&str, "GL_OES_blend_func_separate"); + if (ctx->Extensions.EXT_blend_subtract) + len += append_extension(&str, "GL_OES_blend_subtract"); + + if (ctx->Extensions.EXT_stencil_wrap) + len += append_extension(&str, "GL_OES_stencil_wrap"); + + if (ctx->Extensions.ARB_texture_cube_map) + len += append_extension(&str, "GL_OES_texture_cube_map"); + if (ctx->Extensions.ARB_texture_env_crossbar) + len += append_extension(&str, "GL_OES_texture_env_crossbar"); + if (ctx->Extensions.ARB_texture_mirrored_repeat) + len += append_extension(&str, "GL_OES_texture_mirrored_repeat"); + + if (ctx->Extensions.ARB_framebuffer_object) { + len += append_extension(&str, "GL_OES_framebuffer_object"); + len += append_extension(&str, "GL_OES_depth24"); + len += append_extension(&str, "GL_OES_depth32"); + len += append_extension(&str, "GL_OES_fbo_render_mipmap"); + len += append_extension(&str, "GL_OES_rgb8_rgba8"); + len += append_extension(&str, "GL_OES_stencil1"); + len += append_extension(&str, "GL_OES_stencil4"); + len += append_extension(&str, "GL_OES_stencil8"); + } + + if (ctx->Extensions.EXT_vertex_array) + len += append_extension(&str, "GL_OES_element_index_uint"); + if (ctx->Extensions.ARB_vertex_buffer_object) + len += append_extension(&str, "GL_OES_mapbuffer"); + if (ctx->Extensions.EXT_texture_filter_anisotropic) + len += append_extension(&str, "GL_EXT_texture_filter_anisotropic"); + + /* some applications check this for NPOT support */ + if (ctx->Extensions.ARB_texture_non_power_of_two) + len += append_extension(&str, "GL_ARB_texture_non_power_of_two"); + + if (ctx->Extensions.EXT_texture_compression_s3tc) + len += append_extension(&str, "GL_EXT_texture_compression_dxt1"); + if (ctx->Extensions.EXT_texture_lod_bias) + len += append_extension(&str, "GL_EXT_texture_lod_bias"); + if (ctx->Extensions.EXT_blend_minmax) + len += append_extension(&str, "GL_EXT_blend_minmax"); + if (ctx->Extensions.EXT_multi_draw_arrays) + len += append_extension(&str, "GL_EXT_multi_draw_arrays"); + +#if FEATURE_OES_EGL_image + if (ctx->Extensions.OES_EGL_image) + len += append_extension(&str, "GL_OES_EGL_image"); +#endif + + return len; +} + + +static GLubyte * +compute_extensions_es1(const GLcontext *ctx) +{ + GLubyte *s; + unsigned int len; + + len = make_extension_string_es1(ctx, NULL); + s = malloc(len + 1); + if (!s) + return NULL; + make_extension_string_es1(ctx, s); + + return s; +} + +static size_t +make_extension_string_es2(const GLcontext *ctx, GLubyte *str) { size_t len = 0; @@ -801,21 +898,19 @@ make_extension_string_es2(const GLcontext *ctx, char *str) static GLubyte * compute_extensions_es2(GLcontext *ctx) { - if (!ctx->Extensions.String) { - char *s; - unsigned int len; - - len = make_extension_string_es2(ctx, NULL); - s = (char *) malloc(len + 1); - if (!s) - return NULL; - make_extension_string_es2(ctx, s); - ctx->Extensions.String = (const GLubyte *) s; - } + GLubyte *s; + unsigned int len; - return ctx->Extensions.String; + len = make_extension_string_es2(ctx, NULL); + s = malloc(len + 1); + if (!s) + return NULL; + make_extension_string_es2(ctx, s); + + return s; } + GLubyte * _mesa_make_extension_string(GLcontext *ctx) { @@ -825,6 +920,7 @@ _mesa_make_extension_string(GLcontext *ctx) case API_OPENGLES2: return compute_extensions_es2(ctx); case API_OPENGLES: + return compute_extensions_es1(ctx); default: assert(0); return NULL; -- cgit v1.2.3 From fa416106307dc193e2133aa6a29b9bcfc91f8b39 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 12:40:47 -0400 Subject: mesa: Move struct _glapi_table allocation out of context.c We now allocate the table from api_exec.c and dlist.c where we fill out the table. This way, context.c doesn't need to know the actual contents of struct _glapi_table. --- src/mesa/es/main/es_generator.py | 12 ++++++++++-- src/mesa/main/api_exec.c | 12 ++++++++++-- src/mesa/main/api_exec.h | 6 ++++-- src/mesa/main/context.c | 26 +++++++++++++------------- src/mesa/main/dlist.c | 12 ++++++++++-- src/mesa/main/dlist.h | 2 +- 6 files changed, 48 insertions(+), 22 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/es/main/es_generator.py b/src/mesa/es/main/es_generator.py index f736792dec..dbb516a4c1 100644 --- a/src/mesa/es/main/es_generator.py +++ b/src/mesa/es/main/es_generator.py @@ -667,9 +667,15 @@ for funcName in keys: # end for each function -print "void" -print "_mesa_init_exec_table(struct _glapi_table *exec)" +print "struct _glapi_table *" +print "_mesa_create_exec_table(void)" print "{" +print " struct _glapi_table *exec;" +print " exec = _mesa_alloc_dispatch_table(sizeof *exec);" +print " if (exec == NULL)" +print " return NULL;" +print "" + for func in keys: prefix = "_es_" if func not in allSpecials else "_check_" for spec in apiutil.Categories(func): @@ -682,4 +688,6 @@ for func in keys: suffix = ext[0].split("_")[0] entry += suffix print " SET_%s(exec, %s%s);" % (entry, prefix, entry) +print "" +print " return exec;" print "}" diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index 1e1aa41611..7b3f3d9ea1 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c @@ -119,9 +119,15 @@ * \param ctx GL context to which \c exec belongs. * \param exec dispatch table. */ -void -_mesa_init_exec_table(struct _glapi_table *exec) +struct _glapi_table * +_mesa_create_exec_table(void) { + struct _glapi_table *exec; + + exec = _mesa_alloc_dispatch_table(sizeof *exec); + if (exec == NULL) + return NULL; + #if _HAVE_FULL_GL _mesa_loopback_init_api_table( exec ); #endif @@ -777,4 +783,6 @@ _mesa_init_exec_table(struct _glapi_table *exec) SET_ObjectUnpurgeableAPPLE(exec, _mesa_ObjectUnpurgeableAPPLE); SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE); #endif + + return exec; } diff --git a/src/mesa/main/api_exec.h b/src/mesa/main/api_exec.h index 4bd715053a..dd8d500865 100644 --- a/src/mesa/main/api_exec.h +++ b/src/mesa/main/api_exec.h @@ -29,9 +29,11 @@ struct _glapi_table; +extern struct _glapi_table * +_mesa_alloc_dispatch_table(int size); -extern void -_mesa_init_exec_table(struct _glapi_table *exec); +extern struct _glapi_table * +_mesa_create_exec_table(void); #endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 25288a4e9c..8d71cefdcf 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -129,8 +129,6 @@ #include "version.h" #include "viewport.h" #include "vtxfmt.h" -#include "glapi/glthread.h" -#include "glapi/glapitable.h" #include "shader/program.h" #include "shader/prog_print.h" #include "shader/shader_api.h" @@ -749,8 +747,8 @@ generic_nop(void) /** * Allocate and initialize a new dispatch table. */ -static struct _glapi_table * -alloc_dispatch_table(void) +struct _glapi_table * +_mesa_alloc_dispatch_table(int size) { /* Find the larger of Mesa's dispatch table and libGL's dispatch table. * In practice, this'll be the same for stand-alone Mesa. But for DRI @@ -758,7 +756,7 @@ alloc_dispatch_table(void) * DRI drivers. */ GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), - sizeof(struct _glapi_table) / sizeof(_glapi_proc)); + size / sizeof(_glapi_proc)); struct _glapi_table *table = (struct _glapi_table *) malloc(numEntries * sizeof(_glapi_proc)); if (table) { @@ -853,22 +851,24 @@ _mesa_initialize_context_for_api(GLcontext *ctx, return GL_FALSE; } +#if FEATURE_dispatch /* setup the API dispatch tables */ - ctx->Exec = alloc_dispatch_table(); - ctx->Save = alloc_dispatch_table(); - if (!ctx->Exec || !ctx->Save) { + ctx->Exec = _mesa_create_exec_table(); + if (!ctx->Exec) { _mesa_release_shared_state(ctx, ctx->Shared); - if (ctx->Exec) - free(ctx->Exec); return GL_FALSE; } -#if FEATURE_dispatch - _mesa_init_exec_table(ctx->Exec); #endif ctx->CurrentDispatch = ctx->Exec; #if FEATURE_dlist - _mesa_init_save_table(ctx->Save); + ctx->Save = _mesa_create_save_table(); + if (!ctx->Save) { + _mesa_release_shared_state(ctx, ctx->Shared); + free(ctx->Exec); + return GL_FALSE; + } + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); #endif diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index f869a585d6..168c424ea1 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -8747,9 +8747,15 @@ exec_MultiModeDrawElementsIBM(const GLenum * mode, * initialized from _mesa_init_api_defaults and from the active vtxfmt * struct. */ -void -_mesa_init_save_table(struct _glapi_table *table) +struct _glapi_table * +_mesa_create_save_table(void) { + struct _glapi_table *table; + + table = _mesa_alloc_dispatch_table(sizeof *table); + if (table == NULL) + return NULL; + _mesa_loopback_init_api_table(table); /* GL 1.0 */ @@ -9349,6 +9355,8 @@ _mesa_init_save_table(struct _glapi_table *table) (void) save_ClearBufferfv; (void) save_ClearBufferfi; #endif + + return table; } diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h index f37a93a7f4..f8255facc5 100644 --- a/src/mesa/main/dlist.h +++ b/src/mesa/main/dlist.h @@ -72,7 +72,7 @@ extern void _mesa_delete_list(GLcontext *ctx, struct gl_display_list *dlist); extern void _mesa_save_vtxfmt_init( GLvertexformat *vfmt ); -extern void _mesa_init_save_table( struct _glapi_table *table ); +extern struct _glapi_table *_mesa_create_save_table(void); extern void _mesa_install_dlist_vtxfmt(struct _glapi_table *disp, const GLvertexformat *vfmt); -- cgit v1.2.3 From 1741ddb747ca0be284315adb4b6fe67ddf292d03 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 13:30:03 -0400 Subject: mesa: Move references to main/remap_helper.h to api_exec.c --- src/mesa/es/main/es_generator.py | 26 +++++++++++++++++++++ src/mesa/glapi/gen/remap_helper.py | 12 ++-------- src/mesa/main/api_exec.c | 34 +++++++++++++++++++++++++++ src/mesa/main/remap.c | 48 ++++++++------------------------------ src/mesa/main/remap.h | 32 ++++++++++++++++++++----- src/mesa/main/remap_helper.h | 11 ++------- 6 files changed, 100 insertions(+), 63 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/es/main/es_generator.py b/src/mesa/es/main/es_generator.py index dbb516a4c1..8dedafbceb 100644 --- a/src/mesa/es/main/es_generator.py +++ b/src/mesa/es/main/es_generator.py @@ -209,6 +209,32 @@ extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... ); #include "main/dispatch.h" +#if FEATURE_remap_table + +#include "main/remap.h" + +#ifdef IN_DRI_DRIVER +#define _GLAPI_USE_REMAP_TABLE +#endif + +#define need_MESA_remap_table +#include "main/remap_helper.h" + +void +_mesa_init_remap_table(void) +{ + _mesa_do_init_remap_table(_mesa_function_pool, + driDispatchRemapTable_size, + MESA_remap_table_functions); +} + +void +_mesa_map_static_functions(void) +{ +} + +#endif + typedef void (*_glapi_proc)(void); /* generic function pointer */ """ diff --git a/src/mesa/glapi/gen/remap_helper.py b/src/mesa/glapi/gen/remap_helper.py index 8b50526d2b..69b8e5e9d0 100644 --- a/src/mesa/glapi/gen/remap_helper.py +++ b/src/mesa/glapi/gen/remap_helper.py @@ -65,17 +65,12 @@ class PrintGlRemap(gl_XML.gl_print_base): def printRealHeader(self): print '#include "main/dispatch.h"' + print '#include "main/remap.h"' print '' return def printBody(self, api): - print 'struct gl_function_remap {' - print ' GLint func_index;' - print ' GLint dispatch_offset; /* for sanity check */' - print '};' - print '' - pool_indices = {} print '/* this is internal to remap.c */' @@ -108,10 +103,7 @@ class PrintGlRemap(gl_XML.gl_print_base): print '' print '/* these functions need to be remapped */' - print 'static const struct {' - print ' GLint pool_index;' - print ' GLint remap_index;' - print '} MESA_remap_table_functions[] = {' + print 'static const struct gl_function_pool_remap MESA_remap_table_functions[] = {' # output all functions that need to be remapped # iterate by offsets so that they are sorted by remap indices for f in api.functionIterateByOffset(): diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c index 7b3f3d9ea1..7b6ac63fac 100644 --- a/src/mesa/main/api_exec.c +++ b/src/mesa/main/api_exec.c @@ -107,6 +107,40 @@ #endif #include "main/dispatch.h" +#define need_MESA_remap_table +#include "main/remap.h" +#include "main/remap_helper.h" + +/* This is shared across all APIs but We define this here since + * desktop GL has the biggest remap table. */ +int driDispatchRemapTable[driDispatchRemapTable_size]; + +/** + * Map the functions which are already static. + * + * When a extension function are incorporated into the ABI, the + * extension suffix is usually stripped. Mapping such functions + * makes sure the alternative names are available. + * + * Note that functions mapped by _mesa_init_remap_table() are + * excluded. + */ +void +_mesa_map_static_functions(void) +{ + /* Remap static functions which have alternative names and are in the ABI. + * This is to be on the safe side. glapi should have defined those names. + */ + _mesa_map_function_array(MESA_alt_functions); +} + +void +_mesa_init_remap_table(void) +{ + _mesa_do_init_remap_table(_mesa_function_pool, + driDispatchRemapTable_size, + MESA_remap_table_functions); +} /** diff --git a/src/mesa/main/remap.c b/src/mesa/main/remap.c index bfceb43c97..38ddc0c1dd 100644 --- a/src/mesa/main/remap.c +++ b/src/mesa/main/remap.c @@ -38,23 +38,15 @@ #include "remap.h" #include "imports.h" - -#include "main/dispatch.h" - +#include "glapi/glapi.h" #if FEATURE_remap_table -#define need_MESA_remap_table -#include "main/remap_helper.h" - #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #define MAX_ENTRY_POINTS 16 - -/* this is global for quick access */ -int driDispatchRemapTable[driDispatchRemapTable_size]; - +static const char *_mesa_function_pool; /** * Return the spec string associated with the given function index. @@ -67,10 +59,7 @@ int driDispatchRemapTable[driDispatchRemapTable_size]; const char * _mesa_get_function_spec(GLint func_index) { - if (func_index < ARRAY_SIZE(_mesa_function_pool)) - return _mesa_function_pool + func_index; - else - return NULL; + return _mesa_function_pool + func_index; } @@ -161,33 +150,15 @@ _mesa_map_function_array(const struct gl_function_remap *func_array) } -/** - * Map the functions which are already static. - * - * When a extension function are incorporated into the ABI, the - * extension suffix is usually stripped. Mapping such functions - * makes sure the alternative names are available. - * - * Note that functions mapped by _mesa_init_remap_table() are - * excluded. - */ -void -_mesa_map_static_functions(void) -{ - /* Remap static functions which have alternative names and are in the ABI. - * This is to be on the safe side. glapi should have defined those names. - */ - _mesa_map_function_array(MESA_alt_functions); -} - - /** * Initialize the remap table. This is called in one_time_init(). * The remap table needs to be initialized before calling the * CALL/GET/SET macros defined in main/dispatch.h. */ void -_mesa_init_remap_table(void) +_mesa_do_init_remap_table(const char *pool, + int size, + const struct gl_function_pool_remap *remap) { static GLboolean initialized = GL_FALSE; GLint i; @@ -195,15 +166,16 @@ _mesa_init_remap_table(void) if (initialized) return; initialized = GL_TRUE; + _mesa_function_pool = pool; /* initialize the remap table */ - for (i = 0; i < ARRAY_SIZE(driDispatchRemapTable); i++) { + for (i = 0; i < size; i++) { GLint offset; const char *spec; /* sanity check */ - ASSERT(i == MESA_remap_table_functions[i].remap_index); - spec = _mesa_function_pool + MESA_remap_table_functions[i].pool_index; + ASSERT(i == remap[i].remap_index); + spec = _mesa_function_pool + remap[i].pool_index; offset = _mesa_map_function_spec(spec); /* store the dispatch offset in the remap table */ diff --git a/src/mesa/main/remap.h b/src/mesa/main/remap.h index d080188d89..dda1a6be3a 100644 --- a/src/mesa/main/remap.h +++ b/src/mesa/main/remap.h @@ -28,9 +28,17 @@ #define REMAP_H -#include "main/mtypes.h" +#include "main/mfeatures.h" -struct gl_function_remap; +struct gl_function_pool_remap { + int pool_index; + int remap_index; +}; + +struct gl_function_remap { + int func_index; + int dispatch_offset; /* for sanity check */ +}; #if FEATURE_remap_table @@ -39,9 +47,9 @@ extern int driDispatchRemapTable[]; extern const char * -_mesa_get_function_spec(GLint func_index); +_mesa_get_function_spec(int func_index); -extern GLint +extern int _mesa_map_function_spec(const char *spec); extern void @@ -50,18 +58,23 @@ _mesa_map_function_array(const struct gl_function_remap *func_array); extern void _mesa_map_static_functions(void); +extern void +_mesa_do_init_remap_table(const char *pool, + int size, + const struct gl_function_pool_remap *remap); + extern void _mesa_init_remap_table(void); #else /* FEATURE_remap_table */ static INLINE const char * -_mesa_get_function_spec(GLint func_index) +_mesa_get_function_spec(int func_index) { return NULL; } -static INLINE GLint +static INLINE int _mesa_map_function_spec(const char *spec) { return -1; @@ -77,6 +90,13 @@ _mesa_map_static_functions(void) { } +static INLINE void +_mesa_do_init_remap_table(const char *pool, + int size, + const struct gl_function_pool_remap *remap) +{ +} + static INLINE void _mesa_init_remap_table(void) { diff --git a/src/mesa/main/remap_helper.h b/src/mesa/main/remap_helper.h index 52edf67b54..2df11a454d 100644 --- a/src/mesa/main/remap_helper.h +++ b/src/mesa/main/remap_helper.h @@ -26,11 +26,7 @@ */ #include "main/dispatch.h" - -struct gl_function_remap { - GLint func_index; - GLint dispatch_offset; /* for sanity check */ -}; +#include "main/remap.h" /* this is internal to remap.c */ #ifdef need_MESA_remap_table @@ -4427,10 +4423,7 @@ static const char _mesa_function_pool[] = ; /* these functions need to be remapped */ -static const struct { - GLint pool_index; - GLint remap_index; -} MESA_remap_table_functions[] = { +static const struct gl_function_pool_remap MESA_remap_table_functions[] = { { 1461, AttachShader_remap_index }, { 8848, CreateProgram_remap_index }, { 20883, CreateShader_remap_index }, -- cgit v1.2.3 From ea0c7e71638a4a72a4eae962e6cc471bd33a5605 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Thu, 22 Apr 2010 20:26:51 -0400 Subject: mesa: Move api_exec_es*.c into mesa/main This requires renaming a few functions to have unique names so that they can all live within the same driver. --- src/mesa/Makefile | 6 + src/mesa/es/Makefile | 8 - src/mesa/es/main/APIspec.dtd | 52 - src/mesa/es/main/APIspec.py | 617 ------ src/mesa/es/main/APIspec.xml | 4336 -------------------------------------- src/mesa/es/main/APIspecutil.py | 265 --- src/mesa/es/main/es_generator.py | 719 ------- src/mesa/es/sources.mak | 2 - src/mesa/main/APIspec.dtd | 52 + src/mesa/main/APIspec.py | 617 ++++++ src/mesa/main/APIspec.xml | 4336 ++++++++++++++++++++++++++++++++++++++ src/mesa/main/APIspecutil.py | 265 +++ src/mesa/main/api_exec.h | 6 + src/mesa/main/context.c | 48 +- src/mesa/main/es_generator.py | 726 +++++++ src/mesa/main/remap.h | 33 + src/mesa/sources.mak | 2 + 17 files changed, 6086 insertions(+), 6004 deletions(-) delete mode 100644 src/mesa/es/main/APIspec.dtd delete mode 100644 src/mesa/es/main/APIspec.py delete mode 100644 src/mesa/es/main/APIspec.xml delete mode 100644 src/mesa/es/main/APIspecutil.py delete mode 100644 src/mesa/es/main/es_generator.py create mode 100644 src/mesa/main/APIspec.dtd create mode 100644 src/mesa/main/APIspec.py create mode 100644 src/mesa/main/APIspec.xml create mode 100644 src/mesa/main/APIspecutil.py create mode 100644 src/mesa/main/es_generator.py (limited to 'src/mesa') diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 8c0ebf84c4..7dcde5275e 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -24,6 +24,12 @@ default: depend asm_subdirs glsl_builtin libmesa.a libmesagallium.a \ libglapi.a driver_subdirs +main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@ + +main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py + $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@ + ###################################################################### # Helper libraries used by many drivers: diff --git a/src/mesa/es/Makefile b/src/mesa/es/Makefile index 8b484853af..b095620c9d 100644 --- a/src/mesa/es/Makefile +++ b/src/mesa/es/Makefile @@ -83,17 +83,9 @@ libes2api.a: $(ES2_API_OBJECTS) @$(MKLIB) -o es2api -static $(ES2_API_OBJECTS) GENERATED_SOURCES := \ - main/api_exec_es1.c \ - main/api_exec_es2.c \ main/get_es1.c \ main/get_es2.c -main/api_exec_es1.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py - $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES1.1 > $@ - -main/api_exec_es2.c: main/APIspec.xml main/es_generator.py main/APIspecutil.py main/APIspec.py - $(PYTHON2) $(PYTHON_FLAGS) main/es_generator.py -S main/APIspec.xml -V GLES2.0 > $@ - main/get_es1.c: main/get_gen.py $(PYTHON2) $(PYTHON_FLAGS) $< 1 > $@ diff --git a/src/mesa/es/main/APIspec.dtd b/src/mesa/es/main/APIspec.dtd deleted file mode 100644 index efcfa31f10..0000000000 --- a/src/mesa/es/main/APIspec.dtd +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mesa/es/main/APIspec.py b/src/mesa/es/main/APIspec.py deleted file mode 100644 index 6947f7301c..0000000000 --- a/src/mesa/es/main/APIspec.py +++ /dev/null @@ -1,617 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2009 Chia-I Wu -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# on the rights to use, copy, modify, merge, publish, distribute, sub -# license, and/or sell copies of the Software, and to permit persons to whom -# the Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. -""" -A parser for APIspec. -""" - -class SpecError(Exception): - """Error in the spec file.""" - - -class Spec(object): - """A Spec is an abstraction of the API spec.""" - - def __init__(self, doc): - self.doc = doc - - self.spec_node = doc.getRootElement() - self.tmpl_nodes = {} - self.api_nodes = {} - self.impl_node = None - - # parse - node = self.spec_node.children - while node: - if node.type == "element": - if node.name == "template": - self.tmpl_nodes[node.prop("name")] = node - elif node.name == "api": - self.api_nodes[node.prop("name")] = node - else: - raise SpecError("unexpected node %s in apispec" % - node.name) - node = node.next - - # find an implementation - for name, node in self.api_nodes.iteritems(): - if node.prop("implementation") == "true": - self.impl_node = node - break - if not self.impl_node: - raise SpecError("unable to find an implementation") - - def get_impl(self): - """Return the implementation.""" - return API(self, self.impl_node) - - def get_api(self, name): - """Return an API.""" - return API(self, self.api_nodes[name]) - - -class API(object): - """An API consists of categories and functions.""" - - def __init__(self, spec, api_node): - self.name = api_node.prop("name") - self.is_impl = (api_node.prop("implementation") == "true") - - self.categories = [] - self.functions = [] - - # parse - func_nodes = [] - node = api_node.children - while node: - if node.type == "element": - if node.name == "category": - cat = node.prop("name") - self.categories.append(cat) - elif node.name == "function": - func_nodes.append(node) - else: - raise SpecError("unexpected node %s in api" % node.name) - node = node.next - - # realize functions - for func_node in func_nodes: - tmpl_node = spec.tmpl_nodes[func_node.prop("template")] - try: - func = Function(tmpl_node, func_node, self.is_impl, - self.categories) - except SpecError, e: - func_name = func_node.prop("name") - raise SpecError("failed to parse %s: %s" % (func_name, e)) - self.functions.append(func) - - def match(self, func, conversions={}): - """Find a matching function in the API.""" - match = None - need_conv = False - for f in self.functions: - matched, conv = f.match(func, conversions) - if matched: - match = f - need_conv = conv - # exact match - if not need_conv: - break - return (match, need_conv) - - -class Function(object): - """Parse and realize a