On Sat, Jul 5, 2014 at 5:20 PM, Roland Scheidegger <srol...@vmware.com> wrote: > Am 05.07.2014 06:07, schrieb Ilia Mirkin: >> The new location field can be either center, centroid, or sample, which >> indicates the location that the shader should interpolate at. > Looks good though maybe it should be mentioned in the interpolator > section in tgsi.rst (yeah centroid wasn't neither).
I added this bit: """ +The Location field specifies the location inside the pixel that the +interpolation should be done at, one of ``TGSI_INTERPOLATE_LOC_*``. """ Let me know if you want me to resend. > In any case, > Reviewed-by: Roland Scheidegger <srol...@vmware.com> > >> >> Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> >> --- >> >> I tried to make sure I hit all the uses, but I guess a bunch of drivers don't >> look at the Centroid field at all? > Well drivers not doing msaa or just fake one like llvmpipe aren't > interested in it. > And, this wasn't exposed via d3d9, though r300 reportedly can do it (the > docs even mention it for r5xx), I suspect using some of the crazy > backdoor mechanisms of d3d9. Some very quick look at the docs though > don't indicate how this could be done (if it's even possible per > interpolator) for these chips, which is I guess why centroid isn't handled. > >> >> src/gallium/auxiliary/tgsi/tgsi_build.c | 8 ++++---- >> src/gallium/auxiliary/tgsi/tgsi_dump.c | 5 +++-- >> src/gallium/auxiliary/tgsi/tgsi_scan.c | 2 +- >> src/gallium/auxiliary/tgsi/tgsi_scan.h | 2 +- >> src/gallium/auxiliary/tgsi/tgsi_strings.c | 7 +++++++ >> src/gallium/auxiliary/tgsi/tgsi_strings.h | 2 ++ >> src/gallium/auxiliary/tgsi/tgsi_ureg.c | 12 ++++++------ >> src/gallium/auxiliary/tgsi/tgsi_ureg.h | 2 +- >> src/gallium/drivers/ilo/shader/toy_tgsi.c | 2 +- >> src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 2 +- >> src/gallium/drivers/r600/r600_shader.c | 4 ++-- >> src/gallium/drivers/radeonsi/si_shader.c | 6 +++--- >> src/gallium/include/pipe/p_shader_tokens.h | 9 +++++++-- >> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 5 +++-- >> src/mesa/state_tracker/st_glsl_to_tgsi.h | 2 +- >> src/mesa/state_tracker/st_program.c | 13 +++++++++---- >> 16 files changed, 52 insertions(+), 31 deletions(-) >> >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c >> b/src/gallium/auxiliary/tgsi/tgsi_build.c >> index 7621b6a..bef5c75 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c >> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c >> @@ -200,7 +200,7 @@ tgsi_default_declaration_interp( void ) >> struct tgsi_declaration_interp di; >> >> di.Interpolate = TGSI_INTERPOLATE_CONSTANT; >> - di.Centroid = 0; >> + di.Location = TGSI_INTERPOLATE_LOC_CENTER; >> di.CylindricalWrap = 0; >> di.Padding = 0; >> >> @@ -209,7 +209,7 @@ tgsi_default_declaration_interp( void ) >> >> static struct tgsi_declaration_interp >> tgsi_build_declaration_interp(unsigned interpolate, >> - unsigned centroid, >> + unsigned interpolate_location, >> unsigned cylindrical_wrap, >> struct tgsi_declaration *declaration, >> struct tgsi_header *header) >> @@ -217,7 +217,7 @@ tgsi_build_declaration_interp(unsigned interpolate, >> struct tgsi_declaration_interp di; >> >> di.Interpolate = interpolate; >> - di.Centroid = centroid; >> + di.Location = interpolate_location; >> di.CylindricalWrap = cylindrical_wrap; >> di.Padding = 0; >> >> @@ -433,7 +433,7 @@ tgsi_build_full_declaration( >> size++; >> >> *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate, >> - full_decl->Interp.Centroid, >> + full_decl->Interp.Location, >> full_decl->Interp.CylindricalWrap, >> declaration, >> header); >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c >> b/src/gallium/auxiliary/tgsi/tgsi_dump.c >> index 8e09bac..884d8cf 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c >> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c >> @@ -349,8 +349,9 @@ iter_declaration( >> ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); >> } >> >> - if (decl->Interp.Centroid) { >> - TXT( ", CENTROID" ); >> + if (decl->Interp.Location != TGSI_INTERPOLATE_LOC_CENTER) { >> + TXT( ", " ); >> + ENM( decl->Interp.Location, tgsi_interpolate_locations ); >> } >> >> if (decl->Interp.CylindricalWrap) { >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c >> b/src/gallium/auxiliary/tgsi/tgsi_scan.c >> index 00fdcfb..563d2c5 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c >> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c >> @@ -187,7 +187,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, >> info->input_semantic_name[reg] = (ubyte) semName; >> info->input_semantic_index[reg] = (ubyte) semIndex; >> info->input_interpolate[reg] = >> (ubyte)fulldecl->Interp.Interpolate; >> - info->input_centroid[reg] = >> (ubyte)fulldecl->Interp.Centroid; >> + info->input_interpolate_loc[reg] = >> (ubyte)fulldecl->Interp.Location; >> info->input_cylindrical_wrap[reg] = >> (ubyte)fulldecl->Interp.CylindricalWrap; >> info->num_inputs++; >> >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h >> b/src/gallium/auxiliary/tgsi/tgsi_scan.h >> index 0be2feb..1869b41 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h >> +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h >> @@ -45,7 +45,7 @@ struct tgsi_shader_info >> ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x >> */ >> ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; >> ubyte input_interpolate[PIPE_MAX_SHADER_INPUTS]; >> - ubyte input_centroid[PIPE_MAX_SHADER_INPUTS]; >> + ubyte input_interpolate_loc[PIPE_MAX_SHADER_INPUTS]; >> ubyte input_usage_mask[PIPE_MAX_SHADER_INPUTS]; >> ubyte input_cylindrical_wrap[PIPE_MAX_SHADER_INPUTS]; >> ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< >> TGSI_SEMANTIC_x */ >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c >> b/src/gallium/auxiliary/tgsi/tgsi_strings.c >> index 713631f..3c108a8 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c >> +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c >> @@ -142,6 +142,13 @@ const char >> *tgsi_interpolate_names[TGSI_INTERPOLATE_COUNT] = >> "COLOR" >> }; >> >> +const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT] = >> +{ >> + "CENTER", >> + "CENTROID", >> + "SAMPLE", >> +}; >> + >> const char *tgsi_primitive_names[PIPE_PRIM_MAX] = >> { >> "POINTS", >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h >> b/src/gallium/auxiliary/tgsi/tgsi_strings.h >> index 3477d50..1c37c29 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_strings.h >> +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h >> @@ -50,6 +50,8 @@ extern const char *tgsi_type_names[5]; >> >> extern const char *tgsi_interpolate_names[TGSI_INTERPOLATE_COUNT]; >> >> +extern const char *tgsi_interpolate_locations[TGSI_INTERPOLATE_LOC_COUNT]; >> + >> extern const char *tgsi_primitive_names[PIPE_PRIM_MAX]; >> >> extern const char *tgsi_fs_coord_origin_names[2]; >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c >> b/src/gallium/auxiliary/tgsi/tgsi_ureg.c >> index bd0a3f7..39216e5 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c >> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c >> @@ -103,7 +103,7 @@ struct ureg_program >> unsigned semantic_index; >> unsigned interp; >> unsigned char cylindrical_wrap; >> - unsigned char centroid; >> + unsigned interp_location; >> } fs_input[UREG_MAX_INPUT]; >> unsigned nr_fs_inputs; >> >> @@ -345,7 +345,7 @@ ureg_DECL_fs_input_cyl_centroid(struct ureg_program >> *ureg, >> unsigned semantic_index, >> unsigned interp_mode, >> unsigned cylindrical_wrap, >> - unsigned centroid) >> + unsigned interp_location) >> { >> unsigned i; >> >> @@ -361,7 +361,7 @@ ureg_DECL_fs_input_cyl_centroid(struct ureg_program >> *ureg, >> ureg->fs_input[i].semantic_index = semantic_index; >> ureg->fs_input[i].interp = interp_mode; >> ureg->fs_input[i].cylindrical_wrap = cylindrical_wrap; >> - ureg->fs_input[i].centroid = centroid; >> + ureg->fs_input[i].interp_location = interp_location; >> ureg->nr_fs_inputs++; >> } else { >> set_bad(ureg); >> @@ -1288,7 +1288,7 @@ emit_decl_fs(struct ureg_program *ureg, >> unsigned semantic_index, >> unsigned interpolate, >> unsigned cylindrical_wrap, >> - unsigned centroid) >> + unsigned interpolate_location) >> { >> union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 4); >> >> @@ -1307,7 +1307,7 @@ emit_decl_fs(struct ureg_program *ureg, >> out[2].value = 0; >> out[2].decl_interp.Interpolate = interpolate; >> out[2].decl_interp.CylindricalWrap = cylindrical_wrap; >> - out[2].decl_interp.Centroid = centroid; >> + out[2].decl_interp.Location = interpolate_location; >> >> out[3].value = 0; >> out[3].decl_semantic.Name = semantic_name; >> @@ -1539,7 +1539,7 @@ static void emit_decls( struct ureg_program *ureg ) >> ureg->fs_input[i].semantic_index, >> ureg->fs_input[i].interp, >> ureg->fs_input[i].cylindrical_wrap, >> - ureg->fs_input[i].centroid); >> + ureg->fs_input[i].interp_location); >> } >> } else { >> for (i = 0; i < ureg->nr_gs_inputs; i++) { >> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h >> b/src/gallium/auxiliary/tgsi/tgsi_ureg.h >> index 28edea6..2c3746c 100644 >> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h >> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h >> @@ -199,7 +199,7 @@ ureg_DECL_fs_input_cyl_centroid(struct ureg_program *, >> unsigned semantic_index, >> unsigned interp_mode, >> unsigned cylindrical_wrap, >> - unsigned centroid); >> + unsigned interp_location); >> >> static INLINE struct ureg_src >> ureg_DECL_fs_input_cyl(struct ureg_program *ureg, >> diff --git a/src/gallium/drivers/ilo/shader/toy_tgsi.c >> b/src/gallium/drivers/ilo/shader/toy_tgsi.c >> index e816ab4..08fb10b 100644 >> --- a/src/gallium/drivers/ilo/shader/toy_tgsi.c >> +++ b/src/gallium/drivers/ilo/shader/toy_tgsi.c >> @@ -2298,7 +2298,7 @@ decl_add_in(struct toy_tgsi *tgsi, const struct >> tgsi_full_declaration *decl) >> tgsi->inputs[slot].semantic_index = index; >> } >> tgsi->inputs[slot].interp = interp->Interpolate; >> - tgsi->inputs[slot].centroid = interp->Centroid; >> + tgsi->inputs[slot].centroid = interp->Location == >> TGSI_INTERPOLATE_LOC_CENTROID; >> } >> } >> >> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp >> b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp >> index af3a87c..93f96a1 100644 >> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp >> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp >> @@ -950,7 +950,7 @@ bool Source::scanDeclaration(const struct >> tgsi_full_declaration *decl) >> default: >> break; >> } >> - if (decl->Interp.Centroid || info->io.sampleInterp) >> + if (decl->Interp.Location || info->io.sampleInterp) >> info->in[i].centroid = 1; >> } >> } >> diff --git a/src/gallium/drivers/r600/r600_shader.c >> b/src/gallium/drivers/r600/r600_shader.c >> index 448ca80..6952e3c 100644 >> --- a/src/gallium/drivers/r600/r600_shader.c >> +++ b/src/gallium/drivers/r600/r600_shader.c >> @@ -579,7 +579,7 @@ static int tgsi_declaration(struct r600_shader_ctx *ctx) >> ctx->shader->input[i].name = d->Semantic.Name; >> ctx->shader->input[i].sid = d->Semantic.Index; >> ctx->shader->input[i].interpolate = d->Interp.Interpolate; >> - ctx->shader->input[i].centroid = d->Interp.Centroid; >> + ctx->shader->input[i].centroid = d->Interp.Location == >> TGSI_INTERPOLATE_LOC_CENTROID; >> ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] >> + d->Range.First; >> if (ctx->type == TGSI_PROCESSOR_FRAGMENT) { >> ctx->shader->input[i].spi_sid = >> r600_spi_sid(&ctx->shader->input[i]); >> @@ -735,7 +735,7 @@ static int evergreen_gpr_count(struct r600_shader_ctx >> *ctx) >> ctx->input_linear = TRUE; >> if (ctx->info.input_interpolate[i] == >> TGSI_INTERPOLATE_PERSPECTIVE) >> ctx->input_perspective = TRUE; >> - if (ctx->info.input_centroid[i]) >> + if (ctx->info.input_interpolate_loc[i] == >> TGSI_INTERPOLATE_LOC_CENTROID) >> ctx->input_centroid = TRUE; >> } >> >> diff --git a/src/gallium/drivers/radeonsi/si_shader.c >> b/src/gallium/drivers/radeonsi/si_shader.c >> index f0650f4..07d9833 100644 >> --- a/src/gallium/drivers/radeonsi/si_shader.c >> +++ b/src/gallium/drivers/radeonsi/si_shader.c >> @@ -172,7 +172,7 @@ static int si_store_shader_io_attribs(struct si_shader >> *shader, >> shader->input[i].sid = d->Semantic.Index; >> shader->input[i].index = d->Range.First; >> shader->input[i].interpolate = d->Interp.Interpolate; >> - shader->input[i].centroid = d->Interp.Centroid; >> + shader->input[i].centroid = d->Interp.Location == >> TGSI_INTERPOLATE_LOC_CENTROID; >> return -1; >> >> case TGSI_FILE_OUTPUT: >> @@ -427,7 +427,7 @@ static void declare_input_fs( >> case TGSI_INTERPOLATE_LINEAR: >> if (si_shader_ctx->shader->key.ps.interp_at_sample) >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_LINEAR_SAMPLE); >> - else if (decl->Interp.Centroid) >> + else if (decl->Interp.Location == >> TGSI_INTERPOLATE_LOC_CENTROID) >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_LINEAR_CENTROID); >> else >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_LINEAR_CENTER); >> @@ -441,7 +441,7 @@ static void declare_input_fs( >> case TGSI_INTERPOLATE_PERSPECTIVE: >> if (si_shader_ctx->shader->key.ps.interp_at_sample) >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_PERSP_SAMPLE); >> - else if (decl->Interp.Centroid) >> + else if (decl->Interp.Location == >> TGSI_INTERPOLATE_LOC_CENTROID) >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_PERSP_CENTROID); >> else >> interp_param = LLVMGetParam(main_fn, >> SI_PARAM_PERSP_CENTER); >> diff --git a/src/gallium/include/pipe/p_shader_tokens.h >> b/src/gallium/include/pipe/p_shader_tokens.h >> index 9261b79..e68258d 100644 >> --- a/src/gallium/include/pipe/p_shader_tokens.h >> +++ b/src/gallium/include/pipe/p_shader_tokens.h >> @@ -103,6 +103,11 @@ enum tgsi_file_type { >> #define TGSI_INTERPOLATE_COLOR 3 /* special color case for >> smooth/flat */ >> #define TGSI_INTERPOLATE_COUNT 4 >> >> +#define TGSI_INTERPOLATE_LOC_CENTER 0 >> +#define TGSI_INTERPOLATE_LOC_CENTROID 1 >> +#define TGSI_INTERPOLATE_LOC_SAMPLE 2 >> +#define TGSI_INTERPOLATE_LOC_COUNT 3 >> + >> #define TGSI_CYLINDRICAL_WRAP_X (1 << 0) >> #define TGSI_CYLINDRICAL_WRAP_Y (1 << 1) >> #define TGSI_CYLINDRICAL_WRAP_Z (1 << 2) >> @@ -138,9 +143,9 @@ struct tgsi_declaration_dimension >> struct tgsi_declaration_interp >> { >> unsigned Interpolate : 4; /**< one of TGSI_INTERPOLATE_x */ >> - unsigned Centroid : 1; /**< centroid sampling? */ >> + unsigned Location : 2; /**< one of TGSI_INTERPOLATE_LOC_x */ >> unsigned CylindricalWrap:4; /**< TGSI_CYLINDRICAL_WRAP_x flags */ >> - unsigned Padding : 23; >> + unsigned Padding : 22; >> }; >> >> #define TGSI_SEMANTIC_POSITION 0 >> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp >> b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp >> index 9e19431..f47cd7d 100644 >> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp >> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp >> @@ -4848,6 +4848,7 @@ emit_edgeflags(struct st_translate *t) >> * \param inputSemanticIndex the semantic index (ex: which texcoord) for >> * each input >> * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input >> + * \param interpLocation the TGSI_INTERPOLATE_LOC_* location for each input >> * \param numOutputs number of output registers used >> * \param outputMapping maps Mesa fragment program outputs to TGSI >> * generic outputs >> @@ -4869,7 +4870,7 @@ st_translate_program( >> const ubyte inputSemanticName[], >> const ubyte inputSemanticIndex[], >> const GLuint interpMode[], >> - const GLboolean is_centroid[], >> + const GLuint interpLocation[], >> GLuint numOutputs, >> const GLuint outputMapping[], >> const ubyte outputSemanticName[], >> @@ -4915,7 +4916,7 @@ st_translate_program( >> >> inputSemanticName[i], >> >> inputSemanticIndex[i], >> interpMode[i], 0, >> - is_centroid[i]); >> + interpLocation[i]); >> } >> >> if (proginfo->InputsRead & VARYING_BIT_POS) { >> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.h >> b/src/mesa/state_tracker/st_glsl_to_tgsi.h >> index a3fe91f..2e7cb78 100644 >> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.h >> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.h >> @@ -45,7 +45,7 @@ enum pipe_error st_translate_program( >> const ubyte inputSemanticName[], >> const ubyte inputSemanticIndex[], >> const GLuint interpMode[], >> - const GLboolean is_centroid[], >> + const GLuint interpLocation[], >> GLuint numOutputs, >> const GLuint outputMapping[], >> const ubyte outputSemanticName[], >> diff --git a/src/mesa/state_tracker/st_program.c >> b/src/mesa/state_tracker/st_program.c >> index 3570557..b603759 100644 >> --- a/src/mesa/state_tracker/st_program.c >> +++ b/src/mesa/state_tracker/st_program.c >> @@ -351,7 +351,7 @@ st_translate_vertex_program(struct st_context *st, >> NULL, /* input semantic name */ >> NULL, /* input semantic index */ >> NULL, /* interp mode */ >> - NULL, /* is centroid */ >> + NULL, /* interp location */ >> /* outputs */ >> num_outputs, >> stvp->result_to_output, >> @@ -481,6 +481,7 @@ st_translate_fragment_program(struct st_context *st, >> GLuint outputMapping[FRAG_RESULT_MAX]; >> GLuint inputMapping[VARYING_SLOT_MAX]; >> GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */ >> + GLuint interpLocation[PIPE_MAX_SHADER_INPUTS]; >> GLuint attr; >> GLbitfield64 inputsRead; >> struct ureg_program *ureg; >> @@ -489,7 +490,6 @@ st_translate_fragment_program(struct st_context *st, >> >> ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; >> ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; >> - GLboolean is_centroid[PIPE_MAX_SHADER_INPUTS]; >> uint fs_num_inputs = 0; >> >> ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; >> @@ -541,7 +541,12 @@ st_translate_fragment_program(struct st_context *st, >> const GLuint slot = fs_num_inputs++; >> >> inputMapping[attr] = slot; >> - is_centroid[slot] = (stfp->Base.IsCentroid & BITFIELD64_BIT(attr)) >> != 0; >> + if (stfp->Base.IsCentroid & BITFIELD64_BIT(attr)) >> + interpLocation[slot] = TGSI_INTERPOLATE_LOC_CENTROID; >> + else if (stfp->Base.IsSample & BITFIELD64_BIT(attr)) >> + interpLocation[slot] = TGSI_INTERPOLATE_LOC_SAMPLE; >> + else >> + interpLocation[slot] = TGSI_INTERPOLATE_LOC_CENTER; >> >> switch (attr) { >> case VARYING_SLOT_POS: >> @@ -768,7 +773,7 @@ st_translate_fragment_program(struct st_context *st, >> input_semantic_name, >> input_semantic_index, >> interpMode, >> - is_centroid, >> + interpLocation, >> /* outputs */ >> fs_num_outputs, >> outputMapping, >> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev