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

Christoph Bumiller e0425955 at student.tuwien.ac.at
Tue Mar 19 09:08:48 PDT 2013


On 15.03.2013 22:16, Christoph Bumiller wrote:
> 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

I would push this soon if there are no objections ...

> ---
>  src/gallium/auxiliary/draw/draw_pipe_wide_point.c |   46 +++++++++++++--------
>  src/gallium/auxiliary/tgsi/tgsi_dump.c            |    1 +
>  src/gallium/auxiliary/tgsi/tgsi_strings.c         |    4 +-
>  src/gallium/docs/source/cso/rasterizer.rst        |    5 ++
>  src/gallium/docs/source/screen.rst                |    8 ++++
>  src/gallium/docs/source/tgsi.rst                  |   29 +++++++++++++
>  src/gallium/drivers/freedreno/freedreno_screen.c  |    2 +
>  src/gallium/drivers/i915/i915_screen.c            |    2 +
>  src/gallium/drivers/llvmpipe/lp_screen.c          |    1 +
>  src/gallium/drivers/nv30/nv30_screen.c            |    1 +
>  src/gallium/drivers/nv30/nvfx_fragprog.c          |   42 ++++++++++---------
>  src/gallium/drivers/nv30/nvfx_vertprog.c          |    7 +++-
>  src/gallium/drivers/nv50/codegen/nv50_ir_driver.h |    2 -
>  src/gallium/drivers/nv50/nv50_screen.c            |    1 +
>  src/gallium/drivers/nv50/nv50_surface.c           |    5 +-
>  src/gallium/drivers/nvc0/nvc0_program.c           |   37 +---------------
>  src/gallium/drivers/nvc0/nvc0_screen.c            |    1 +
>  src/gallium/drivers/r300/r300_screen.c            |    2 +
>  src/gallium/drivers/r600/r600_pipe.c              |    2 +
>  src/gallium/drivers/radeonsi/radeonsi_pipe.c      |    2 +
>  src/gallium/drivers/softpipe/sp_screen.c          |    2 +
>  src/gallium/drivers/svga/svga_screen.c            |    2 +
>  src/gallium/include/pipe/p_defines.h              |    3 +-
>  src/gallium/include/pipe/p_shader_tokens.h        |    4 +-
>  src/gallium/include/pipe/p_state.h                |    2 +-
>  src/mesa/state_tracker/st_context.c               |    3 +
>  src/mesa/state_tracker/st_context.h               |    2 +
>  src/mesa/state_tracker/st_program.c               |   45 +++++++++++++++-----
>  28 files changed, 171 insertions(+), 92 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..0d3fee4 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
> @@ -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:
> 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..40062c7 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c
> @@ -78,7 +78,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] =
> diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst
> index f4e24f0..8338243 100644
> --- a/src/gallium/docs/source/cso/rasterizer.rst
> +++ b/src/gallium/docs/source/cso/rasterizer.rst
> @@ -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).
> diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
> index 68d1a35..0550a30 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -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:
> diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
> index d9a7fe9..e5a61bc 100644
> --- a/src/gallium/docs/source/tgsi.rst
> +++ b/src/gallium/docs/source/tgsi.rst
> @@ -1931,6 +1931,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
>  """""""""""""""""""""
>  
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 5310fc7..5ff132d 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -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;
> diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
> index eb96e9e..13aa91c 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -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:
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
> index 93e125d..5ec1df6 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -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:
> diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
> index 90c3672..e17ee76 100644
> --- a/src/gallium/drivers/nv30/nv30_screen.c
> +++ b/src/gallium/drivers/nv30/nv30_screen.c
> @@ -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;
> diff --git a/src/gallium/drivers/nv30/nvfx_fragprog.c b/src/gallium/drivers/nv30/nvfx_fragprog.c
> index 935804e..4be7dec 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 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;
>        }
> diff --git a/src/gallium/drivers/nv30/nvfx_vertprog.c b/src/gallium/drivers/nv30/nvfx_vertprog.c
> index 827d518..24b2412 100644
> --- a/src/gallium/drivers/nv30/nvfx_vertprog.c
> +++ b/src/gallium/drivers/nv30/nvfx_vertprog.c
> @@ -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;
>           }
> diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
> index c5a5b23..51ed9c1 100644
> --- a/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
> +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_driver.h
> @@ -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)
> diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
> index aed1dd5..fb29b22 100644
> --- a/src/gallium/drivers/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nv50/nv50_screen.c
> @@ -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:
> 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/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
> index 7d03479..e77b819 100644
> --- a/src/gallium/drivers/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nvc0/nvc0_screen.c
> @@ -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;
> diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
> index 06ed1cb..46fb869 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -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:
> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
> index 60a0247..9ed8814 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -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;
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> index acf3e2d..53bcac5 100644
> --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> @@ -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;
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
> index 16aba5a..937035e 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -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);
> diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
> index 3e71ac3..f0831b9 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -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;
> diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
> index fdf6e7f..7f20b99 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -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
>  };
>  
>  /**
> diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
> index a9fb6aa..6851dbf 100644
> --- a/src/gallium/include/pipe/p_shader_tokens.h
> +++ b/src/gallium/include/pipe/p_shader_tokens.h
> @@ -163,7 +163,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
>  {
> diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
> index ab49cab..dfafd0b 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 */
> +   uint32_t sprite_coord_enable; /* referring to 32 TEXCOORD/GENERIC inputs */
>  
>     float line_width;
>     float point_size;           /**< used when no per-vertex size */
> diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
> index f9a584b..e2d074d 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -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);
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index b9a98cd..c6c68ad 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -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.
>      */
> diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
> index 6af8df3..7a38da84 100644
> --- a/src/mesa/state_tracker/st_program.c
> +++ b/src/mesa/state_tracker/st_program.c
> @@ -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;



More information about the mesa-dev mailing list