[Mesa-dev] [Patch v2] Mesa: Add support for GL_OES_texture_*float* extensions.
Ian Romanick
idr at freedesktop.org
Tue Dec 2 11:10:50 PST 2014
On 11/27/2014 10:56 AM, Kalyan Kondapally wrote:
> This patch adds support for following GLES2 Texture Float extensions:
> 1)GL_OES_texture_float,
> 2)GL_OES_texture_half_float,
> 3)GL_OES_texture_float_linear,
> 4)GL_OES_texture_half_float_linear.
>
> Support for these extensions need to be explicitly enabled per driver
> and this patch enables support for i965 drivers.
>
> v2: Indentation fixes. (Brian Paul)
> Fixed Comments and added some to new private functions.(Brian Paul)
> Added assert in valid_filter_for_float.(Brian Paul)
> Renamed Float and HALF_FLOAT_OES as IsFloatOES and IsHalfFloatOES.(Brian Paul)
> adjust_for_oes_float_texture to return GLenum. (Brain Paul)
> Use RGB_32F internal floating point format for RGB base format.
>
> Signed-off-by: Kevin Rogovin <kevin.rogovin at intel.com>
> Signed-off-by: Kalyan Kondapally <kalyan.kondapally at intel.com>
> ---
> src/mesa/drivers/dri/i965/intel_extensions.c | 6 +++
> src/mesa/main/extensions.c | 4 ++
> src/mesa/main/glformats.c | 46 +++++++++++++++++--
> src/mesa/main/glformats.h | 3 +-
> src/mesa/main/mtypes.h | 6 +++
> src/mesa/main/pack.c | 16 +++++++
> src/mesa/main/teximage.c | 68 +++++++++++++++++++++++++++-
> src/mesa/main/texobj.c | 53 ++++++++++++++++++++++
> 8 files changed, 196 insertions(+), 6 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
> index bbbb76f..e95eaef 100644
> --- a/src/mesa/drivers/dri/i965/intel_extensions.c
> +++ b/src/mesa/drivers/dri/i965/intel_extensions.c
> @@ -245,6 +245,12 @@ intelInitExtensions(struct gl_context *ctx)
> ctx->Extensions.OES_standard_derivatives = true;
> ctx->Extensions.OES_EGL_image_external = true;
>
> + bool enable_opengles2_extensions = ctx->API == API_OPENGLES2;
> + ctx->Extensions.OES_texture_float = enable_opengles2_extensions;
> + ctx->Extensions.OES_texture_half_float = enable_opengles2_extensions;
> + ctx->Extensions.OES_texture_float_linear = enable_opengles2_extensions;
> + ctx->Extensions.OES_texture_half_float_linear = enable_opengles2_extensions;
> +
The code that decides which extension strings to expose to the
application already does per-API filtering. Unless there is code
elsewhere in Mesa that behaves differently when these extensions are
enabled, there is no reason to do this. Notice that we enable all the
desktop OpenGL extensions even in an OpenGL ES 1.1 context.
I see that v3 moves this to handle_first_current. I'll add further
comments on the updated patch.
> if (brw->gen >= 6)
> ctx->Const.GLSLVersion = 330;
> else
> diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
> index 0df04c2..6833fcf 100644
> --- a/src/mesa/main/extensions.c
> +++ b/src/mesa/main/extensions.c
> @@ -314,6 +314,10 @@ static const struct extension extension_table[] = {
> { "GL_OES_texture_3D", o(EXT_texture3D), ES2, 2005 },
> { "GL_OES_texture_cube_map", o(ARB_texture_cube_map), ES1, 2007 },
> { "GL_OES_texture_env_crossbar", o(ARB_texture_env_crossbar), ES1, 2005 },
> + { "GL_OES_texture_float", o(OES_texture_float), ES2, 2005 },
> + { "GL_OES_texture_float_linear", o(OES_texture_float_linear), ES2, 2005 },
> + { "GL_OES_texture_half_float", o(OES_texture_half_float), ES2, 2005 },
> + { "GL_OES_texture_half_float_linear", o(OES_texture_half_float_linear), ES2, 2005 },
> { "GL_OES_texture_mirrored_repeat", o(dummy_true), ES1, 2005 },
> { "GL_OES_texture_npot", o(ARB_texture_non_power_of_two), ES1 | ES2, 2005 },
> { "GL_OES_vertex_array_object", o(dummy_true), ES1 | ES2, 2010 },
> diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c
> index 00478f9..c2e6c37 100644
> --- a/src/mesa/main/glformats.c
> +++ b/src/mesa/main/glformats.c
> @@ -93,6 +93,7 @@ _mesa_sizeof_type(GLenum type)
> case GL_DOUBLE:
> return sizeof(GLdouble);
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> return sizeof(GLhalfARB);
> case GL_FIXED:
> return sizeof(GLfixed);
> @@ -125,6 +126,7 @@ _mesa_sizeof_packed_type(GLenum type)
> case GL_INT:
> return sizeof(GLint);
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> return sizeof(GLhalfARB);
> case GL_FLOAT:
> return sizeof(GLfloat);
> @@ -241,6 +243,7 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type)
> case GL_FLOAT:
> return comps * sizeof(GLfloat);
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> return comps * sizeof(GLhalfARB);
> case GL_UNSIGNED_BYTE_3_3_2:
> case GL_UNSIGNED_BYTE_2_3_3_REV:
> @@ -1448,6 +1451,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
> }
> return GL_NO_ERROR;
>
> + case GL_HALF_FLOAT_OES:
> + switch (format) {
> + case GL_RGBA:
> + case GL_RGB:
> + case GL_LUMINANCE_ALPHA:
> + case GL_LUMINANCE:
> + case GL_ALPHA:
> + return GL_NO_ERROR;
> + default:
> + return GL_INVALID_OPERATION;
> + }
> +
> default:
> ; /* fall-through */
> }
> @@ -1782,7 +1797,8 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type,
> * \return error code, or GL_NO_ERROR.
> */
> GLenum
> -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
> +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
> + GLenum format, GLenum type,
> GLenum internalFormat)
> {
> switch (format) {
> @@ -1847,11 +1863,17 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
> case GL_RGBA16F:
> case GL_RGBA32F:
> break;
> + case GL_RGBA:
> + if (ctx->Extensions.OES_texture_float && internalFormat == format)
> + break;
> default:
> return GL_INVALID_OPERATION;
> }
> break;
>
> + case GL_HALF_FLOAT_OES:
> + if (ctx->Extensions.OES_texture_half_float && internalFormat == format)
> + break;
> default:
> return GL_INVALID_OPERATION;
> }
> @@ -1956,11 +1978,19 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
> case GL_R11F_G11F_B10F:
> case GL_RGB9_E5:
> break;
> + case GL_RGB:
> + if (ctx->Extensions.OES_texture_float && internalFormat == format)
> + break;
> default:
> return GL_INVALID_OPERATION;
> }
> break;
>
> + case GL_HALF_FLOAT_OES:
> + if (!ctx->Extensions.OES_texture_half_float || internalFormat != format)
> + return GL_INVALID_OPERATION;
> + break;
> +
> case GL_UNSIGNED_INT_2_10_10_10_REV:
> switch (internalFormat) {
> case GL_RGB: /* GL_EXT_texture_type_2_10_10_10_REV */
> @@ -2200,9 +2230,17 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
> case GL_ALPHA:
> case GL_LUMINANCE:
> case GL_LUMINANCE_ALPHA:
> - if (type != GL_UNSIGNED_BYTE || format != internalFormat)
> - return GL_INVALID_OPERATION;
> - break;
> + switch (type) {
> + case GL_FLOAT:
> + if (ctx->Extensions.OES_texture_float && internalFormat == format)
> + break;
> + case GL_HALF_FLOAT_OES:
> + if (ctx->Extensions.OES_texture_half_float && internalFormat == format)
> + break;
> + default:
> + if (type != GL_UNSIGNED_BYTE || format != internalFormat)
> + return GL_INVALID_OPERATION;
> + }
> }
>
> return GL_NO_ERROR;
> diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h
> index 7b03215..9b1674e 100644
> --- a/src/mesa/main/glformats.h
> +++ b/src/mesa/main/glformats.h
> @@ -122,7 +122,8 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type,
> unsigned dimensions);
>
> extern GLenum
> -_mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
> +_mesa_es3_error_check_format_and_type(const struct gl_context *ctx,
> + GLenum format, GLenum type,
> GLenum internalFormat);
>
>
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index 7389baa..4e44b6e 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -1220,6 +1220,8 @@ struct gl_texture_object
> GLboolean Purgeable; /**< Is the buffer purgeable under memory
> pressure? */
> GLboolean Immutable; /**< GL_ARB_texture_storage */
> + GLboolean IsFloatOES; /**< GL_OES_float_texture */
> + GLboolean IsHalfFloatOES; /**< GL_OES_half_float_texture */
>
> GLuint MinLevel; /**< GL_ARB_texture_view */
> GLuint MinLayer; /**< GL_ARB_texture_view */
> @@ -3842,6 +3844,10 @@ struct gl_extensions
> GLboolean OES_draw_texture;
> GLboolean OES_depth_texture_cube_map;
> GLboolean OES_EGL_image_external;
> + GLboolean OES_texture_float;
> + GLboolean OES_texture_half_float;
> + GLboolean OES_texture_float_linear;
> + GLboolean OES_texture_half_float_linear;
> GLboolean OES_compressed_ETC1_RGB8_texture;
> GLboolean extension_sentinel;
> /** The extension string */
> diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
> index 649a74c..daafb1e 100644
> --- a/src/mesa/main/pack.c
> +++ b/src/mesa/main/pack.c
> @@ -2301,6 +2301,7 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4],
> }
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLhalfARB *dst = (GLhalfARB *) dstAddr;
> switch (dstFormat) {
> @@ -2724,6 +2725,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
> srcType == GL_INT ||
> srcType == GL_UNSIGNED_INT_24_8_EXT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
>
> @@ -2863,6 +2865,7 @@ extract_uint_indexes(GLuint n, GLuint indexes[],
> }
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLuint i;
> const GLhalfARB *s = (const GLhalfARB *) src;
> @@ -3102,6 +3105,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_UNSIGNED_BYTE_3_3_2 ||
> srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
> @@ -3219,6 +3223,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
> PROCESS(aSrc, ACOMP, 1.0F, 1.0F, GLfloat, (GLfloat));
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> PROCESS(rSrc, RCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
> PROCESS(gSrc, GCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
> PROCESS(bSrc, BCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
> @@ -3717,6 +3722,7 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4],
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_UNSIGNED_BYTE_3_3_2 ||
> srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
> @@ -3814,6 +3820,7 @@ extract_uint_rgba(GLuint n, GLuint rgba[][4],
> PROCESS(aSrc, ACOMP, 1, GLfloat, clamp_float_to_uint);
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> PROCESS(rSrc, RCOMP, 0, GLhalfARB, clamp_half_to_uint);
> PROCESS(gSrc, GCOMP, 0, GLhalfARB, clamp_half_to_uint);
> PROCESS(bSrc, BCOMP, 0, GLhalfARB, clamp_half_to_uint);
> @@ -4218,6 +4225,7 @@ _mesa_unpack_color_span_ubyte(struct gl_context *ctx,
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_UNSIGNED_BYTE_3_3_2 ||
> srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
> @@ -4471,6 +4479,7 @@ _mesa_unpack_color_span_float( struct gl_context *ctx,
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_UNSIGNED_BYTE_3_3_2 ||
> srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
> @@ -4675,6 +4684,7 @@ _mesa_unpack_color_span_uint(struct gl_context *ctx,
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_UNSIGNED_BYTE_3_3_2 ||
> srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
> @@ -4803,6 +4813,7 @@ _mesa_unpack_index_span( struct gl_context *ctx, GLuint n,
> srcType == GL_UNSIGNED_INT ||
> srcType == GL_INT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT);
>
> ASSERT(dstType == GL_UNSIGNED_BYTE ||
> @@ -4974,6 +4985,7 @@ _mesa_pack_index_span( struct gl_context *ctx, GLuint n,
> }
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLhalfARB *dst = (GLhalfARB *) dest;
> GLuint i;
> @@ -5023,6 +5035,7 @@ _mesa_unpack_stencil_span( struct gl_context *ctx, GLuint n,
> srcType == GL_INT ||
> srcType == GL_UNSIGNED_INT_24_8_EXT ||
> srcType == GL_HALF_FLOAT_ARB ||
> + srcType == GL_HALF_FLOAT_OES ||
> srcType == GL_FLOAT ||
> srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
>
> @@ -5213,6 +5226,7 @@ _mesa_pack_stencil_span( struct gl_context *ctx, GLuint n,
> }
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLhalfARB *dst = (GLhalfARB *) dest;
> GLuint i;
> @@ -5430,6 +5444,7 @@ _mesa_unpack_depth_span( struct gl_context *ctx, GLuint n,
> needClamp = GL_TRUE;
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLuint i;
> const GLhalfARB *src = (const GLhalfARB *) source;
> @@ -5619,6 +5634,7 @@ _mesa_pack_depth_span( struct gl_context *ctx, GLuint n, GLvoid *dest,
> }
> break;
> case GL_HALF_FLOAT_ARB:
> + case GL_HALF_FLOAT_OES:
> {
> GLhalfARB *dst = (GLhalfARB *) dest;
> GLuint i;
> diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
> index 4f4bb11..b24c593 100644
> --- a/src/mesa/main/teximage.c
> +++ b/src/mesa/main/teximage.c
> @@ -62,7 +62,60 @@
> */
> #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL)
>
> +/**
> + * Returns a corresponding internal floating point format for a given base
> + * format as specifed by OES_texture_float. In case of Float, the internal
> + * format needs to be a 32 bit component and in case of HALF_FLOAT it needs to
> + * be a 16 bit component.
> + *
> + * For example, given base format GL_ALPHA, type Float return GL_ALPHA32F_ARB.
> + */
> +static GLenum
> +adjust_for_oes_float_texture(GLenum format, GLenum type)
> +{
> + switch (type) {
> + case GL_FLOAT: {
> + switch (format) {
> + case GL_RGBA:
> + return GL_RGBA32F_ARB;
> + case GL_RGB:
> + return GL_RGB32F_ARB;
> + case GL_ALPHA:
> + return GL_ALPHA32F_ARB;
> + case GL_LUMINANCE:
> + return GL_LUMINANCE32F_ARB;
> + case GL_LUMINANCE_ALPHA:
> + return GL_LUMINANCE_ALPHA32F_ARB;
> + default:
> + break;
> + }
> + break;
> + }
>
> + case GL_HALF_FLOAT_OES: {
> + switch (format) {
> + case GL_RGBA:
> + return GL_RGBA16F_ARB;
> + case GL_RGB:
> + return GL_RGB16F_ARB;
> + case GL_ALPHA:
> + return GL_ALPHA16F_ARB;
> + case GL_LUMINANCE:
> + return GL_LUMINANCE16F_ARB;
> + case GL_LUMINANCE_ALPHA:
> + return GL_LUMINANCE_ALPHA16F_ARB;
> + default:
> + break;
> + }
> + break;
> + }
> +
> + default:
> + break;
> + }
> +
> + return format;
> +}
>
> /**
> * Return the simple base format for a given internal texture format.
> @@ -2137,7 +2190,7 @@ texture_error_check( struct gl_context *ctx,
>
> if (_mesa_is_gles(ctx)) {
> if (_mesa_is_gles3(ctx)) {
> - err = _mesa_es3_error_check_format_and_type(format, type,
> + err = _mesa_es3_error_check_format_and_type(ctx, format, type,
> internalFormat);
> } else {
> if (format != internalFormat) {
> @@ -3239,6 +3292,19 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
> texFormat = _mesa_glenum_to_compressed_format(internalFormat);
> }
> else {
> + /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized
> + * internal floating point format for the given base format.
> + */
> + if (_mesa_is_gles(ctx) && format == internalFormat) {
> + if (type == GL_HALF_FLOAT_OES && ctx->Extensions.OES_texture_half_float)
> + texObj->IsHalfFloatOES = GL_TRUE;
> + else if (type == GL_FLOAT && ctx->Extensions.OES_texture_float)
> + texObj->IsFloatOES = GL_TRUE;
> +
> + if (texObj->IsHalfFloatOES || texObj->IsFloatOES)
> + internalFormat = adjust_for_oes_float_texture(format, type);
> + }
> +
> texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
> internalFormat, format, type);
> }
> diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
> index 923cf60..4d0099a 100644
> --- a/src/mesa/main/texobj.c
> +++ b/src/mesa/main/texobj.c
> @@ -49,6 +49,51 @@
> /** \name Internal functions */
> /*@{*/
>
> +/**
> + * This function checks for all valid combinations of Min and Mag filters for
> + * Float types, when extensions like OES_texture_float and
> + * OES_texture_float_linear are supported . OES_texture_float mentions support
> + * for NEAREST, NEAREST_MIPMAP_NEAREST magnification and minification filters.
> + * Mag filters like LINEAR and min filters like NEAREST_MIPMAP_LINEAR,
> + * LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR are only valid in case
> + * OES_texture_float_linear is supported.
> + *
> + * Returns true in case the filter is valid for given Float type else false.
> + */
> +static bool valid_filter_for_float(const struct gl_context *ctx,
> + const struct gl_texture_object *obj) {
> + ASSERT(_mesa_is_gles(ctx));
> + switch (obj->Sampler.MagFilter) {
> + case GL_LINEAR:
> + if (obj->IsHalfFloatOES && !ctx->Extensions.OES_texture_half_float_linear)
> + return false;
> + else if (obj->IsFloatOES && !ctx->Extensions.OES_texture_float_linear)
> + return false;
> + case GL_NEAREST:
> + case GL_NEAREST_MIPMAP_NEAREST:
> + break;
> + default:
> + return false;
> + }
> +
> + switch (obj->Sampler.MinFilter) {
> + case GL_NEAREST:
> + case GL_NEAREST_MIPMAP_NEAREST:
> + return true;
> + case GL_LINEAR:
> + case GL_NEAREST_MIPMAP_LINEAR:
> + case GL_LINEAR_MIPMAP_NEAREST:
> + case GL_LINEAR_MIPMAP_LINEAR:
> + if (obj->IsHalfFloatOES && ctx->Extensions.OES_texture_half_float_linear)
> + return true;
> + else if (obj->IsFloatOES && ctx->Extensions.OES_texture_float_linear)
> + return true;
> + default:
> + return false;
> + }
> +
> + return false;
> +}
>
> /**
> * Return the gl_texture_object for a given ID.
> @@ -542,6 +587,14 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
> t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT;
> }
>
> + /* Check if the texture type is Float or HalfFloatOES and ensure Min and Mag
> + * filters are supported in this case.
> + */
> + if ((t->IsFloatOES || t->IsHalfFloatOES) && !valid_filter_for_float(ctx, t)) {
> + incomplete(t, BASE, "Filter is not supported with Float types.");
> + return;
> + }
> +
> /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
> * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
> */
>
More information about the mesa-dev
mailing list