gallium: switch dedicated centroid field to interpolation location
authorIlia Mirkin <imirkin@alum.mit.edu>
Wed, 2 Jul 2014 00:54:01 +0000 (20:54 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Wed, 9 Jul 2014 23:26:32 +0000 (19:26 -0400)
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 <imirkin@alum.mit.edu>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
17 files changed:
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h
src/gallium/auxiliary/tgsi/tgsi_strings.c
src/gallium/auxiliary/tgsi/tgsi_strings.h
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/gallium/docs/source/tgsi.rst
src/gallium/drivers/ilo/shader/toy_tgsi.c
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/include/pipe/p_shader_tokens.h
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.h
src/mesa/state_tracker/st_program.c

index 7621b6a02c9fcaed717b2f24af62f96b0f15fd42..bef5c75ac767988b37e05476cc9992fbe365f331 100644 (file)
@@ -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);
index 8e09bacf4cf9c9f4cb9edcc741dd2a77438dcd4f..884d8cf935447ac2b5e573bb48f2f8889895a9e5 100644 (file)
@@ -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) {
index 00fdcfb76e6d3d126e82d3bb1f2f5c9fae4c0860..563d2c55f60fd3347599040ce03b7f8380fa4d7c 100644 (file)
@@ -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++;
 
index 0be2febb072512974a4412be91dcff77b4c73637..1869b41e74e3d87d6a236a6f1d209b59655e453e 100644 (file)
@@ -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 */
index 713631fbec4988123a98b27b4f59d716476d02d5..3c108a8c1c9f5a909637de090e61cbde59e2a046 100644 (file)
@@ -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",
index 3477d50b8adfd3b36b07a6baa7ac30b1ee6ea484..1c37c290974a32f16e0d4b34b6433ef79d957e2b 100644 (file)
@@ -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];
index bd0a3f79fbdd87eb4c9f17a9dd3ae606403af21f..39216e59124471fde1288cfd0a184b5db1db19f6 100644 (file)
@@ -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++) {
index 28edea6cdae737050c802cff9af95ccbafcf744a..2c3746c77f2b9fa28298e6596a64b9823c0bb2aa 100644 (file)
@@ -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,
index 4213b4ac185530c2e3ace23a63e03b19a25c63da..5571b758f4bea0eeaa8be9c7d5c3e7a528d76cb9 100644 (file)
@@ -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
index e816ab44c709fe3de95cce4f8e443517cc998d73..08fb10b92739446335f74ad0c28b7b6319626de5 100644 (file)
@@ -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;
    }
 }
 
index af3a87ccf6a5a0dbcfa6008c0b2d293dab924702..93f96a1b7318864570426b95b7c79a41577cf496 100644 (file)
@@ -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;
             }
          }
index 448ca8044de8ed7a504775f6fde1dd37d70be588..6952e3c82263a6f0161ca52ef59e92b4e08db789 100644 (file)
@@ -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;
        }
 
index f0650f4fe9ddfafb6b5d9a01e2d5a1d187a753b8..07d9833bd1ca0ce74b91a73c68183fab8ac14628 100644 (file)
@@ -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);
index 9261b79d91e92c27d72f5adc709b01955fcca685..e68258d777628c080b36420ccbefa776cfe86be4 100644 (file)
@@ -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
index 9e194313942cff82af29fce2fb28b35daed933f6..f47cd7d53507362949ed840a9cca86de07ac2769 100644 (file)
@@ -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) {
index a3fe91f7e807a60f87164d924a9ef5b09dd26c9d..2e7cb78d514c9696b20c41ede6bd327bb65ad99d 100644 (file)
@@ -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[],
index 3570557fee6ae79f1ba32a2829c2bfd0f0352d84..b603759f8f8f50351b7e467158ea378988398916 100644 (file)
@@ -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,