gallium: add TGSI_SEMANTIC_TEXCOORD,PCOORD v3
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 15 Mar 2013 21:11:31 +0000 (22:11 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Wed, 20 Mar 2013 11:25:21 +0000 (12:25 +0100)
This makes it possible to identify gl_TexCoord and gl_PointCoord
for drivers where sprite coordinate replacement is restricted.

The new PIPE_CAP_TGSI_TEXCOORD decides whether these varyings
should be hidden behind the GENERIC semantic or not.

With this patch only nvc0 and nv30 will request that they be used.

v2: introduce a CAP so other drivers don't have to bother with
the new semantic

v3: adapt to introduction gl_varying_slot enum

28 files changed:
src/gallium/auxiliary/draw/draw_pipe_wide_point.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_strings.c
src/gallium/docs/source/cso/rasterizer.rst
src/gallium/docs/source/screen.rst
src/gallium/docs/source/tgsi.rst
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/nv30/nv30_screen.c
src/gallium/drivers/nv30/nvfx_fragprog.c
src/gallium/drivers/nv30/nvfx_vertprog.c
src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nvc0/nvc0_program.c
src/gallium/drivers/nvc0/nvc0_screen.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_shader_tokens.h
src/gallium/include/pipe/p_state.h
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_program.c

index 8e0a117843e715ac63cefa38d4e7319f3ab14ef3..0d3fee4bb0d2b9cd0a6310db2a5e2417c47ec980 100644 (file)
@@ -52,6 +52,7 @@
  */
 
 
+#include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -74,6 +75,9 @@ struct widepoint_stage {
    uint num_texcoord_gen;
    uint texcoord_gen_slot[PIPE_MAX_SHADER_OUTPUTS];
 
+   /* TGSI_SEMANTIC to which sprite_coord_enable applies */
+   unsigned sprite_coord_semantic;
+
    int psize_slot;
 };
 
@@ -233,28 +237,29 @@ widepoint_first_point(struct draw_stage *stage,
 
       wide->num_texcoord_gen = 0;
 
-      /* Loop over fragment shader inputs looking for generic inputs
+      /* Loop over fragment shader inputs looking for the PCOORD input or 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 == wide->sprite_coord_semantic) {
+            /* Note that sprite_coord_enable is a bitfield of 32 bits. */
+            if (si >= 32 || !(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;
       }
    }
 
@@ -326,6 +331,11 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw )
    if (!draw_alloc_temp_verts( &wide->stage, 4 ))
       goto fail;
 
+   wide->sprite_coord_semantic =
+      draw->pipe->screen->get_param(draw->pipe->screen, PIPE_CAP_TGSI_TEXCOORD)
+      ?
+      TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
+
    return &wide->stage;
 
  fail:
index d98f6c49366f95d952d173c4bd702723216b496c..365665fa6f789764bb3dea9ec6963148d227de2d 100644 (file)
@@ -305,6 +305,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 );
index 5c92e9a1001d023e8e00043ff41979dce0d1b713..95a5aded819334b93491a53d21918e223bbe912f 100644 (file)
@@ -76,7 +76,9 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] =
    "GRID_SIZE",
    "BLOCK_ID",
    "BLOCK_SIZE",
-   "THREAD_ID"
+   "THREAD_ID",
+   "TEXCOORD",
+   "PCOORD"
 };
 
 const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] =
index f4e24f0b438683b4431600e46e0a10e563f919e6..8338243be9f19a257702e279bb34796de8c025d8 100644 (file)
@@ -159,13 +159,18 @@ Points
 
 sprite_coord_enable
 ^^^^^^^^^^^^^^^^^^^
+The effect of this state depends on PIPE_CAP_TGSI_TEXCOORD !
 
 Controls automatic texture coordinate generation for rendering sprite points.
 
+If PIPE_CAP_TGSI_TEXCOORD is false:
 When bit k in the sprite_coord_enable bitfield is set, then generic
 input k to the fragment shader will get an automatically computed
 texture coordinate.
 
+If PIPE_CAP_TGSI_TEXCOORD is true:
+The bitfield refers to inputs with TEXCOORD semantic instead of generic inputs.
+
 The texture coordinate will be of the form (s, t, 0, 1) where s varies
 from 0 to 1 from left to right while t varies from 0 to 1 according to
 the state of 'sprite_coord_mode' (see below).
index 68d1a35cc7396785fbe40e2747a3a85e67e94ff1..0550a30714a535d93a7e63ce8241747fad68e6df 100644 (file)
@@ -137,6 +137,14 @@ The integer capabilities:
 * ``PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT``: Describes the required
   alignment for pipe_sampler_view::u.buf.first_element, in bytes.
   If a driver does not support first/last_element, it should return 0.
+* ``PIPE_CAP_TGSI_TEXCOORD``: This CAP describes a hw limitation.
+  If true, the hardware cannot replace arbitrary shader inputs with sprite
+  coordinates and hence the inputs that are desired to be replaceable must
+  be declared with TGSI_SEMANTIC_TEXCOORD instead of TGSI_SEMANTIC_GENERIC.
+  The rasterizer's sprite_coord_enable state therefore also applies to the
+  TEXCOORD semantic.
+  Also, TGSI_SEMANTIC_PCOORD becomes available, which labels a fragment shader
+  input that will always be replaced with sprite coordinates.
 
 
 .. _pipe_capf:
index 4c55e60cff0176508429f863199745cd091a2d2a..28308cb948379b267bc4bd640bfaf3b36c45a96c 100644 (file)
@@ -1949,6 +1949,35 @@ When using this semantic, be sure to set the appropriate state in the
 :ref:`rasterizer` first.
 
 
+TGSI_SEMANTIC_TEXCOORD
+""""""""""""""""""""""
+
+Only available if PIPE_CAP_TGSI_TEXCOORD is exposed !
+
+Vertex shader outputs and fragment shader inputs may be labeled with
+this semantic to make them 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.
+
+If the driver does not support TEXCOORD, sprite coordinate replacement
+applies to inputs with the GENERIC semantic instead.
+
+The intended use case for this semantic is gl_TexCoord.
+
+
+TGSI_SEMANTIC_PCOORD
+""""""""""""""""""""
+
+Only available if PIPE_CAP_TGSI_TEXCOORD is exposed !
+
+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.
+
+The intended use case for this semantic is gl_PointCoord.
+
+
 TGSI_SEMANTIC_GENERIC
 """""""""""""""""""""
 
index 5310fc7fdf8b7300bfa233a8364f05abe7a4f32d..5ff132dac72565adf414acf8d2fc1acf2ea4b61e 100644 (file)
@@ -165,6 +165,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TEXTURE_MULTISAMPLE:
        case PIPE_CAP_USER_CONSTANT_BUFFERS:
                return 1;
+       case PIPE_CAP_TGSI_TEXCOORD:
+               return 0;
 
        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
                return 256;
index eb96e9e13b001abadfdcbca4e1ca081f288c1efc..13aa91c29bdfec310c350ff848c0c4f75ca193d0 100644 (file)
@@ -184,6 +184,8 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
    case PIPE_CAP_USER_INDEX_BUFFERS:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
       return 1;
+   case PIPE_CAP_TGSI_TEXCOORD:
+      return 0;
 
    /* Unsupported features (boolean caps). */
    case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
index 93e125da38d99f5125760a3f456018ca1a01c736..5ec1df659b886f30efe7dc12df47bf9bc801e63a 100644 (file)
@@ -208,6 +208,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+   case PIPE_CAP_TGSI_TEXCOORD:
       return 0;
 
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
index 90c367280d4aa87f2ddac9ee4e0fd91ef4add480..e17ee76fbd19d911d34a13c293ae6d3204b63522 100644 (file)
@@ -79,6 +79,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
    case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+   case PIPE_CAP_TGSI_TEXCOORD:
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
    case PIPE_CAP_USER_INDEX_BUFFERS:
       return 1;
index 935804e8e14f8c71c72ea8eefda14d44d6970d1b..4be7dec2c03b1270a7a2513017fa907c340114f6 100644 (file)
@@ -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 be assigned to remaining TC slots later */
+      return TRUE;
    default:
       assert(0);
       return FALSE;
@@ -955,22 +957,24 @@ 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) {
+            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->texcoord[hw] = 0xfffe;
+               fpc->fp->point_sprite_control |= (0x00000100 << hw);
+            } else {
+               fpc->fp->texcoord[hw] = fdec->Semantic.Index + 8;
             }
+            hw = NVFX_FP_OP_INPUT_SRC_TC(hw);
+            fpc->r_input[idx] = nvfx_reg(NVFXSR_INPUT, hw);
+            return TRUE;
          }
          return FALSE;
       }
index 74dba38001cbc6427184c92cc126df7cf8fc84f8..b73d418404569a399f9ae3b350a446540d004b55 100644 (file)
@@ -819,6 +819,7 @@ nvfx_vertprog_parse_decl_output(struct nv30_context *nv30, struct nvfx_vpc *vpc,
 {
    unsigned num_texcoords = nv30->is_nv4x ? 10 : 8;
    unsigned idx = fdec->Range.First;
+   unsigned semantic_index = fdec->Semantic.Index;
    int hw = 0, i;
 
    switch (fdec->Semantic.Name) {
@@ -860,8 +861,12 @@ nvfx_vertprog_parse_decl_output(struct nv30_context *nv30, struct nvfx_vpc *vpc,
       hw = NVFX_VP(INST_DEST_PSZ);
       break;
    case TGSI_SEMANTIC_GENERIC:
+      /* this is really an identifier for VP/FP linkage */
+      semantic_index += 8;
+      /* fall through */
+   case TGSI_SEMANTIC_TEXCOORD:
       for (i = 0; i < num_texcoords; i++) {
-         if (vpc->vp->texcoord[i] == fdec->Semantic.Index) {
+         if (vpc->vp->texcoord[i] == semantic_index) {
             hw = NVFX_VP(INST_DEST_TC(i));
             break;
          }
index c5a5b23c320954bf5e9f5a99c377a6ef90ee2c31..51ed9c1e1ae117c57fa20ff9728e2f8f0f233c6b 100644 (file)
@@ -70,8 +70,6 @@ struct nv50_ir_varying
 #endif
 
 #define NV50_SEMANTIC_CLIPDISTANCE  (TGSI_SEMANTIC_COUNT + 0)
-#define NV50_SEMANTIC_TEXCOORD      (TGSI_SEMANTIC_COUNT + 1)
-#define NV50_SEMANTIC_POINTCOORD    (TGSI_SEMANTIC_COUNT + 2)
 #define NV50_SEMANTIC_VIEWPORTINDEX (TGSI_SEMANTIC_COUNT + 4)
 #define NV50_SEMANTIC_LAYER         (TGSI_SEMANTIC_COUNT + 5)
 #define NV50_SEMANTIC_INVOCATIONID  (TGSI_SEMANTIC_COUNT + 6)
index aed1dd56eb501868127f759ba8b8a93468ffac65..fb29b2290c241d975b1c2cbf8f4424c5fd7aec94 100644 (file)
@@ -184,6 +184,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
    case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+   case PIPE_CAP_TGSI_TEXCOORD:
    case PIPE_CAP_TEXTURE_MULTISAMPLE:
       return 0;
    default:
index 7a0470c429441a7ffdc7b5a2427ca939786687ef..117d3d1894b69d2cb58816510fc05f17edd61157 100644 (file)
@@ -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);
 
index 2f4eae8f0526c42abd78cb2a27c530b9bc1a9626..2f1b41704a59e76624928d5ffe346b24bbfb94c7 100644 (file)
 #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;
index 7d034797eef67b59e2b49bb92665f5c0445c6f95..e77b819b6513c3c1fe6ef67872912ba7186bd5bf 100644 (file)
@@ -114,6 +114,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TWO_SIDED_STENCIL:
    case PIPE_CAP_DEPTH_CLIP_DISABLE:
    case PIPE_CAP_POINT_SPRITE:
+   case PIPE_CAP_TGSI_TEXCOORD:
       return 1;
    case PIPE_CAP_SM3:
       return 1;
index 06ed1cb5b5bb151fd75860958475bda8a33f6f1e..46fb869cb7285f7566304e606ca0d2200fde1bf0 100644 (file)
@@ -172,6 +172,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
         case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
             return r300screen->caps.has_tcl;
+       case PIPE_CAP_TGSI_TEXCOORD:
+            return 0;
 
         /* Texturing. */
         case PIPE_CAP_MAX_COMBINED_SAMPLERS:
index 60a0247d5dddd25ad719b9c95c39ef63557f773d..9ed88148c4998dda586bf0e04c3791dbef13056f 100644 (file)
@@ -565,6 +565,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
                return 1;
+       case PIPE_CAP_TGSI_TEXCOORD:
+               return 0;
 
         case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
                 return R600_MAP_BUFFER_ALIGNMENT;
index 2abfce476a25c7d002fa61408387daee3847ad92..859843867ce926d3ae787c4f614fd2051a7bfeae 100644 (file)
@@ -330,6 +330,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_START_INSTANCE:
        case PIPE_CAP_NPOT_TEXTURES:
                return 1;
+       case PIPE_CAP_TGSI_TEXCOORD:
+               return 0;
 
         case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
                 return 64;
index 16aba5a630d117d9b8ca96489d46966436bd3d65..937035e5511d461c01e31c6b2861dbc52b40f69d 100644 (file)
@@ -173,6 +173,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
       return 0;
+   case PIPE_CAP_TGSI_TEXCOORD:
+      return 0;
    }
    /* should only get here on unhandled cases */
    debug_printf("Unexpected PIPE_CAP %d query\n", param);
index 3e71ac3c6bf145e54c51e94703df9d6ca58027f7..f0831b9f2fed7d80a23ff68de1ad8d51e2b08abe 100644 (file)
@@ -150,6 +150,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_POINT_SPRITE:
       return 1;
+   case PIPE_CAP_TGSI_TEXCOORD:
+      return 0;
    case PIPE_CAP_MAX_RENDER_TARGETS:
       if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_RENDER_TARGETS, &result))
          return 1;
index fdf6e7fb17bb31e7d58dc5653a357ab54d26335f..7f20b992a138197bcb7b2b7ac7fcf0fbeb3c8d8e 100644 (file)
@@ -498,7 +498,8 @@ enum pipe_cap {
    PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT = 75,
    PIPE_CAP_CUBE_MAP_ARRAY = 76,
    PIPE_CAP_TEXTURE_BUFFER_OBJECTS = 77,
-   PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78
+   PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78,
+   PIPE_CAP_TGSI_TEXCOORD = 79
 };
 
 /**
index 1ca46fd0206a02cccddfecaee5ca2f30277f4b41..478ce25f57cfc926a545d56abbd6a4584e64c037 100644 (file)
@@ -162,7 +162,9 @@ struct tgsi_declaration_interp
 #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_TEXCOORD   19 /**< texture or sprite coordinates */
+#define TGSI_SEMANTIC_PCOORD     20 /**< point sprite coordinate */
+#define TGSI_SEMANTIC_COUNT      21 /**< number of semantic values */
 
 struct tgsi_declaration_semantic
 {
index ab49cabb80098b8587562a0b68ae322315b12d6a..dfafd0bb99f0414adb900d3de13fdee79f080507 100644 (file)
@@ -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 */
+   uint32_t sprite_coord_enable; /* referring to 32 TEXCOORD/GENERIC inputs */
 
    float line_width;
    float point_size;           /**< used when no per-vertex size */
index f9a584ba0ac7cff8ae3fb810a128a55a297ea9c8..e2d074d14a4b99e3a4bbc279a3f496fb4eabe817 100644 (file)
@@ -183,6 +183,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
       screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
    st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
 
+   st->needs_texcoord_semantic =
+      screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
+
    /* GL limits and extensions */
    st_init_limits(st);
    st_init_extensions(st);
index b9a98cd051d4b7aa9d5eaaa073b0d36ad6ed42f4..c6c68adcfb21f9f08f538f2e3a4a475db1608537 100644 (file)
@@ -85,6 +85,8 @@ struct st_context
    boolean has_time_elapsed;
    boolean has_shader_model3;
 
+   boolean needs_texcoord_semantic;
+
    /* On old libGL's for linux we need to invalidate the drawables
     * on glViewpport calls, this is set via a option.
     */
index 6af8df31641d6e7f9b0f4bd96a99c8122ddb09b9..7a38da84ffa4d04afb25ed97e2219f2d4247937a 100644 (file)
@@ -177,6 +177,7 @@ void
 st_prepare_vertex_program(struct gl_context *ctx,
                             struct st_vertex_program *stvp)
 {
+   struct st_context *st = st_context(ctx);
    GLuint attr;
 
    stvp->num_inputs = 0;
@@ -267,7 +268,8 @@ st_prepare_vertex_program(struct gl_context *ctx,
          case VARYING_SLOT_TEX5:
          case VARYING_SLOT_TEX6:
          case VARYING_SLOT_TEX7:
-            stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stvp->output_semantic_name[slot] = st->needs_texcoord_semantic ?
+               TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
             stvp->output_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
             break;
 
@@ -275,10 +277,8 @@ st_prepare_vertex_program(struct gl_context *ctx,
          default:
             assert(attr < VARYING_SLOT_MAX);
             stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
-            stvp->output_semantic_index[slot] = (VARYING_SLOT_VAR0 - 
-                                                VARYING_SLOT_TEX0 +
-                                                attr - 
-                                                VARYING_SLOT_VAR0);
+            stvp->output_semantic_index[slot] = st->needs_texcoord_semantic ?
+               (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0);
             break;
          }
       }
@@ -585,11 +585,18 @@ st_translate_fragment_program(struct st_context *st,
              * 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.
+             * However, some drivers may need us to identify the PNTC and TEXi
+             * varyings if, for example, their capability to replace them with
+             * sprite coordinates is limited.
              */
          case VARYING_SLOT_PNTC:
+            if (st->needs_texcoord_semantic) {
+               input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD;
+               input_semantic_index[slot] = 0;
+               interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+               break;
+            }
+            /* fall through */
          case VARYING_SLOT_TEX0:
          case VARYING_SLOT_TEX1:
          case VARYING_SLOT_TEX2:
@@ -598,13 +605,29 @@ st_translate_fragment_program(struct st_context *st,
          case VARYING_SLOT_TEX5:
          case VARYING_SLOT_TEX6:
          case VARYING_SLOT_TEX7:
+            if (st->needs_texcoord_semantic) {
+               input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
+               input_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
+               interpMode[slot] =
+                  st_translate_interp(stfp->Base.InterpQualifier[attr], FALSE);
+               break;
+            }
+            /* fall through */
          case VARYING_SLOT_VAR0:
          default:
-            /* Actually, let's try and zero-base this just for
-             * readability of the generated TGSI.
+            /* Semantic indices should be zero-based because drivers may choose
+             * to assign a fixed slot determined by that index.
+             * This is useful because ARB_separate_shader_objects uses location
+             * qualifiers for linkage, and if the semantic index corresponds to
+             * these locations, linkage passes in the driver become unecessary.
+             *
+             * If needs_texcoord_semantic is true, no semantic indices will be
+             * consumed for the TEXi varyings, and we can base the locations of
+             * the user varyings on VAR0.  Otherwise, we use TEX0 as base index.
              */
             assert(attr >= VARYING_SLOT_TEX0);
-            input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0);
+            input_semantic_index[slot] = st->needs_texcoord_semantic ?
+               (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0);
             input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
             if (attr == VARYING_SLOT_PNTC)
                interpMode[slot] = TGSI_INTERPOLATE_LINEAR;