tgsi: add support for texture offsets to the TGSI IR. (v2)
authorDave Airlie <airlied@redhat.com>
Fri, 26 Aug 2011 09:59:18 +0000 (10:59 +0100)
committerDave Airlie <airlied@redhat.com>
Fri, 2 Sep 2011 09:47:45 +0000 (10:47 +0100)
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.

v2: add some more comments, add back padding I removed.

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
13 files changed:
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/auxiliary/tgsi/tgsi_parse.c
src/gallium/auxiliary/tgsi/tgsi_parse.h
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/gallium/docs/source/tgsi.rst
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/include/pipe/p_shader_tokens.h
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_mesa_to_tgsi.c

index 269940ec840784bb351f02a36451aa1a9a1d686e..6ec2b0d8f216207f7a7d80dcae81ff8daa02da52 100644 (file)
@@ -631,6 +631,7 @@ tgsi_default_instruction_texture( void )
    struct tgsi_instruction_texture instruction_texture;
 
    instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN;
+   instruction_texture.NumOffsets = 0;
    instruction_texture.Padding = 0;
 
    return instruction_texture;
@@ -639,6 +640,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,6 +648,7 @@ tgsi_build_instruction_texture(
    struct tgsi_instruction_texture instruction_texture;
 
    instruction_texture.Texture = texture;
+   instruction_texture.NumOffsets = num_offsets;
    instruction_texture.Padding = 0;
    instruction->Texture = 1;
 
@@ -654,6 +657,43 @@ tgsi_build_instruction_texture(
    return instruction_texture;
 }
 
+
+static struct tgsi_texture_offset
+tgsi_default_texture_offset( void )
+{
+   struct tgsi_texture_offset texture_offset;
+
+   texture_offset.Index = 0;
+   texture_offset.File = 0;
+   texture_offset.SwizzleX = 0;
+   texture_offset.SwizzleY = 0;
+   texture_offset.SwizzleZ = 0;
+   texture_offset.Padding = 0;
+
+   return 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;
+   texture_offset.Padding = 0;
+
+   instruction_grow( instruction, header );
+
+   return texture_offset;
+}
+
 static struct tgsi_src_register
 tgsi_default_src_register( void )
 {
@@ -825,6 +865,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 +951,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;
index c12662076b1bf069ad30a3ee25874e60a4276640..7e2825e9ce1d7e79c254b7ff58ca5da24c310dd5 100644 (file)
@@ -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) {
index 38dc1efa5512051b86492f2aa7246e5bb019bc5e..fd118c5bb118c6ce347b5f3738e960aa61385c1e 100644 (file)
@@ -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];
index 3f6964c17fb5611db42fbb1ca85719d2ffc32ef2..a750715790621286f369dc3a620046e26885ae54 100644 (file)
@@ -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
index fb36f9de32dcd06b0c883b41c78535dcf5796d10..e1902eb1862570f122fbba3673b3fe8c50c21b73 100644 (file)
@@ -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 );
index b7a3c9bc0e600132649085d50286bf894049ffe8..f7b7e6edc98f4a5eca26888a35d634b83324161e 100644 (file)
@@ -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
index a920741c36bbca1321ac239952636c60ce8850ec..cada435aee7fc7608e063c623452c00851e45e0f 100644 (file)
@@ -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] );
index e3a4915d03c3df6c0d713dc1a0f7441b3a1d3784..8f5f22e175023dc7006ae3bf44753474e80c7043 100644 (file)
@@ -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 );                                         \
index 039cb1c03d555c779e444b250a3d1b1b657a41c1..5cf08752e752d46728db5922f8305229048442a8 100644 (file)
@@ -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)
index 89c6536b1f475d3a6b34d36bf50b93bc27f36d31..dd33a10a1a6d283154b00f8dc3f6038730d54a78 100644 (file)
@@ -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];
         }
index d3a3632654c15fdd657b961dd3a5088155c7744f..72d3139562e1f6b26b096298ef39d4f19bcc346c 100644 (file)
@@ -401,6 +401,8 @@ struct tgsi_instruction
  * If tgsi_instruction::Label is TRUE, tgsi_instruction_label follows.
  *
  * If tgsi_instruction::Texture is TRUE, tgsi_instruction_texture follows.
+ *   if texture instruction has a number of offsets,
+ *   then tgsi_instruction::Texture::NumOffset of tgsi_texture_offset follow.
  * 
  * Then, tgsi_instruction::NumDstRegs of tgsi_dst_register follow.
  * 
@@ -437,7 +439,23 @@ struct tgsi_instruction_label
 struct tgsi_instruction_texture
 {
    unsigned Texture  : 8;    /* TGSI_TEXTURE_ */
-   unsigned Padding  : 24;
+   unsigned NumOffsets : 4;
+   unsigned Padding : 20;
+};
+
+/* for texture offsets in GLSL and DirectX.
+ * Generally these always come from TGSI_FILE_IMMEDIATE,
+ * however DX11 appears to have the capability to do
+ * non-constant texture offsets.
+ */
+struct tgsi_texture_offset
+{
+   int      Index    : 16;
+   unsigned File     : 4;  /**< one of TGSI_FILE_x */
+   unsigned SwizzleX : 2;  /* TGSI_SWIZZLE_x */
+   unsigned SwizzleY : 2;  /* TGSI_SWIZZLE_x */
+   unsigned SwizzleZ : 2;  /* TGSI_SWIZZLE_x */
+   unsigned Padding  : 6;
 };
 
 /*
index e2857edf390517485cf7987071bcbc4587c6a38b..31750686e9825182f2d5efdb0fb6623def23c58d 100644 (file)
@@ -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) {
@@ -4216,6 +4236,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)
@@ -4224,6 +4261,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;
 
@@ -4260,10 +4299,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;
 
index 656c985d78ffd00d77b22d1ff94a9924beff3845..f4263c64c3dadf2ed900567bb3579bd23238fa8c 100644 (file)
@@ -705,6 +705,7 @@ compile_instruction(
                      dst, num_dst, 
                      translate_texture_target( inst->TexSrcTarget,
                                                inst->TexShadow ),
+                     NULL, 0,
                      src, num_src );
       return;