2017-09-14 3:29 GMT+02:00 Ian Romanick <i...@freedesktop.org>: > On 09/11/2017 01:21 PM, Thomas Helland wrote: >> Length of the token was already calculated by flex and stored in yyleng, >> no need to implicitly call strlen() via linear_strdup(). >> >> Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com> >> Reviewed-by: Timothy Arceri <tarc...@itsqueeze.com> >> >> V2: Also convert this pattern in glsl_lexer.ll >> >> V3: Remove a misplaced comment >> Fix compile warning from V2 >> --- >> src/compiler/glsl/glcpp/glcpp-lex.l | 9 +- >> src/compiler/glsl/glsl_lexer.ll | 32 ++++- >> src/compiler/glsl/glsl_parser.yy | 246 >> ++++++++++++++++++------------------ >> 3 files changed, 157 insertions(+), 130 deletions(-) >> >> diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l >> b/src/compiler/glsl/glcpp/glcpp-lex.l >> index 381b97364a..9cfcc12022 100644 >> --- a/src/compiler/glsl/glcpp/glcpp-lex.l >> +++ b/src/compiler/glsl/glcpp/glcpp-lex.l >> @@ -101,7 +101,14 @@ void glcpp_set_column (int column_no , yyscan_t >> yyscanner); >> #define RETURN_STRING_TOKEN(token) \ >> do { \ >> if (! parser->skipping) { \ >> - yylval->str = linear_strdup(yyextra->linalloc, >> yytext); \ >> + /* We're not doing linear_strdup here, to avoid \ >> + * an implicit call on strlen() for the length \ >> + * of the string, as this is already found by \ >> + * flex and stored in yyleng */ \ >> + void *mem_ctx = yyextra->linalloc; \ >> + yylval->str = linear_alloc_child(mem_ctx, \ >> + yyleng + 1); \ >> + memcpy(yylval->str, yytext, yyleng + 1); \ >> RETURN_TOKEN_NEVER_SKIP (token); \ >> } \ >> } while(0) >> diff --git a/src/compiler/glsl/glsl_lexer.ll >> b/src/compiler/glsl/glsl_lexer.ll >> index 7c41455d98..3a67f0ea40 100644 >> --- a/src/compiler/glsl/glsl_lexer.ll >> +++ b/src/compiler/glsl/glsl_lexer.ll >> @@ -81,8 +81,13 @@ static int classify_identifier(struct >> _mesa_glsl_parse_state *, const char *); >> "illegal use of reserved word `%s'", yytext); \ >> return ERROR_TOK; \ >> } else { >> \ >> - void *mem_ctx = yyextra->linalloc; >> \ >> - yylval->identifier = linear_strdup(mem_ctx, yytext); \ >> + /* We're not doing linear_strdup here, to avoid an implicit \ >> + * call on strlen() for the length of the string, as this is \ >> + * already found by flex and stored in yyleng */ \ >> + void *mem_ctx = yyextra->linalloc; \ >> + yylval->identifier = (char *) linear_alloc_child(mem_ctx, \ >> + yyleng + 1); \ >> + memcpy(yylval->identifier, yytext, yyleng + 1); \ > > Could this (here and below) be implemented as: > > char *id = (char *) linear_alloc_child(mem_ctx, yyleng + 1); > memcpy(id, yytext, yyleng + 1); > yylval->identifier = id; > > Then the type of identifier doesn't have to change, and the last hunk is > unnecessary. >
That should do the trick, not sure why I didn't think of that. I'll roll up a reworked patch this evening, or during the weekend. >> return classify_identifier(yyextra, yytext); \ >> } >> \ >> } while (0) >> @@ -261,8 +266,13 @@ HASH ^{SPC}#{SPC} >> <PP>[ \t\r]* { } >> <PP>: return COLON; >> <PP>[_a-zA-Z][_a-zA-Z0-9]* { >> + /* We're not doing linear_strdup here, to >> avoid an implicit call >> + * on strlen() for the length of the >> string, as this is already >> + * found by flex and stored in yyleng >> + */ >> void *mem_ctx = yyextra->linalloc; >> - yylval->identifier = linear_strdup(mem_ctx, >> yytext); >> + yylval->identifier = (char *) >> linear_alloc_child(mem_ctx, yyleng + 1); >> + memcpy(yylval->identifier, yytext, yyleng + >> 1); >> return IDENTIFIER; >> } >> <PP>[1-9][0-9]* { >> @@ -449,8 +459,13 @@ layout { >> || yyextra->ARB_tessellation_shader_enable) { >> return LAYOUT_TOK; >> } else { >> + /* We're not doing linear_strdup here, to avoid an >> implicit call >> + * on strlen() for the length of the string, as this is >> already >> + * found by flex and stored in yyleng >> + */ >> void *mem_ctx = yyextra->linalloc; >> - yylval->identifier = linear_strdup(mem_ctx, yytext); >> + yylval->identifier = (char *) >> linear_alloc_child(mem_ctx, yyleng + 1); >> + memcpy(yylval->identifier, yytext, yyleng + 1); >> return classify_identifier(yyextra, yytext); >> } >> } >> @@ -621,12 +636,17 @@ u64vec4 KEYWORD_WITH_ALT(0, 0, 0, 0, >> yyextra->ARB_gpu_shader_int64_enable, U64V >> [_a-zA-Z][_a-zA-Z0-9]* { >> struct _mesa_glsl_parse_state *state = yyextra; >> void *ctx = state->linalloc; >> - if (state->es_shader && strlen(yytext) > 1024) { >> + if (state->es_shader && yyleng + 1 > 1024) { >> _mesa_glsl_error(yylloc, state, >> "Identifier `%s' exceeds 1024 >> characters", >> yytext); >> } else { >> - yylval->identifier = linear_strdup(ctx, yytext); >> + /* We're not doing linear_strdup here, to avoid >> an implicit call >> + * on strlen() for the length of the string, as >> this is already >> + * found by flex and stored in yyleng >> + */ >> + yylval->identifier = (char *) >> linear_alloc_child(ctx, yyleng + 1); >> + memcpy(yylval->identifier, yytext, yyleng + 1); >> } >> return classify_identifier(state, yytext); >> } >> diff --git a/src/compiler/glsl/glsl_parser.yy >> b/src/compiler/glsl/glsl_parser.yy >> index 7b93d34fa3..d10b9a6a12 100644 >> --- a/src/compiler/glsl/glsl_parser.yy >> +++ b/src/compiler/glsl/glsl_parser.yy >> @@ -100,7 +100,7 @@ static bool match_layout_qualifier(const char *s1, const >> char *s2, >> int64_t n64; >> float real; >> double dreal; >> - const char *identifier; >> + char *identifier; >> >> struct ast_type_qualifier type_qualifier; >> >> @@ -2231,128 +2231,128 @@ type_specifier_nonarray: >> ; >> >> basic_type_specifier_nonarray: >> - VOID_TOK { $$ = "void"; } >> - | FLOAT_TOK { $$ = "float"; } >> - | DOUBLE_TOK { $$ = "double"; } >> - | INT_TOK { $$ = "int"; } >> - | UINT_TOK { $$ = "uint"; } >> - | BOOL_TOK { $$ = "bool"; } >> - | VEC2 { $$ = "vec2"; } >> - | VEC3 { $$ = "vec3"; } >> - | VEC4 { $$ = "vec4"; } >> - | BVEC2 { $$ = "bvec2"; } >> - | BVEC3 { $$ = "bvec3"; } >> - | BVEC4 { $$ = "bvec4"; } >> - | IVEC2 { $$ = "ivec2"; } >> - | IVEC3 { $$ = "ivec3"; } >> - | IVEC4 { $$ = "ivec4"; } >> - | UVEC2 { $$ = "uvec2"; } >> - | UVEC3 { $$ = "uvec3"; } >> - | UVEC4 { $$ = "uvec4"; } >> - | DVEC2 { $$ = "dvec2"; } >> - | DVEC3 { $$ = "dvec3"; } >> - | DVEC4 { $$ = "dvec4"; } >> - | MAT2X2 { $$ = "mat2"; } >> - | MAT2X3 { $$ = "mat2x3"; } >> - | MAT2X4 { $$ = "mat2x4"; } >> - | MAT3X2 { $$ = "mat3x2"; } >> - | MAT3X3 { $$ = "mat3"; } >> - | MAT3X4 { $$ = "mat3x4"; } >> - | MAT4X2 { $$ = "mat4x2"; } >> - | MAT4X3 { $$ = "mat4x3"; } >> - | MAT4X4 { $$ = "mat4"; } >> - | DMAT2X2 { $$ = "dmat2"; } >> - | DMAT2X3 { $$ = "dmat2x3"; } >> - | DMAT2X4 { $$ = "dmat2x4"; } >> - | DMAT3X2 { $$ = "dmat3x2"; } >> - | DMAT3X3 { $$ = "dmat3"; } >> - | DMAT3X4 { $$ = "dmat3x4"; } >> - | DMAT4X2 { $$ = "dmat4x2"; } >> - | DMAT4X3 { $$ = "dmat4x3"; } >> - | DMAT4X4 { $$ = "dmat4"; } >> - | SAMPLER1D { $$ = "sampler1D"; } >> - | SAMPLER2D { $$ = "sampler2D"; } >> - | SAMPLER2DRECT { $$ = "sampler2DRect"; } >> - | SAMPLER3D { $$ = "sampler3D"; } >> - | SAMPLERCUBE { $$ = "samplerCube"; } >> - | SAMPLEREXTERNALOES { $$ = "samplerExternalOES"; } >> - | SAMPLER1DSHADOW { $$ = "sampler1DShadow"; } >> - | SAMPLER2DSHADOW { $$ = "sampler2DShadow"; } >> - | SAMPLER2DRECTSHADOW { $$ = "sampler2DRectShadow"; } >> - | SAMPLERCUBESHADOW { $$ = "samplerCubeShadow"; } >> - | SAMPLER1DARRAY { $$ = "sampler1DArray"; } >> - | SAMPLER2DARRAY { $$ = "sampler2DArray"; } >> - | SAMPLER1DARRAYSHADOW { $$ = "sampler1DArrayShadow"; } >> - | SAMPLER2DARRAYSHADOW { $$ = "sampler2DArrayShadow"; } >> - | SAMPLERBUFFER { $$ = "samplerBuffer"; } >> - | SAMPLERCUBEARRAY { $$ = "samplerCubeArray"; } >> - | SAMPLERCUBEARRAYSHADOW { $$ = "samplerCubeArrayShadow"; } >> - | ISAMPLER1D { $$ = "isampler1D"; } >> - | ISAMPLER2D { $$ = "isampler2D"; } >> - | ISAMPLER2DRECT { $$ = "isampler2DRect"; } >> - | ISAMPLER3D { $$ = "isampler3D"; } >> - | ISAMPLERCUBE { $$ = "isamplerCube"; } >> - | ISAMPLER1DARRAY { $$ = "isampler1DArray"; } >> - | ISAMPLER2DARRAY { $$ = "isampler2DArray"; } >> - | ISAMPLERBUFFER { $$ = "isamplerBuffer"; } >> - | ISAMPLERCUBEARRAY { $$ = "isamplerCubeArray"; } >> - | USAMPLER1D { $$ = "usampler1D"; } >> - | USAMPLER2D { $$ = "usampler2D"; } >> - | USAMPLER2DRECT { $$ = "usampler2DRect"; } >> - | USAMPLER3D { $$ = "usampler3D"; } >> - | USAMPLERCUBE { $$ = "usamplerCube"; } >> - | USAMPLER1DARRAY { $$ = "usampler1DArray"; } >> - | USAMPLER2DARRAY { $$ = "usampler2DArray"; } >> - | USAMPLERBUFFER { $$ = "usamplerBuffer"; } >> - | USAMPLERCUBEARRAY { $$ = "usamplerCubeArray"; } >> - | SAMPLER2DMS { $$ = "sampler2DMS"; } >> - | ISAMPLER2DMS { $$ = "isampler2DMS"; } >> - | USAMPLER2DMS { $$ = "usampler2DMS"; } >> - | SAMPLER2DMSARRAY { $$ = "sampler2DMSArray"; } >> - | ISAMPLER2DMSARRAY { $$ = "isampler2DMSArray"; } >> - | USAMPLER2DMSARRAY { $$ = "usampler2DMSArray"; } >> - | IMAGE1D { $$ = "image1D"; } >> - | IMAGE2D { $$ = "image2D"; } >> - | IMAGE3D { $$ = "image3D"; } >> - | IMAGE2DRECT { $$ = "image2DRect"; } >> - | IMAGECUBE { $$ = "imageCube"; } >> - | IMAGEBUFFER { $$ = "imageBuffer"; } >> - | IMAGE1DARRAY { $$ = "image1DArray"; } >> - | IMAGE2DARRAY { $$ = "image2DArray"; } >> - | IMAGECUBEARRAY { $$ = "imageCubeArray"; } >> - | IMAGE2DMS { $$ = "image2DMS"; } >> - | IMAGE2DMSARRAY { $$ = "image2DMSArray"; } >> - | IIMAGE1D { $$ = "iimage1D"; } >> - | IIMAGE2D { $$ = "iimage2D"; } >> - | IIMAGE3D { $$ = "iimage3D"; } >> - | IIMAGE2DRECT { $$ = "iimage2DRect"; } >> - | IIMAGECUBE { $$ = "iimageCube"; } >> - | IIMAGEBUFFER { $$ = "iimageBuffer"; } >> - | IIMAGE1DARRAY { $$ = "iimage1DArray"; } >> - | IIMAGE2DARRAY { $$ = "iimage2DArray"; } >> - | IIMAGECUBEARRAY { $$ = "iimageCubeArray"; } >> - | IIMAGE2DMS { $$ = "iimage2DMS"; } >> - | IIMAGE2DMSARRAY { $$ = "iimage2DMSArray"; } >> - | UIMAGE1D { $$ = "uimage1D"; } >> - | UIMAGE2D { $$ = "uimage2D"; } >> - | UIMAGE3D { $$ = "uimage3D"; } >> - | UIMAGE2DRECT { $$ = "uimage2DRect"; } >> - | UIMAGECUBE { $$ = "uimageCube"; } >> - | UIMAGEBUFFER { $$ = "uimageBuffer"; } >> - | UIMAGE1DARRAY { $$ = "uimage1DArray"; } >> - | UIMAGE2DARRAY { $$ = "uimage2DArray"; } >> - | UIMAGECUBEARRAY { $$ = "uimageCubeArray"; } >> - | UIMAGE2DMS { $$ = "uimage2DMS"; } >> - | UIMAGE2DMSARRAY { $$ = "uimage2DMSArray"; } >> - | ATOMIC_UINT { $$ = "atomic_uint"; } >> - | INT64_TOK { $$ = "int64_t"; } >> - | I64VEC2 { $$ = "i64vec2"; } >> - | I64VEC3 { $$ = "i64vec3"; } >> - | I64VEC4 { $$ = "i64vec4"; } >> - | UINT64_TOK { $$ = "uint64_t"; } >> - | U64VEC2 { $$ = "u64vec2"; } >> - | U64VEC3 { $$ = "u64vec3"; } >> - | U64VEC4 { $$ = "u64vec4"; } >> + VOID_TOK { $$ = (char *) "void"; } >> + | FLOAT_TOK { $$ = (char *) "float"; } >> + | DOUBLE_TOK { $$ = (char *) "double"; } >> + | INT_TOK { $$ = (char *) "int"; } >> + | UINT_TOK { $$ = (char *) "uint"; } >> + | BOOL_TOK { $$ = (char *) "bool"; } >> + | VEC2 { $$ = (char *) "vec2"; } >> + | VEC3 { $$ = (char *) "vec3"; } >> + | VEC4 { $$ = (char *) "vec4"; } >> + | BVEC2 { $$ = (char *) "bvec2"; } >> + | BVEC3 { $$ = (char *) "bvec3"; } >> + | BVEC4 { $$ = (char *) "bvec4"; } >> + | IVEC2 { $$ = (char *) "ivec2"; } >> + | IVEC3 { $$ = (char *) "ivec3"; } >> + | IVEC4 { $$ = (char *) "ivec4"; } >> + | UVEC2 { $$ = (char *) "uvec2"; } >> + | UVEC3 { $$ = (char *) "uvec3"; } >> + | UVEC4 { $$ = (char *) "uvec4"; } >> + | DVEC2 { $$ = (char *) "dvec2"; } >> + | DVEC3 { $$ = (char *) "dvec3"; } >> + | DVEC4 { $$ = (char *) "dvec4"; } >> + | MAT2X2 { $$ = (char *) "mat2"; } >> + | MAT2X3 { $$ = (char *) "mat2x3"; } >> + | MAT2X4 { $$ = (char *) "mat2x4"; } >> + | MAT3X2 { $$ = (char *) "mat3x2"; } >> + | MAT3X3 { $$ = (char *) "mat3"; } >> + | MAT3X4 { $$ = (char *) "mat3x4"; } >> + | MAT4X2 { $$ = (char *) "mat4x2"; } >> + | MAT4X3 { $$ = (char *) "mat4x3"; } >> + | MAT4X4 { $$ = (char *) "mat4"; } >> + | DMAT2X2 { $$ = (char *) "dmat2"; } >> + | DMAT2X3 { $$ = (char *) "dmat2x3"; } >> + | DMAT2X4 { $$ = (char *) "dmat2x4"; } >> + | DMAT3X2 { $$ = (char *) "dmat3x2"; } >> + | DMAT3X3 { $$ = (char *) "dmat3"; } >> + | DMAT3X4 { $$ = (char *) "dmat3x4"; } >> + | DMAT4X2 { $$ = (char *) "dmat4x2"; } >> + | DMAT4X3 { $$ = (char *) "dmat4x3"; } >> + | DMAT4X4 { $$ = (char *) "dmat4"; } >> + | SAMPLER1D { $$ = (char *) "sampler1D"; } >> + | SAMPLER2D { $$ = (char *) "sampler2D"; } >> + | SAMPLER2DRECT { $$ = (char *) "sampler2DRect"; } >> + | SAMPLER3D { $$ = (char *) "sampler3D"; } >> + | SAMPLERCUBE { $$ = (char *) "samplerCube"; } >> + | SAMPLEREXTERNALOES { $$ = (char *) "samplerExternalOES"; } >> + | SAMPLER1DSHADOW { $$ = (char *) "sampler1DShadow"; } >> + | SAMPLER2DSHADOW { $$ = (char *) "sampler2DShadow"; } >> + | SAMPLER2DRECTSHADOW { $$ = (char *) "sampler2DRectShadow"; } >> + | SAMPLERCUBESHADOW { $$ = (char *) "samplerCubeShadow"; } >> + | SAMPLER1DARRAY { $$ = (char *) "sampler1DArray"; } >> + | SAMPLER2DARRAY { $$ = (char *) "sampler2DArray"; } >> + | SAMPLER1DARRAYSHADOW { $$ = (char *) "sampler1DArrayShadow"; } >> + | SAMPLER2DARRAYSHADOW { $$ = (char *) "sampler2DArrayShadow"; } >> + | SAMPLERBUFFER { $$ = (char *) "samplerBuffer"; } >> + | SAMPLERCUBEARRAY { $$ = (char *) "samplerCubeArray"; } >> + | SAMPLERCUBEARRAYSHADOW { $$ = (char *) "samplerCubeArrayShadow"; } >> + | ISAMPLER1D { $$ = (char *) "isampler1D"; } >> + | ISAMPLER2D { $$ = (char *) "isampler2D"; } >> + | ISAMPLER2DRECT { $$ = (char *) "isampler2DRect"; } >> + | ISAMPLER3D { $$ = (char *) "isampler3D"; } >> + | ISAMPLERCUBE { $$ = (char *) "isamplerCube"; } >> + | ISAMPLER1DARRAY { $$ = (char *) "isampler1DArray"; } >> + | ISAMPLER2DARRAY { $$ = (char *) "isampler2DArray"; } >> + | ISAMPLERBUFFER { $$ = (char *) "isamplerBuffer"; } >> + | ISAMPLERCUBEARRAY { $$ = (char *) "isamplerCubeArray"; } >> + | USAMPLER1D { $$ = (char *) "usampler1D"; } >> + | USAMPLER2D { $$ = (char *) "usampler2D"; } >> + | USAMPLER2DRECT { $$ = (char *) "usampler2DRect"; } >> + | USAMPLER3D { $$ = (char *) "usampler3D"; } >> + | USAMPLERCUBE { $$ = (char *) "usamplerCube"; } >> + | USAMPLER1DARRAY { $$ = (char *) "usampler1DArray"; } >> + | USAMPLER2DARRAY { $$ = (char *) "usampler2DArray"; } >> + | USAMPLERBUFFER { $$ = (char *) "usamplerBuffer"; } >> + | USAMPLERCUBEARRAY { $$ = (char *) "usamplerCubeArray"; } >> + | SAMPLER2DMS { $$ = (char *) "sampler2DMS"; } >> + | ISAMPLER2DMS { $$ = (char *) "isampler2DMS"; } >> + | USAMPLER2DMS { $$ = (char *) "usampler2DMS"; } >> + | SAMPLER2DMSARRAY { $$ = (char *) "sampler2DMSArray"; } >> + | ISAMPLER2DMSARRAY { $$ = (char *) "isampler2DMSArray"; } >> + | USAMPLER2DMSARRAY { $$ = (char *) "usampler2DMSArray"; } >> + | IMAGE1D { $$ = (char *) "image1D"; } >> + | IMAGE2D { $$ = (char *) "image2D"; } >> + | IMAGE3D { $$ = (char *) "image3D"; } >> + | IMAGE2DRECT { $$ = (char *) "image2DRect"; } >> + | IMAGECUBE { $$ = (char *) "imageCube"; } >> + | IMAGEBUFFER { $$ = (char *) "imageBuffer"; } >> + | IMAGE1DARRAY { $$ = (char *) "image1DArray"; } >> + | IMAGE2DARRAY { $$ = (char *) "image2DArray"; } >> + | IMAGECUBEARRAY { $$ = (char *) "imageCubeArray"; } >> + | IMAGE2DMS { $$ = (char *) "image2DMS"; } >> + | IMAGE2DMSARRAY { $$ = (char *) "image2DMSArray"; } >> + | IIMAGE1D { $$ = (char *) "iimage1D"; } >> + | IIMAGE2D { $$ = (char *) "iimage2D"; } >> + | IIMAGE3D { $$ = (char *) "iimage3D"; } >> + | IIMAGE2DRECT { $$ = (char *) "iimage2DRect"; } >> + | IIMAGECUBE { $$ = (char *) "iimageCube"; } >> + | IIMAGEBUFFER { $$ = (char *) "iimageBuffer"; } >> + | IIMAGE1DARRAY { $$ = (char *) "iimage1DArray"; } >> + | IIMAGE2DARRAY { $$ = (char *) "iimage2DArray"; } >> + | IIMAGECUBEARRAY { $$ = (char *) "iimageCubeArray"; } >> + | IIMAGE2DMS { $$ = (char *) "iimage2DMS"; } >> + | IIMAGE2DMSARRAY { $$ = (char *) "iimage2DMSArray"; } >> + | UIMAGE1D { $$ = (char *) "uimage1D"; } >> + | UIMAGE2D { $$ = (char *) "uimage2D"; } >> + | UIMAGE3D { $$ = (char *) "uimage3D"; } >> + | UIMAGE2DRECT { $$ = (char *) "uimage2DRect"; } >> + | UIMAGECUBE { $$ = (char *) "uimageCube"; } >> + | UIMAGEBUFFER { $$ = (char *) "uimageBuffer"; } >> + | UIMAGE1DARRAY { $$ = (char *) "uimage1DArray"; } >> + | UIMAGE2DARRAY { $$ = (char *) "uimage2DArray"; } >> + | UIMAGECUBEARRAY { $$ = (char *) "uimageCubeArray"; } >> + | UIMAGE2DMS { $$ = (char *) "uimage2DMS"; } >> + | UIMAGE2DMSARRAY { $$ = (char *) "uimage2DMSArray"; } >> + | ATOMIC_UINT { $$ = (char *) "atomic_uint"; } >> + | INT64_TOK { $$ = (char *) "int64_t"; } >> + | I64VEC2 { $$ = (char *) "i64vec2"; } >> + | I64VEC3 { $$ = (char *) "i64vec3"; } >> + | I64VEC4 { $$ = (char *) "i64vec4"; } >> + | UINT64_TOK { $$ = (char *) "uint64_t"; } >> + | U64VEC2 { $$ = (char *) "u64vec2"; } >> + | U64VEC3 { $$ = (char *) "u64vec3"; } >> + | U64VEC4 { $$ = (char *) "u64vec4"; } >> ; >> >> precision_qualifier: >> > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev