[Mesa-dev] [PATCH 1/2] tgsi: add support for texture offsets to the TGSI IR.

Brian Paul brian.e.paul at gmail.com
Tue Aug 30 07:43:10 PDT 2011


On Mon, Aug 29, 2011 at 7:38 AM, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This adds tokens for texture offsets, to store 4 * swizzled vec 3
> for use in TXF and other opcodes.
>
> It also contains TGSI exec changes for softpipe to use this code,
> along with GLSL->TGSI support for TXF.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>  src/gallium/auxiliary/tgsi/tgsi_build.c      |   64 ++++++++++++++++++++++++-
>  src/gallium/auxiliary/tgsi/tgsi_dump.c       |   11 ++++
>  src/gallium/auxiliary/tgsi/tgsi_exec.c       |   22 ++++++++-
>  src/gallium/auxiliary/tgsi/tgsi_exec.h       |    3 +-
>  src/gallium/auxiliary/tgsi/tgsi_parse.c      |    3 +
>  src/gallium/auxiliary/tgsi/tgsi_parse.h      |    2 +
>  src/gallium/auxiliary/tgsi/tgsi_ureg.c       |   24 +++++++++-
>  src/gallium/auxiliary/tgsi/tgsi_ureg.h       |   12 ++++-
>  src/gallium/docs/source/tgsi.rst             |   13 ++++-
>  src/gallium/drivers/softpipe/sp_tex_sample.c |   17 +++++--
>  src/gallium/include/pipe/p_shader_tokens.h   |   11 ++++-
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp   |   47 ++++++++++++++++++-
>  src/mesa/state_tracker/st_mesa_to_tgsi.c     |    1 +
>  13 files changed, 208 insertions(+), 22 deletions(-)
>
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
> index 269940e..56491c9 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_build.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
> @@ -631,7 +631,7 @@ tgsi_default_instruction_texture( void )
>    struct tgsi_instruction_texture instruction_texture;
>
>    instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
> -   instruction_texture.Padding = 0;
> +   instruction_texture.NumOffsets = 0;
>
>    return instruction_texture;
>  }
> @@ -639,6 +639,7 @@ tgsi_default_instruction_texture( void )
>  static struct tgsi_instruction_texture
>  tgsi_build_instruction_texture(
>    unsigned texture,
> +   unsigned num_offsets,
>    struct tgsi_token *prev_token,
>    struct tgsi_instruction *instruction,
>    struct tgsi_header *header )
> @@ -646,7 +647,7 @@ tgsi_build_instruction_texture(
>    struct tgsi_instruction_texture instruction_texture;
>
>    instruction_texture.Texture = texture;
> -   instruction_texture.Padding = 0;
> +   instruction_texture.NumOffsets = num_offsets;
>    instruction->Texture = 1;
>
>    instruction_grow( instruction, header );
> @@ -654,6 +655,41 @@ tgsi_build_instruction_texture(
>    return instruction_texture;
>  }
>
> +
> +static struct tgsi_texture_offset
> +tgsi_default_texture_offset( void )
> +{
> +   struct tgsi_texture_offset instruction_texture_offset;
> +
> +   instruction_texture_offset.Index = 0;
> +   instruction_texture_offset.File = 0;
> +   instruction_texture_offset.SwizzleX = 0;
> +   instruction_texture_offset.SwizzleY = 0;
> +   instruction_texture_offset.SwizzleZ = 0;
> +
> +   return instruction_texture_offset;
> +}
> +
> +static struct tgsi_texture_offset
> +tgsi_build_texture_offset(
> +   int index, int file, int swizzle_x, int swizzle_y, int swizzle_z,
> +   struct tgsi_token *prev_token,
> +   struct tgsi_instruction *instruction,
> +   struct tgsi_header *header )
> +{
> +   struct tgsi_texture_offset texture_offset;
> +
> +   texture_offset.Index = index;
> +   texture_offset.File = file;
> +   texture_offset.SwizzleX = swizzle_x;
> +   texture_offset.SwizzleY = swizzle_y;
> +   texture_offset.SwizzleZ = swizzle_z;
> +
> +   instruction_grow( instruction, header );
> +
> +   return texture_offset;
> +}
> +
>  static struct tgsi_src_register
>  tgsi_default_src_register( void )
>  {
> @@ -825,6 +861,9 @@ tgsi_default_full_instruction( void )
>    full_instruction.Predicate = tgsi_default_instruction_predicate();
>    full_instruction.Label = tgsi_default_instruction_label();
>    full_instruction.Texture = tgsi_default_instruction_texture();
> +   for( i = 0;  i < TGSI_FULL_MAX_TEX_OFFSETS; i++ ) {
> +      full_instruction.TexOffsets[i] = tgsi_default_texture_offset();
> +   }
>    for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
>       full_instruction.Dst[i] = tgsi_default_full_dst_register();
>    }
> @@ -908,12 +947,31 @@ tgsi_build_full_instruction(
>
>       *instruction_texture = tgsi_build_instruction_texture(
>          full_inst->Texture.Texture,
> +        full_inst->Texture.NumOffsets,
>          prev_token,
>          instruction,
>          header   );
>       prev_token = (struct tgsi_token  *) instruction_texture;
> -   }
>
> +      for (i = 0; i < full_inst->Texture.NumOffsets; i++) {
> +         struct tgsi_texture_offset *texture_offset;
> +
> +         if ( maxsize <= size )
> +            return 0;
> +        texture_offset = (struct tgsi_texture_offset *)&tokens[size];
> +         size++;
> +         *texture_offset = tgsi_build_texture_offset(
> +            full_inst->TexOffsets[i].Index,
> +            full_inst->TexOffsets[i].File,
> +            full_inst->TexOffsets[i].SwizzleX,
> +            full_inst->TexOffsets[i].SwizzleY,
> +            full_inst->TexOffsets[i].SwizzleZ,
> +            prev_token,
> +            instruction,
> +            header);
> +         prev_token = (struct tgsi_token *) texture_offset;
> +      }
> +   }
>    for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
>       const struct tgsi_full_dst_register *reg = &full_inst->Dst[i];
>       struct tgsi_dst_register *dst_register;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> index c126620..7e2825e 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> @@ -693,6 +693,17 @@ iter_instruction(
>    if (inst->Instruction.Texture) {
>       TXT( ", " );
>       ENM( inst->Texture.Texture, tgsi_texture_names );
> +      for (i = 0; i < inst->Texture.NumOffsets; i++) {
> +         TXT( ", " );
> +         ENM( inst->TexOffsets[i].File, tgsi_file_names);
> +         CHR( '[' );
> +         SID( inst->TexOffsets[i].Index );
> +         CHR( ']' );
> +         CHR( '.' );
> +         ENM( inst->TexOffsets[i].SwizzleX, tgsi_swizzle_names);
> +         ENM( inst->TexOffsets[i].SwizzleY, tgsi_swizzle_names);
> +         ENM( inst->TexOffsets[i].SwizzleZ, tgsi_swizzle_names);
> +      }
>    }
>
>    switch (inst->Instruction.Opcode) {
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 38dc1ef..fd118c5 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -1929,11 +1929,28 @@ exec_txf(struct tgsi_exec_machine *mach,
>         const struct tgsi_full_instruction *inst)
>  {
>    struct tgsi_sampler *sampler;
> -   const uint unit = inst->Src[1].Register.Index;
> +   const uint unit = inst->Src[2].Register.Index;
>    union tgsi_exec_channel r[4];
> +   union tgsi_exec_channel offset[3];
>    uint chan;
>    float rgba[NUM_CHANNELS][QUAD_SIZE];
>    int j;
> +   int8_t offsets[3];
> +
> +   if (inst->Texture.NumOffsets == 1) {
> +      union tgsi_exec_channel index;
> +      index.i[0] = index.i[1] = index.i[2] = index.i[3] = inst->TexOffsets[0].Index;
> +      fetch_src_file_channel(mach, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleX, &index, &ZeroVec, &offset[0]);
> +      fetch_src_file_channel(mach, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleY, &index, &ZeroVec, &offset[1]);
> +      fetch_src_file_channel(mach, inst->TexOffsets[0].File,
> +                             inst->TexOffsets[0].SwizzleZ, &index, &ZeroVec, &offset[2]);
> +     offsets[0] = offset[0].i[0];
> +     offsets[1] = offset[1].i[0];
> +     offsets[2] = offset[2].i[0];
> +   } else
> +     offsets[0] = offsets[1] = offsets[2] = 0;
>
>    IFETCH(&r[3], 0, CHAN_W);
>
> @@ -1959,7 +1976,8 @@ exec_txf(struct tgsi_exec_machine *mach,
>    }
>
>    sampler = mach->Samplers[unit];
> -   sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i, rgba);
> +   sampler->get_texel(sampler, r[0].i, r[1].i, r[2].i, r[3].i,
> +                     offsets, rgba);
>
>    for (j = 0; j < QUAD_SIZE; j++) {
>       r[0].f[j] = rgba[0][j];
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> index 3f6964c..a750715 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> @@ -94,7 +94,8 @@ struct tgsi_sampler
>                    int dims[4]);
>    void (*get_texel)(struct tgsi_sampler *sampler, const int i[QUAD_SIZE],
>                     const int j[QUAD_SIZE], const int k[QUAD_SIZE],
> -                    const int lod[QUAD_SIZE], float rgba[NUM_CHANNELS][QUAD_SIZE]);
> +                    const int lod[QUAD_SIZE], const int8_t offset[3],
> +                    float rgba[NUM_CHANNELS][QUAD_SIZE]);
>  };
>
>  #define TGSI_EXEC_NUM_TEMPS       128
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
> index fb36f9d..e1902eb 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
> @@ -188,6 +188,9 @@ tgsi_parse_token(
>
>       if (inst->Instruction.Texture) {
>          next_token( ctx, &inst->Texture);
> +         for( i = 0; i < inst->Texture.NumOffsets; i++ ) {
> +            next_token( ctx, &inst->TexOffsets[i] );
> +         }
>       }
>
>       assert( inst->Instruction.NumDstRegs <= TGSI_FULL_MAX_DST_REGISTERS );
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
> index b7a3c9b..f7b7e6e 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
> @@ -86,6 +86,7 @@ struct tgsi_full_property
>
>  #define TGSI_FULL_MAX_DST_REGISTERS 2
>  #define TGSI_FULL_MAX_SRC_REGISTERS 5 /* SAMPLE_D has 5 */
> +#define TGSI_FULL_MAX_TEX_OFFSETS 4
>
>  struct tgsi_full_instruction
>  {
> @@ -95,6 +96,7 @@ struct tgsi_full_instruction
>    struct tgsi_instruction_texture     Texture;
>    struct tgsi_full_dst_register       Dst[TGSI_FULL_MAX_DST_REGISTERS];
>    struct tgsi_full_src_register       Src[TGSI_FULL_MAX_SRC_REGISTERS];
> +   struct tgsi_texture_offset          TexOffsets[TGSI_FULL_MAX_TEX_OFFSETS];
>  };
>
>  union tgsi_full_token
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> index a920741..cada435 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
> @@ -54,6 +54,7 @@ union tgsi_any_token {
>    struct tgsi_instruction_predicate insn_predicate;
>    struct tgsi_instruction_label insn_label;
>    struct tgsi_instruction_texture insn_texture;
> +   struct tgsi_texture_offset insn_texture_offset;
>    struct tgsi_src_register src;
>    struct tgsi_dimension dim;
>    struct tgsi_dst_register dst;
> @@ -997,7 +998,7 @@ ureg_fixup_label(struct ureg_program *ureg,
>  void
>  ureg_emit_texture(struct ureg_program *ureg,
>                   unsigned extended_token,
> -                  unsigned target )
> +                  unsigned target, unsigned num_offsets)
>  {
>    union tgsi_any_token *out, *insn;
>
> @@ -1008,6 +1009,20 @@ ureg_emit_texture(struct ureg_program *ureg,
>
>    out[0].value = 0;
>    out[0].insn_texture.Texture = target;
> +   out[0].insn_texture.NumOffsets = num_offsets;
> +}
> +
> +void
> +ureg_emit_texture_offset(struct ureg_program *ureg,
> +                         const struct tgsi_texture_offset *offset)
> +{
> +   union tgsi_any_token *out;
> +
> +   out = get_tokens( ureg, DOMAIN_INSN, 1);
> +
> +   out[0].value = 0;
> +   out[0].insn_texture_offset = *offset;
> +
>  }
>
>
> @@ -1074,6 +1089,8 @@ ureg_tex_insn(struct ureg_program *ureg,
>               const struct ureg_dst *dst,
>               unsigned nr_dst,
>               unsigned target,
> +              const struct tgsi_texture_offset *texoffsets,
> +              unsigned nr_offset,
>               const struct ureg_src *src,
>               unsigned nr_src )
>  {
> @@ -1106,7 +1123,10 @@ ureg_tex_insn(struct ureg_program *ureg,
>                          nr_dst,
>                          nr_src);
>
> -   ureg_emit_texture( ureg, insn.extended_token, target );
> +   ureg_emit_texture( ureg, insn.extended_token, target, nr_offset );
> +
> +   for (i = 0; i < nr_offset; i++)
> +      ureg_emit_texture_offset( ureg, &texoffsets[i]);
>
>    for (i = 0; i < nr_dst; i++)
>       ureg_emit_dst( ureg, dst[i] );
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
> index e3a4915..8f5f22e 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
> @@ -451,6 +451,8 @@ ureg_tex_insn(struct ureg_program *ureg,
>               const struct ureg_dst *dst,
>               unsigned nr_dst,
>               unsigned target,
> +              const struct tgsi_texture_offset *texoffsets,
> +              unsigned nr_offset,
>               const struct ureg_src *src,
>               unsigned nr_src );
>
> @@ -493,7 +495,11 @@ ureg_emit_label(struct ureg_program *ureg,
>  void
>  ureg_emit_texture(struct ureg_program *ureg,
>                   unsigned insn_token,
> -                  unsigned target );
> +                  unsigned target, unsigned num_offsets);
> +
> +void
> +ureg_emit_texture_offset(struct ureg_program *ureg,
> +                         const struct tgsi_texture_offset *offset);
>
>  void
>  ureg_emit_dst( struct ureg_program *ureg,
> @@ -677,7 +683,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
>                          dst.PredSwizzleW,                              \
>                          1,                                             \
>                          2);                                            \
> -   ureg_emit_texture( ureg, insn.extended_token, target );              \
> +   ureg_emit_texture( ureg, insn.extended_token, target, 0 );          \
>    ureg_emit_dst( ureg, dst );                                          \
>    ureg_emit_src( ureg, src0 );                                         \
>    ureg_emit_src( ureg, src1 );                                         \
> @@ -732,7 +738,7 @@ static INLINE void ureg_##op( struct ureg_program *ureg,                \
>                          dst.PredSwizzleW,                              \
>                          1,                                             \
>                          4);                                            \
> -   ureg_emit_texture( ureg, insn.extended_token, target );              \
> +   ureg_emit_texture( ureg, insn.extended_token, target, 0 );          \
>    ureg_emit_dst( ureg, dst );                                          \
>    ureg_emit_src( ureg, src0 );                                         \
>    ureg_emit_src( ureg, src1 );                                         \
> diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
> index 039cb1c..5cf0875 100644
> --- a/src/gallium/docs/source/tgsi.rst
> +++ b/src/gallium/docs/source/tgsi.rst
> @@ -1026,9 +1026,16 @@ XXX so let's discuss it, yeah?
>   dst.w = |src0.w - src1.w| + src2.w
>
>
> -.. opcode:: TXF - Texel Fetch
> -
> -  TBD
> +.. opcode:: TXF - Texel Fetch (as per NV_gpu_shader4), extract a single texel
> +                  from a specified texture image. The source sampler may
> +                 not be a CUBE or SHADOW.
> +                  src 0 is a four-component signed integer vector used to
> +                 identify the single texel accessed. 3 components + level.
> +                 src 1 is a 3 component constant signed integer vector,
> +                 with each component only have a range of
> +                 -8..+8 (hw only seems to deal with this range, interface
> +                 allows for up to unsigned int).
> +                 TXF(uint_vec coord, int_vec offset).
>
>
>  .. opcode:: TXQ - Texture Size Query (as per NV_gpu_program4)
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 89c6536..dd33a10 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -2614,6 +2614,7 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>           const int v_j[QUAD_SIZE],
>           const int v_k[QUAD_SIZE],
>           const int lod[QUAD_SIZE],
> +          const int8_t offset[3],
>           float rgba[NUM_CHANNELS][QUAD_SIZE])
>  {
>    const struct sp_sampler_variant *samp = sp_sampler_variant(tgsi_sampler);
> @@ -2629,7 +2630,7 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>    switch(texture->target) {
>    case PIPE_TEXTURE_1D:
>       for (j = 0; j < QUAD_SIZE; j++) {
> -        tx = get_texel_2d(samp, addr, v_i[j], 0);
> +        tx = get_texel_2d(samp, addr, v_i[j] + offset[0], 0);
>         for (c = 0; c < 4; c++) {
>            rgba[c][j] = tx[c];
>         }
> @@ -2637,7 +2638,8 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>       break;
>    case PIPE_TEXTURE_1D_ARRAY:
>       for (j = 0; j < QUAD_SIZE; j++) {
> -        tx = get_texel_1d_array(samp, addr, v_i[j], v_j[j]);
> +        tx = get_texel_1d_array(samp, addr, v_i[j] + offset[0],
> +                                v_j[j] + offset[1]);
>         for (c = 0; c < 4; c++) {
>            rgba[c][j] = tx[c];
>         }
> @@ -2646,7 +2648,8 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>    case PIPE_TEXTURE_2D:
>    case PIPE_TEXTURE_RECT:
>       for (j = 0; j < QUAD_SIZE; j++) {
> -        tx = get_texel_2d(samp, addr, v_i[j], v_j[j]);
> +        tx = get_texel_2d(samp, addr, v_i[j] + offset[0],
> +                          v_j[j] + offset[1]);
>         for (c = 0; c < 4; c++) {
>            rgba[c][j] = tx[c];
>         }
> @@ -2654,7 +2657,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>       break;
>    case PIPE_TEXTURE_2D_ARRAY:
>       for (j = 0; j < QUAD_SIZE; j++) {
> -        tx = get_texel_2d_array(samp, addr, v_i[j], v_j[j], v_k[j]);
> +        tx = get_texel_2d_array(samp, addr, v_i[j] + offset[0],
> +                                v_j[j] + offset[1],
> +                                v_k[j] + offset[2]);
>         for (c = 0; c < 4; c++) {
>            rgba[c][j] = tx[c];
>         }
> @@ -2662,7 +2667,9 @@ sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>       break;
>    case PIPE_TEXTURE_3D:
>       for (j = 0; j < QUAD_SIZE; j++) {
> -        tx = get_texel_3d(samp, addr, v_i[j], v_j[j], v_k[j]);
> +        tx = get_texel_3d(samp, addr, v_i[j] + offset[0],
> +                          v_j[j] + offset[1],
> +                          v_k[j] + offset[2]);
>         for (c = 0; c < 4; c++) {
>            rgba[c][j] = tx[c];
>         }
> diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
> index d3a3632..e5e7c0b 100644
> --- a/src/gallium/include/pipe/p_shader_tokens.h
> +++ b/src/gallium/include/pipe/p_shader_tokens.h
> @@ -437,7 +437,16 @@ struct tgsi_instruction_label
>  struct tgsi_instruction_texture
>  {
>    unsigned Texture  : 8;    /* TGSI_TEXTURE_ */
> -   unsigned Padding  : 24;
> +   unsigned NumOffsets : 4;
> +};
> +
> +struct tgsi_texture_offset
> +{
> +   int Index:16;
> +   unsigned File : 4;
> +   unsigned SwizzleX : 2;  /* TGSI_SWIZZLE_x */
> +   unsigned SwizzleY : 2;  /* TGSI_SWIZZLE_x */
> +   unsigned SwizzleZ : 2;  /* TGSI_SWIZZLE_x */
>  };
>
>  /*
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 9cac309..c2a94f4 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -80,6 +80,9 @@ extern "C" {
>
>  #define MAX_TEMPS         4096
>
> +/* will be 4 for GLSL 4.00 */
> +#define MAX_GLSL_TEXTURE_OFFSET 1
> +
>  class st_src_reg;
>  class st_dst_reg;
>
> @@ -211,6 +214,8 @@ public:
>    int sampler; /**< sampler index */
>    int tex_target; /**< One of TEXTURE_*_INDEX */
>    GLboolean tex_shadow;
> +   struct tgsi_texture_offset tex_offsets[MAX_GLSL_TEXTURE_OFFSET];
> +   unsigned tex_offset_num_offset;
>    int dead_mask; /**< Used in dead code elimination */
>
>    class function_entry *function; /* Set on TGSI_OPCODE_CAL or TGSI_OPCODE_BGNSUB */
> @@ -2421,7 +2426,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
>  void
>  glsl_to_tgsi_visitor::visit(ir_texture *ir)
>  {
> -   st_src_reg result_src, coord, lod_info, projector, dx, dy;
> +   st_src_reg result_src, coord, lod_info, projector, dx, dy, offset;
>    st_dst_reg result_dst, coord_dst;
>    glsl_to_tgsi_instruction *inst = NULL;
>    unsigned opcode = TGSI_OPCODE_NOP;
> @@ -2480,6 +2485,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>       opcode = TGSI_OPCODE_TXF;
>       ir->lod_info.lod->accept(this);
>       lod_info = this->result;
> +      if (ir->offset) {
> +        ir->offset->accept(this);
> +        offset = this->result;
> +      }
>       break;
>    }
>
> @@ -2555,7 +2564,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>       inst = emit(ir, opcode, result_dst, coord, dx, dy);
>    else if (opcode == TGSI_OPCODE_TXQ)
>       inst = emit(ir, opcode, result_dst, lod_info);
> -   else
> +   else if (opcode == TGSI_OPCODE_TXF) {
> +      inst = emit(ir, opcode, result_dst, coord);
> +   } else
>       inst = emit(ir, opcode, result_dst, coord);
>
>    if (ir->shadow_comparitor)
> @@ -2565,6 +2576,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
>                                                   this->shader_program,
>                                                   this->prog);
>
> +   if (ir->offset) {
> +       inst->tex_offset_num_offset = 1;
> +       inst->tex_offsets[0].Index = offset.index;
> +       inst->tex_offsets[0].File = offset.file;
> +       inst->tex_offsets[0].SwizzleX = GET_SWZ(offset.swizzle, 0);
> +       inst->tex_offsets[0].SwizzleY = GET_SWZ(offset.swizzle, 1);
> +       inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
> +   }
> +
>    const glsl_type *sampler_type = ir->sampler->type;
>
>    switch (sampler_type->sampler_dimensionality) {
> @@ -4246,6 +4266,23 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
>    return src;
>  }
>
> +static struct tgsi_texture_offset
> +translate_tex_offset(struct st_translate *t,
> +                     const struct tgsi_texture_offset *in_offset)
> +{
> +   struct tgsi_texture_offset offset;
> +
> +   assert(in_offset->File == PROGRAM_IMMEDIATE);
> +
> +   offset.File = TGSI_FILE_IMMEDIATE;
> +   offset.Index = in_offset->Index;
> +   offset.SwizzleX = in_offset->SwizzleX;
> +   offset.SwizzleY = in_offset->SwizzleY;
> +   offset.SwizzleZ = in_offset->SwizzleZ;
> +
> +   return offset;
> +}
> +
>  static void
>  compile_tgsi_instruction(struct st_translate *t,
>                          const glsl_to_tgsi_instruction *inst)
> @@ -4254,6 +4291,8 @@ compile_tgsi_instruction(struct st_translate *t,
>    GLuint i;
>    struct ureg_dst dst[1];
>    struct ureg_src src[4];
> +   struct tgsi_texture_offset texoffsets[MAX_GLSL_TEXTURE_OFFSET];
> +
>    unsigned num_dst;
>    unsigned num_src;
>
> @@ -4290,10 +4329,14 @@ compile_tgsi_instruction(struct st_translate *t,
>    case TGSI_OPCODE_TXQ:
>    case TGSI_OPCODE_TXF:
>       src[num_src++] = t->samplers[inst->sampler];
> +      for (i = 0; i < inst->tex_offset_num_offset; i++) {
> +         texoffsets[i] = translate_tex_offset(t, &inst->tex_offsets[i]);
> +      }
>       ureg_tex_insn(ureg,
>                     inst->op,
>                     dst, num_dst,
>                     translate_texture_target(inst->tex_target, inst->tex_shadow),
> +                    texoffsets, inst->tex_offset_num_offset,
>                     src, num_src);
>       return;
>
> diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
> index 656c985..f4263c6 100644
> --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
> +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
> @@ -705,6 +705,7 @@ compile_instruction(
>                      dst, num_dst,
>                      translate_texture_target( inst->TexSrcTarget,
>                                                inst->TexShadow ),
> +                     NULL, 0,
>                      src, num_src );
>       return;
>
> --
> 1.7.6

Extending TSGI is a bit of a black art but you seem to have figured it out.

I'm looking at the swizzle fields in tgsi_texture_offset.  Why do
those exist?  I'm guessing it's just for the case that a bunch of
offsets get tightly packed in a constant slot.  0, 1, -1 would seem to
be very common offsets so a whole bunch of offsets might be encoded in
a single constant vector.  If that's the intention, some comments
explaining this would be good.

Also, I thought that the offsets had to be compile-time constants so
tgsi_texture_offset::File would always be PROGRAM_IMMEDIATE.  If
that's true, why have the File field?

-Brian


More information about the mesa-dev mailing list