[Mesa-dev] [PATCH] gallium/tgsi: add offset to TXF

Dave Airlie airlied at gmail.com
Fri Aug 26 03:50:08 PDT 2011


From: Dave Airlie <airlied at redhat.com>

In order to implement the GLSL texelFetchOffset I needed to modify TXF
(which wasn't defined anyways). It now corresponds to the NV_gpu_shader4.

I've limited things to a u8, since hw can only do about 4-5 bits, since
that is what DX specifies, TGSI passes stuff in an immediate so its not a
problem there, if we need to change the tgsi_exec/driver interface later
it isn't a major problem.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 src/gallium/auxiliary/tgsi/tgsi_exec.c       |   15 +++++++++++++--
 src/gallium/auxiliary/tgsi/tgsi_exec.h       |    3 ++-
 src/gallium/auxiliary/tgsi/tgsi_info.c       |    2 +-
 src/gallium/docs/source/tgsi.rst             |   13 ++++++++++---
 src/gallium/drivers/softpipe/sp_tex_sample.c |   17 ++++++++++++-----
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp   |   11 +++++++++--
 6 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 38dc1ef..9cb13f4 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1929,11 +1929,21 @@ 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];
+
+   IFETCH(&offset[0], 1, CHAN_X);
+   IFETCH(&offset[1], 1, CHAN_Y);
+   IFETCH(&offset[2], 1, CHAN_Z);
+
+   offsets[0] = offset[0].i[0];
+   offsets[1] = offset[1].i[0];
+   offsets[2] = offset[2].i[0];
 
    IFETCH(&r[3], 0, CHAN_W);
 
@@ -1959,7 +1969,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_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 14ed56a..fa00b2d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -125,7 +125,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
    { 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
    { 1, 2, 0, 0, 0, 0, "XOR", TGSI_OPCODE_XOR },
    { 1, 3, 0, 0, 0, 0, "SAD", TGSI_OPCODE_SAD },
-   { 1, 2, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
+   { 1, 3, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
    { 1, 2, 1, 0, 0, 0, "TXQ", TGSI_OPCODE_TXQ },
    { 0, 0, 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
    { 0, 0, 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
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/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 9cac309..6364fb1 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2421,7 +2421,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 +2480,11 @@ 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;
+      } else
+	 offset = st_src_reg_for_int(0);
       break;
    }
 
@@ -2555,7 +2560,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, offset);
+   } else
       inst = emit(ir, opcode, result_dst, coord);
 
    if (ir->shadow_comparitor)
-- 
1.7.6



More information about the mesa-dev mailing list