From 4c97ed4411e3653a082875b79587fb308c284a99 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Tue, 1 Jul 2014 20:54:01 -0400 Subject: [PATCH] gallium: switch dedicated centroid field to interpolation location The new location field can be either center, centroid, or sample, which indicates the location that the shader should interpolate at. Signed-off-by: Ilia Mirkin Reviewed-by: Roland Scheidegger --- 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/docs/source/tgsi.rst | 5 +++++ src/gallium/drivers/ilo/shader/toy_tgsi.c | 2 +- .../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 +++++++++---- 17 files changed, 57 insertions(+), 31 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 7621b6a02c9..bef5c75ac76 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 8e09bacf4cf..884d8cf9354 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 00fdcfb76e6..563d2c55f60 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 0be2febb072..1869b41e74e 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 713631fbec4..3c108a8c1c9 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 3477d50b8ad..1c37c290974 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 bd0a3f79fbd..39216e59124 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 28edea6cdae..2c3746c77f2 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/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst index 4213b4ac185..5571b758f4b 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -2735,6 +2735,11 @@ This token is only valid for fragment shader INPUT declarations. The Interpolate field specifes the way input is being interpolated by the rasteriser and is one of TGSI_INTERPOLATE_*. +The Location field specifies the location inside the pixel that the +interpolation should be done at, one of ``TGSI_INTERPOLATE_LOC_*``. Note that +when per-sample shading is enabled, the implementation may choose to +interpolate at the sample irrespective of the Location field. + The CylindricalWrap bitfield specifies which register components should be subject to cylindrical wrapping when interpolating by the rasteriser. If TGSI_CYLINDRICAL_WRAP_X is set to 1, the X component diff --git a/src/gallium/drivers/ilo/shader/toy_tgsi.c b/src/gallium/drivers/ilo/shader/toy_tgsi.c index e816ab44c70..08fb10b9273 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 af3a87ccf6a..93f96a1b731 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 448ca8044de..6952e3c8226 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 f0650f4fe9d..07d9833bd1c 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 9261b79d91e..e68258d7776 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 9e194313942..f47cd7d5350 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 a3fe91f7e80..2e7cb78d514 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 3570557fee6..b603759f8f8 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, -- 2.30.2