[Mesa-dev] [PATCH] gallium: add TGSI_SEMANTIC_TEXCOORD,PCOORD

Christoph Bumiller e0425955 at student.tuwien.ac.at
Wed Mar 13 12:51:45 PDT 2013


Second attempt, 2 years ago no one replied or cared ...

We really need to know about these on nvc0 because there are only 8
fixed hardware locations that can be overwritten by sprite coordinates,
and one location that represents gl_PointCoord and unconditionally
returns sprite coordinates.

So far this was solved via a hack, which works since the locations the
state tracker picks aren't dynamic (and likely will never be, to facilitate
ARB_separate_shader_objects), but it still isn't nice to do it this way.

It looks like nv30 was using a hack, too, since it had a check for
Semantic.Index == 9, which is what mesa uses for PointCoord.

Implementing a safe, non-mesa-dependent way without these SEMANTICs would
be jumping through hoops and doing expensive shader recompilations just
because we like to destroy information at the gallium threshold, and that's
unacceptable.

I started to (try) fix up the other drivers, but maybe we just want a CAP
for this instead, since the default solution - if this is TEXCOORD then
treat it as GENERIC with semantic index += MAX_TEXCOORDS - doesn't really
look that nicer either.
E.g. if PIPE_CAP_RESTRICTED_SPRITE_COORDS is advertised, the state tracker
should use the TEXCOORD and PCOORD semantics, otherwise it should just use
GENERICs as before.
---
 src/gallium/auxiliary/draw/draw_pipe_wide_point.c  |   39 ++++++++--------
 src/gallium/auxiliary/tgsi/tgsi_dump.c             |    1 +
 src/gallium/auxiliary/tgsi/tgsi_strings.c          |    2 +
 src/gallium/docs/source/cso/rasterizer.rst         |    2 +-
 src/gallium/docs/source/tgsi.rst                   |   23 +++++++++-
 src/gallium/drivers/freedreno/freedreno_compiler.c |    2 +
 src/gallium/drivers/i915/i915_fpc_translate.c      |    2 +
 src/gallium/drivers/i915/i915_state_derived.c      |    4 ++
 src/gallium/drivers/llvmpipe/lp_setup_point.c      |   29 ++++++------
 src/gallium/drivers/nv30/nvfx_fragprog.c           |   39 ++++++++--------
 src/gallium/drivers/nv50/nv50_shader_state.c       |    8 +--
 src/gallium/drivers/nv50/nv50_surface.c            |    5 +-
 src/gallium/drivers/nvc0/nvc0_program.c            |   37 +--------------
 src/gallium/drivers/r300/r300_fs.c                 |    2 +
 src/gallium/drivers/r300/r300_shader_semantics.h   |    3 +-
 src/gallium/drivers/r300/r300_vs.c                 |    2 +
 src/gallium/drivers/r600/evergreen_state.c         |    7 ++-
 src/gallium/drivers/r600/r600_shader.c             |    3 +-
 src/gallium/drivers/r600/r600_state.c              |    7 ++-
 src/gallium/drivers/radeonsi/radeonsi_shader.c     |    1 +
 src/gallium/drivers/radeonsi/si_state.c            |    2 +-
 src/gallium/drivers/radeonsi/si_state_draw.c       |    5 +-
 src/gallium/include/pipe/p_shader_tokens.h         |   36 +++++++++------
 src/gallium/include/pipe/p_state.h                 |    2 +-
 src/mesa/state_tracker/st_atom_rasterizer.c        |    6 +--
 src/mesa/state_tracker/st_program.c                |   48 +++++++++----------
 26 files changed, 162 insertions(+), 155 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 8e0a117..d4ed0f7 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -233,28 +233,29 @@ widepoint_first_point(struct draw_stage *stage,
 
       wide->num_texcoord_gen = 0;
 
-      /* Loop over fragment shader inputs looking for generic inputs
-       * for which bit 'k' in sprite_coord_enable is set.
+      /* Loop over fragment shader inputs looking for the PCOORD input or
+       * TEXCOORD inputs for which bit 'k' in sprite_coord_enable is set.
        */
       for (i = 0; i < fs->info.num_inputs; i++) {
-         if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
-            const int generic_index = fs->info.input_semantic_index[i];
-            /* Note that sprite_coord enable is a bitfield of
-             * PIPE_MAX_SHADER_OUTPUTS bits.
-             */
-            if (generic_index < PIPE_MAX_SHADER_OUTPUTS &&
-                (rast->sprite_coord_enable & (1 << generic_index))) {
-               /* OK, this generic attribute needs to be replaced with a
-                * texcoord (see above).
-                */
-               int slot = draw_alloc_extra_vertex_attrib(draw,
-                                                         TGSI_SEMANTIC_GENERIC,
-                                                         generic_index);
-
-               /* add this slot to the texcoord-gen list */
-               wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot;
-            }
+         int slot;
+         const unsigned sn = fs->info.input_semantic_name[i];
+         const unsigned si = fs->info.input_semantic_index[i];
+
+         if (sn == TGSI_SEMANTIC_TEXCOORD) {
+            /* Note that sprite_coord enable is a bitfield of 8 bits. */
+            if (si >= 8 || !(rast->sprite_coord_enable & (1 << si)))
+               continue;
+         } else if (sn != TGSI_SEMANTIC_PCOORD) {
+            continue;
          }
+
+         /* OK, this generic attribute needs to be replaced with a
+          * sprite coord (see above).
+          */
+         slot = draw_alloc_extra_vertex_attrib(draw, sn, si);
+
+         /* add this slot to the texcoord-gen list */
+         wide->texcoord_gen_slot[wide->num_texcoord_gen++] = slot;
       }
    }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 3e6f76a..8f16f2d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -279,6 +279,7 @@ iter_declaration(
       TXT( ", " );
       ENM( decl->Semantic.Name, tgsi_semantic_names );
       if (decl->Semantic.Index != 0 ||
+          decl->Semantic.Name == TGSI_SEMANTIC_TEXCOORD ||
           decl->Semantic.Name == TGSI_SEMANTIC_GENERIC) {
          CHR( '[' );
          UID( decl->Semantic.Index );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c
index 70f997b..eb73521 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
@@ -65,6 +65,8 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] =
    "BCOLOR",
    "FOG",
    "PSIZE",
+   "PCOORD",
+   "TEXCOORD",
    "GENERIC",
    "NORMAL",
    "FACE",
diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
index f4e24f0..61124e5 100644
--- a/src/gallium/docs/source/cso/rasterizer.rst
+++ b/src/gallium/docs/source/cso/rasterizer.rst
@@ -162,7 +162,7 @@ sprite_coord_enable
 
 Controls automatic texture coordinate generation for rendering sprite points.
 
-When bit k in the sprite_coord_enable bitfield is set, then generic
+When bit k in the sprite_coord_enable bitfield is set, then TEXCOORD
 input k to the fragment shader will get an automatically computed
 texture coordinate.
 
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index d9a7fe9..2016e25 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -1922,7 +1922,7 @@ TGSI_SEMANTIC_PSIZE
 """""""""""""""""""
 
 Vertex shader input and output registers may be labeled with
-TGIS_SEMANTIC_PSIZE to indicate that the register contains a point size
+TGSI_SEMANTIC_PSIZE to indicate that the register contains a point size
 in the form (S, 0, 0, 1).  The point size controls the width or diameter
 of points for rasterization.  This label cannot be used in fragment
 shaders.
@@ -1930,13 +1930,32 @@ shaders.
 When using this semantic, be sure to set the appropriate state in the
 :ref:`rasterizer` first.
 
+TGSI_SEMANTIC_PCOORD
+""""""""""""""""""""
+
+Fragment shader inputs may be labeled with TGSI_SEMANTIC_PCOORD to indicate
+that the register contains sprite coordinates in the form (x, y, 0, 1), if
+the current primitive is a point and point sprites are enabled.
+Otherwise, the contents of the register are undefined.
+This semantic should be used for gl_PointCoord.
+
+
+TGSI_SEMANTIC_TEXCOORD
+""""""""""""""""""""""
+
+Vertex shader outputs and fragment shader inputs may be labeled with this
+semantic to make the registers replaceable by sprite coordinates via the
+sprite_coord_enable state in the :ref:`rasterizer`.
+The semantic index permitted with this semantic is limited to <= 7.
+This semantic should be used for gl_TexCoord.
+
 
 TGSI_SEMANTIC_GENERIC
 """""""""""""""""""""
 
 All vertex/fragment shader inputs/outputs not labeled with any other
 semantic label can be considered to be generic attributes.  Typical
-uses of generic inputs/outputs are texcoords and user-defined values.
+uses of generic inputs/outputs are user-defined values.
 
 
 TGSI_SEMANTIC_NORMAL
diff --git a/src/gallium/drivers/freedreno/freedreno_compiler.c b/src/gallium/drivers/freedreno/freedreno_compiler.c
index 0610902..c3c81d1 100644
--- a/src/gallium/drivers/freedreno/freedreno_compiler.c
+++ b/src/gallium/drivers/freedreno/freedreno_compiler.c
@@ -102,6 +102,8 @@ semantic_idx(struct tgsi_declaration_semantic *semantic)
 	int idx = semantic->Name;
 	if (idx == TGSI_SEMANTIC_GENERIC)
 		idx = TGSI_SEMANTIC_COUNT + semantic->Index;
+	if (idx == TGSI_SEMANTIC_TEXCOORD)
+		idx = TGSI_SEMANTIC_COUNT + semantic->Index + TGSI_MAX_TEXCOORDS;
 	return idx;
 }
 
diff --git a/src/gallium/drivers/i915/i915_fpc_translate.c b/src/gallium/drivers/i915/i915_fpc_translate.c
index def9a03..94ae5aa 100644
--- a/src/gallium/drivers/i915/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915/i915_fpc_translate.c
@@ -230,6 +230,8 @@ src_vector(struct i915_fp_compile *p,
          src = swizzle(src, W, W, W, W);
          break;
       case TGSI_SEMANTIC_GENERIC:
+         sem_ind += TGSI_MAX_TEXCOORDS;
+      case TGSI_SEMANTIC_TEXCOORD:
          {
             int real_tex_unit = get_mapping(fs, sem_ind);
             src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL);
diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c
index e01f16e..a1dde05 100644
--- a/src/gallium/drivers/i915/i915_state_derived.c
+++ b/src/gallium/drivers/i915/i915_state_derived.c
@@ -82,11 +82,15 @@ static void calculate_vertex_layout(struct i915_context *i915)
          assert(fs->info.input_semantic_index[i] < 2);
          colors[fs->info.input_semantic_index[i]] = TRUE;
          break;
+      case TGSI_SEMANTIC_TEXCOORD:
       case TGSI_SEMANTIC_GENERIC:
          {
             /* texcoords/varyings/other generic */
             uint unit = fs->info.input_semantic_index[i];
 
+            if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_GENERIC)
+               unit += TGSI_MAX_TEXCOORDS;
+
             texCoords[find_mapping(fs, unit)] = TRUE;
             needW = TRUE;
          }
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_point.c b/src/gallium/drivers/llvmpipe/lp_setup_point.c
index 146f1bd..71f11bb 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_point.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_point.c
@@ -220,6 +220,9 @@ setup_point_coefficients( struct lp_setup_context *setup,
       boolean perspective = !!(interp == LP_INTERP_PERSPECTIVE);
       unsigned i;
 
+      const unsigned sn = shader->info.base.input_semantic_name[slot];
+      const unsigned si = shader->info.base.input_semantic_index[slot];
+
       if (perspective & usage_mask) {
          fragcoord_usage_mask |= TGSI_WRITEMASK_W;
       }
@@ -238,25 +241,21 @@ setup_point_coefficients( struct lp_setup_context *setup,
          /* Sprite tex coords may use linear interpolation someday */
          /* fall-through */
       case LP_INTERP_PERSPECTIVE:
-         /* check if the sprite coord flag is set for this attribute.
+         /* Check if the sprite coord flag is set for this attribute or
+          * if has the PCOORD semantic.
           * If so, set it up so it up so x and y vary from 0 to 1.
           */
-         if (shader->info.base.input_semantic_name[slot] == TGSI_SEMANTIC_GENERIC) {
-            unsigned semantic_index = shader->info.base.input_semantic_index[slot];
-            /* Note that sprite_coord enable is a bitfield of
-             * PIPE_MAX_SHADER_OUTPUTS bits.
-             */
-            if (semantic_index < PIPE_MAX_SHADER_OUTPUTS &&
-                (setup->sprite_coord_enable & (1 << semantic_index))) {
-               for (i = 0; i < NUM_CHANNELS; i++) {
-                  if (usage_mask & (1 << i)) {
-                     texcoord_coef(setup, info, slot + 1, i,
-                                   setup->sprite_coord_origin,
-                                   perspective);
-                  }
+         if (sn == TGSI_SEMANTIC_PCOORD ||
+             (sn == TGSI_SEMANTIC_TEXCOORD &&
+              si < 8 && setup->sprite_coord_enable & (1 << si))) {
+            for (i = 0; i < NUM_CHANNELS; i++) {
+               if (usage_mask & (1 << i)) {
+                  texcoord_coef(setup, info, slot + 1, i,
+                                setup->sprite_coord_origin,
+                                perspective);
                }
-               break;
             }
+            break;
          }
          /* fall-through */
       case LP_INTERP_CONSTANT:
diff --git a/src/gallium/drivers/nv30/nvfx_fragprog.c b/src/gallium/drivers/nv30/nvfx_fragprog.c
index 935804e..5805b12 100644
--- a/src/gallium/drivers/nv30/nvfx_fragprog.c
+++ b/src/gallium/drivers/nv30/nvfx_fragprog.c
@@ -927,15 +927,17 @@ nvfx_fragprog_parse_decl_input(struct nv30_context *nvfx, struct nvfx_fpc *fpc,
    case TGSI_SEMANTIC_FACE:
       hw = NV40_FP_OP_INPUT_SRC_FACING;
       break;
-   case TGSI_SEMANTIC_GENERIC:
-      if (fdec->Semantic.Index >= 8)
-         return TRUE;
-
+   case TGSI_SEMANTIC_TEXCOORD:
+      assert(fdec->Semantic.Index < 8);
       fpc->fp->texcoord[fdec->Semantic.Index] = fdec->Semantic.Index;
       fpc->fp->texcoords |= (1 << fdec->Semantic.Index);
       fpc->fp->vp_or |= (0x00004000 << fdec->Semantic.Index);
       hw = NVFX_FP_OP_INPUT_SRC_TC(fdec->Semantic.Index);
       break;
+   case TGSI_SEMANTIC_GENERIC:
+   case TGSI_SEMANTIC_PCOORD:
+      /* will later assigned to remaining TC slots */
+      return TRUE;
    default:
       assert(0);
       return FALSE;
@@ -955,22 +957,21 @@ nvfx_fragprog_assign_generic(struct nv30_context *nvfx, struct nvfx_fpc *fpc,
 
    switch (fdec->Semantic.Name) {
    case TGSI_SEMANTIC_GENERIC:
-      if (fdec->Semantic.Index >= 8) {
-         for (hw = 0; hw < num_texcoords; hw++) {
-            if (fpc->fp->texcoord[hw] == 0xffff) {
-               fpc->fp->texcoord[hw] = fdec->Semantic.Index;
-               if (hw <= 7) {
-                  fpc->fp->texcoords |= (0x1 << hw);
-                  fpc->fp->vp_or |= (0x00004000 << hw);
-               } else {
-                  fpc->fp->vp_or |= (0x00001000 << (hw - 8));
-               }
-               if (fdec->Semantic.Index == 9)
-                  fpc->fp->point_sprite_control |= (0x00000100 << hw);
-               hw = NVFX_FP_OP_INPUT_SRC_TC(hw);
-               fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw);
-               return TRUE;
+   case TGSI_SEMANTIC_PCOORD:
+      for (hw = 0; hw < num_texcoords; hw++) {
+         if (fpc->fp->texcoord[hw] == 0xffff) {
+            fpc->fp->texcoord[hw] = fdec->Semantic.Index;
+            if (hw <= 7) {
+               fpc->fp->texcoords |= (0x1 << hw);
+               fpc->fp->vp_or |= (0x00004000 << hw);
+            } else {
+               fpc->fp->vp_or |= (0x00001000 << (hw - 8));
             }
+            if (fdec->Semantic.Name == TGSI_SEMANTIC_PCOORD)
+               fpc->fp->point_sprite_control |= (0x00000100 << hw);
+            hw = NVFX_FP_OP_INPUT_SRC_TC(hw);
+            fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw);
+            return TRUE;
          }
          return FALSE;
       }
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index 7f05243..48aef24 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -238,11 +238,9 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
    for (i = 0; i < fp->in_nr; i++) {
       unsigned n = util_bitcount(fp->in[i].mask);
 
-      if (fp->in[i].sn != TGSI_SEMANTIC_GENERIC) {
-         m += n;
-         continue;
-      }
-      if (!(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si))) {
+      if (fp->in[i].sn != TGSI_SEMANTIC_PCOORD &&
+          (fp->in[i].sn != TGSI_SEMANTIC_TEXCOORD ||
+           !(nv50->rast->pipe.sprite_coord_enable & (1 << fp->in[i].si)))) {
          m += n;
          continue;
       }
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 7a0470c..117d3d1 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -494,7 +494,7 @@ nv50_blitter_make_vp(struct nv50_blitter *blit)
    blit->vp.out[1].hw = 2;
    blit->vp.out[1].mask = 0x7;
    blit->vp.out[1].sn = TGSI_SEMANTIC_GENERIC;
-   blit->vp.out[1].si = 8;
+   blit->vp.out[1].si = 0;
    blit->vp.vp.attrs[0] = 0x73;
    blit->vp.vp.psiz = 0x40;
    blit->vp.vp.edgeflag = 0x40;
@@ -536,9 +536,8 @@ nv50_blitter_make_fp(struct pipe_context *pipe,
       return NULL;
 
    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
-   /* NOTE: use GENERIC[8] so we don't use the TEXCOORD slots on nvc0 */
    tc = ureg_DECL_fs_input(
-      ureg, TGSI_SEMANTIC_GENERIC, 8, TGSI_INTERPOLATE_LINEAR);
+      ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR);
 
    data = ureg_DECL_temporary(ureg);
 
diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index 2f4eae8..2f1b417 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -27,33 +27,6 @@
 #include "nv50/codegen/nv50_ir_driver.h"
 #include "nve4_compute.h"
 
-/* If only they told use the actual semantic instead of just GENERIC ... */
-static void
-nvc0_mesa_varying_hack(struct nv50_ir_varying *var)
-{
-   unsigned c;
-
-   if (var->sn != TGSI_SEMANTIC_GENERIC)
-      return;
-
-   if (var->si <= 7) /* gl_TexCoord */
-      for (c = 0; c < 4; ++c)
-         var->slot[c] = (0x300 + var->si * 0x10 + c * 0x4) / 4;
-   else
-   if (var->si == 9) /* gl_PointCoord */
-      for (c = 0; c < 4; ++c)
-         var->slot[c] = (0x2e0 + c * 0x4) / 4;
-   else
-   if (var->si <= 39)
-      for (c = 0; c < 4; ++c) /* move down user varyings (first has index 8) */
-         var->slot[c] -= 0x80 / 4;
-   else {
-      NOUVEAU_ERR("too many varyings / invalid location: %u !\n", var->si);
-      for (c = 0; c < 4; ++c)
-         var->slot[c] = (0x270 + c * 0x4) / 4; /* catch invalid indices */
-   }
-}
-
 static uint32_t
 nvc0_shader_input_address(unsigned sn, unsigned si, unsigned ubase)
 {
@@ -69,11 +42,11 @@ nvc0_shader_input_address(unsigned sn, unsigned si, unsigned ubase)
    case NV50_SEMANTIC_CLIPDISTANCE: return 0x2c0 + si * 0x4;
    case TGSI_SEMANTIC_CLIPDIST:     return 0x2c0 + si * 0x10;
    case TGSI_SEMANTIC_CLIPVERTEX:   return 0x260;
-   case NV50_SEMANTIC_POINTCOORD:   return 0x2e0;
+   case TGSI_SEMANTIC_PCOORD:       return 0x2e0;
    case NV50_SEMANTIC_TESSCOORD:    return 0x2f0;
    case TGSI_SEMANTIC_INSTANCEID:   return 0x2f8;
    case TGSI_SEMANTIC_VERTEXID:     return 0x2fc;
-   case NV50_SEMANTIC_TEXCOORD:     return 0x300 + si * 0x10;
+   case TGSI_SEMANTIC_TEXCOORD:     return 0x300 + si * 0x10;
    case TGSI_SEMANTIC_FACE:         return 0x3fc;
    case NV50_SEMANTIC_INVOCATIONID: return ~0;
    default:
@@ -99,7 +72,7 @@ nvc0_shader_output_address(unsigned sn, unsigned si, unsigned ubase)
    case NV50_SEMANTIC_CLIPDISTANCE:  return 0x2c0 + si * 0x4;
    case TGSI_SEMANTIC_CLIPDIST:      return 0x2c0 + si * 0x10;
    case TGSI_SEMANTIC_CLIPVERTEX:    return 0x260;
-   case NV50_SEMANTIC_TEXCOORD:      return 0x300 + si * 0x10;
+   case TGSI_SEMANTIC_TEXCOORD:      return 0x300 + si * 0x10;
    case TGSI_SEMANTIC_EDGEFLAG:      return ~0;
    default:
       assert(!"invalid TGSI output semantic");
@@ -149,8 +122,6 @@ nvc0_sp_assign_input_slots(struct nv50_ir_prog_info *info)
 
       for (c = 0; c < 4; ++c)
          info->in[i].slot[c] = (offset + c * 0x4) / 4;
-
-      nvc0_mesa_varying_hack(&info->in[i]);
    }
 
    return 0;
@@ -194,8 +165,6 @@ nvc0_sp_assign_output_slots(struct nv50_ir_prog_info *info)
 
       for (c = 0; c < 4; ++c)
          info->out[i].slot[c] = (offset + c * 0x4) / 4;
-
-      nvc0_mesa_varying_hack(&info->out[i]);
    }
 
    return 0;
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 6e1b4e4..80bff8c 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -59,6 +59,8 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
                 break;
 
             case TGSI_SEMANTIC_GENERIC:
+		index += ATTR_TEXCOORD_COUNT;
+            case TGSI_SEMANTIC_TEXCOORD:
                 assert(index < ATTR_GENERIC_COUNT);
                 fs_inputs->generic[index] = i;
                 break;
diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h
index b756048..5a2eacb 100644
--- a/src/gallium/drivers/r300/r300_shader_semantics.h
+++ b/src/gallium/drivers/r300/r300_shader_semantics.h
@@ -25,7 +25,8 @@
 
 #define ATTR_UNUSED             (-1)
 #define ATTR_COLOR_COUNT        2
-#define ATTR_GENERIC_COUNT      32
+#define ATTR_TEXCOORD_COUNT     TGSI_MAX_TEXCOORDS
+#define ATTR_GENERIC_COUNT      32 /* includes TEXCOORDs */
 
 /* This structure contains information about what attributes are written by VS
  * or read by FS. (but not both) It's much easier to work with than
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 33612a3..5cab47f 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -70,6 +70,8 @@ static void r300_shader_read_vs_outputs(
                 break;
 
             case TGSI_SEMANTIC_GENERIC:
+                index += ATTR_TEXCOORD_COUNT;
+            case TGSI_SEMANTIC_TEXCOORD:
                 assert(index < ATTR_GENERIC_COUNT);
                 vs_outputs->generic[index] = i;
                 vs_outputs->num_generic++;
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 2bdefb0..d0148af 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -940,7 +940,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
 	}
 
 	spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
-	if (state->sprite_coord_enable) {
+	if (state->point_quad_rasterization) {
 		spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
 			      S_0286D4_PNT_SPRITE_OVRD_X(2) |
 			      S_0286D4_PNT_SPRITE_OVRD_Y(3) |
@@ -3295,8 +3295,9 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
 				tmp |= S_028644_FLAT_SHADE(1);
 			}
 
-			if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-			    (sprite_coord_enable & (1 << rshader->input[i].sid))) {
+			if (rshader->input[i].name == TGSI_SEMANTIC_PCOORD &&
+			    (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
+			     (sprite_coord_enable & (1 << rshader->input[i].sid)))) {
 				tmp |= S_028644_PT_SPRITE_TEX(1);
 			}
 
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 29facf7..7788674 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -806,7 +806,8 @@ static int r600_spi_sid(struct r600_shader_io * io)
 		name == TGSI_SEMANTIC_FACE)
 		index = 0;
 	else {
-		if (name == TGSI_SEMANTIC_GENERIC) {
+		if (name == TGSI_SEMANTIC_TEXCOORD ||
+		    name == TGSI_SEMANTIC_GENERIC) {
 			/* For generic params simply use sid from tgsi */
 			index = io->sid;
 		} else {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 846c159..63e5373 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -935,7 +935,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx,
 	}
 
 	spi_interp = S_0286D4_FLAT_SHADE_ENA(1);
-	if (state->sprite_coord_enable) {
+	if (state->point_quad_rasterization) {
 		spi_interp |= S_0286D4_PNT_SPRITE_ENA(1) |
 			      S_0286D4_PNT_SPRITE_OVRD_X(2) |
 			      S_0286D4_PNT_SPRITE_OVRD_Y(3) |
@@ -2722,8 +2722,9 @@ void r600_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
 				rctx->rasterizer && rctx->rasterizer->flatshade))
 			tmp |= S_028644_FLAT_SHADE(1);
 
-		if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC &&
-		    sprite_coord_enable & (1 << rshader->input[i].sid)) {
+		if (rshader->input[i].name == TGSI_SEMANTIC_PCOORD ||
+		    (rshader->input[i].name == TGSI_SEMANTIC_TEXCOORD &&
+                     sprite_coord_enable & (1 << rshader->input[i].sid))) {
 			tmp |= S_028644_PT_SPRITE_TEX(1);
 		}
 
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 95ccd1e..69396d9 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -591,6 +591,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 					color_count++;
 				}
 				break;
+			case TGSI_SEMANTIC_TEXCOORD:
 			case TGSI_SEMANTIC_FOG:
 			case TGSI_SEMANTIC_GENERIC:
 				target = V_008DFC_SQ_EXP_PARAM + param_count;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index a395ec4..d84ac81 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -422,7 +422,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
 	rs->offset_scale = state->offset_scale * 12.0f;
 
 	tmp = S_0286D4_FLAT_SHADE_ENA(1);
-	if (state->sprite_coord_enable) {
+	if (state->point_quad_rasterization) {
 		tmp |= S_0286D4_PNT_SPRITE_ENA(1) |
 			S_0286D4_PNT_SPRITE_OVRD_X(V_0286D4_SPI_PNT_SPRITE_SEL_S) |
 			S_0286D4_PNT_SPRITE_OVRD_Y(V_0286D4_SPI_PNT_SPRITE_SEL_T) |
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 1049d2b..37ceb10 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -332,8 +332,9 @@ bcolor:
 			tmp |= S_028644_FLAT_SHADE(1);
 		}
 
-		if (name == TGSI_SEMANTIC_GENERIC &&
-		    rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
+		if (name == TGSI_SEMANTIC_PCOORD ||
+		    (name == TGSI_SEMANTIC_GENERIC &&
+		     rctx->sprite_coord_enable & (1 << ps->input[i].sid))) {
 			tmp |= S_028644_PT_SPRITE_TEX(1);
 		}
 
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index a9fb6aa..86061b4 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -149,21 +149,27 @@ struct tgsi_declaration_interp
 #define TGSI_SEMANTIC_BCOLOR     2  /**< back-face color */
 #define TGSI_SEMANTIC_FOG        3
 #define TGSI_SEMANTIC_PSIZE      4
-#define TGSI_SEMANTIC_GENERIC    5
-#define TGSI_SEMANTIC_NORMAL     6
-#define TGSI_SEMANTIC_FACE       7
-#define TGSI_SEMANTIC_EDGEFLAG   8
-#define TGSI_SEMANTIC_PRIMID     9
-#define TGSI_SEMANTIC_INSTANCEID 10
-#define TGSI_SEMANTIC_VERTEXID   11
-#define TGSI_SEMANTIC_STENCIL    12
-#define TGSI_SEMANTIC_CLIPDIST   13
-#define TGSI_SEMANTIC_CLIPVERTEX 14
-#define TGSI_SEMANTIC_GRID_SIZE  15 /**< grid size in blocks */
-#define TGSI_SEMANTIC_BLOCK_ID   16 /**< id of the current block */
-#define TGSI_SEMANTIC_BLOCK_SIZE 17 /**< block size in threads */
-#define TGSI_SEMANTIC_THREAD_ID  18 /**< block-relative id of the current thread */
-#define TGSI_SEMANTIC_COUNT      19 /**< number of semantic values */
+#define TGSI_SEMANTIC_PCOORD     5  /**< sprite coordinates */
+#define TGSI_SEMANTIC_TEXCOORD   6  /**< texture or sprite coordinates */
+#define TGSI_SEMANTIC_GENERIC    7
+#define TGSI_SEMANTIC_NORMAL     8
+#define TGSI_SEMANTIC_FACE       9
+#define TGSI_SEMANTIC_EDGEFLAG   10
+#define TGSI_SEMANTIC_PRIMID     11
+#define TGSI_SEMANTIC_INSTANCEID 12
+#define TGSI_SEMANTIC_VERTEXID   13
+#define TGSI_SEMANTIC_STENCIL    14
+#define TGSI_SEMANTIC_CLIPDIST   15
+#define TGSI_SEMANTIC_CLIPVERTEX 16
+#define TGSI_SEMANTIC_GRID_SIZE  17 /**< grid size in blocks */
+#define TGSI_SEMANTIC_BLOCK_ID   18 /**< id of the current block */
+#define TGSI_SEMANTIC_BLOCK_SIZE 19 /**< block size in threads */
+#define TGSI_SEMANTIC_THREAD_ID  20 /**< block-relative id of the current thread */
+#define TGSI_SEMANTIC_COUNT      21 /**< number of semantic values */
+
+/* Semantic index limits:
+ */
+#define TGSI_MAX_TEXCOORDS 8
 
 struct tgsi_declaration_semantic
 {
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index ab49cab..967461f 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -145,7 +145,7 @@ struct pipe_rasterizer_state
    unsigned line_stipple_factor:8;  /**< [1..256] actually */
    unsigned line_stipple_pattern:16;
 
-   unsigned sprite_coord_enable; /* bitfield referring to 32 GENERIC inputs */
+   uint8_t sprite_coord_enable; /* referring to 8 TEXCOORD inputs */
 
    float line_width;
    float point_size;           /**< used when no per-vertex size */
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 0e2a152..0030df0 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -163,7 +163,7 @@ static void update_raster_state( struct st_context *st )
          raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT;
 
       /* Coord replacement flags.  If bit 'k' is set that means
-       * that we need to replace GENERIC[k] attrib with an automatically
+       * that we need to replace TEXCOORD[k] attrib with an automatically
        * computed texture coord.
        */
       for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) {
@@ -171,10 +171,6 @@ static void update_raster_state( struct st_context *st )
             raster->sprite_coord_enable |= 1 << i;
          }
       }
-      if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) {
-         raster->sprite_coord_enable |=
-            1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0);
-      }
 
       raster->point_quad_rasterization = 1;
    }
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index f56f7cb..5c69670 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -574,22 +574,15 @@ st_translate_fragment_program(struct st_context *st,
             input_semantic_index[slot] = 1;
             interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
             break;
-            /* In most cases, there is nothing special about these
-             * inputs, so adopt a convention to use the generic
-             * semantic name and the mesa FRAG_ATTRIB_ number as the
-             * index.
-             *
-             * All that is required is that the vertex shader labels
-             * its own outputs similarly, and that the vertex shader
-             * generates at least every output required by the
-             * fragment shader plus fixed-function hardware (such as
-             * BFC).
-             *
-             * There is no requirement that semantic indexes start at
-             * zero or be restricted to a particular range -- nobody
-             * should be building tables based on semantic index.
-             */
          case FRAG_ATTRIB_PNTC:
+            input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD;
+            input_semantic_index[slot] = 0;
+            interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+            break;
+            /* Semantic indices for TGSI_SEMANTIC_TEXCOORD are limited to [0,7],
+             * which is also the size of the bitfield to enable replacement with
+             * sprite coordinates.
+             */
          case FRAG_ATTRIB_TEX0:
          case FRAG_ATTRIB_TEX1:
          case FRAG_ATTRIB_TEX2:
@@ -598,19 +591,24 @@ st_translate_fragment_program(struct st_context *st,
          case FRAG_ATTRIB_TEX5:
          case FRAG_ATTRIB_TEX6:
          case FRAG_ATTRIB_TEX7:
+            input_semantic_index[slot] = attr - FRAG_ATTRIB_TEX0;
+            input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
+            interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
+                                                   FALSE);
+            break;
+            /* Semantic indices should start at 0 because drivers may assign
+             * fixed slots based on semantic index.
+             * This is useful because ARB_separate_shader_objects uses location
+             * qualifiers for linkage, and the semantic index should correspond
+             * to these locations, and linkage passes become unncessary.
+             */
          case FRAG_ATTRIB_VAR0:
          default:
-            /* Actually, let's try and zero-base this just for
-             * readability of the generated TGSI.
-             */
-            assert(attr >= FRAG_ATTRIB_TEX0);
-            input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0);
+            assert(attr >= FRAG_ATTRIB_VAR0);
+            input_semantic_index[slot] = (attr - FRAG_ATTRIB_VAR0);
             input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            if (attr == FRAG_ATTRIB_PNTC)
-               interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
-            else
-               interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
-                                                      FALSE);
+            interpMode[slot] = st_translate_interp(stfp->Base.InterpQualifier[attr],
+                                                   FALSE);
             break;
          }
       }
-- 
1.7.3.4



More information about the mesa-dev mailing list