Mesa (gallium-gpu4-texture-opcodes): gallium: Prepare interfaces to do TXF in softpipe and TGSI interpreter.

Michał Król michal at kemper.freedesktop.org
Tue Jan 12 12:39:51 UTC 2010


Module: Mesa
Branch: gallium-gpu4-texture-opcodes
Commit: de1fb34223b82caf3805ebca9e1bb2fbc13c99fa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=de1fb34223b82caf3805ebca9e1bb2fbc13c99fa

Author: Michal Krol <michal at vmware.com>
Date:   Tue Jan 12 10:19:22 2010 +0100

gallium: Prepare interfaces to do TXF in softpipe and TGSI interpreter.

---

 src/gallium/auxiliary/draw/draw_gs.c      |    4 +-
 src/gallium/auxiliary/draw/draw_vs_exec.c |    4 +-
 src/gallium/auxiliary/tgsi/tgsi_exec.c    |  219 +++++++++++++++++++++++-----
 src/gallium/auxiliary/tgsi/tgsi_exec.h    |   25 +++-
 src/gallium/drivers/softpipe/sp_fs_exec.c |   17 ++-
 src/gallium/drivers/softpipe/sp_fs_sse.c  |    8 +-
 src/gallium/drivers/softpipe/sp_quad_fs.c |    8 +-
 src/gallium/drivers/softpipe/sp_state.h   |    7 +-
 8 files changed, 227 insertions(+), 65 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c
index 5db2e75..8dde007 100644
--- a/src/gallium/auxiliary/draw/draw_gs.c
+++ b/src/gallium/auxiliary/draw/draw_gs.c
@@ -333,6 +333,8 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
        tgsi_exec_machine_bind_shader(shader->machine,
                                      shader->state.tokens,
                                      draw->gs.num_samplers,
-                                     draw->gs.samplers);
+                                     draw->gs.samplers,
+                                     0,
+                                     NULL);
     }
 }
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 41cc802..46305dc 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -70,7 +70,9 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
       tgsi_exec_machine_bind_shader(evs->machine,
                                     shader->state.tokens,
                                     draw->vs.num_samplers,
-                                    draw->vs.samplers);
+                                    draw->vs.samplers,
+                                    0,
+                                    NULL);
    }
 }
 
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index c3d79c9..4ce4bec 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -540,12 +540,13 @@ tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
  * allocating temporary storage, setting up constants, etc.
  * After this, we can call tgsi_exec_machine_run() many times.
  */
-void 
-tgsi_exec_machine_bind_shader(
-   struct tgsi_exec_machine *mach,
-   const struct tgsi_token *tokens,
-   uint numSamplers,
-   struct tgsi_sampler **samplers)
+void
+tgsi_exec_machine_bind_shader(struct tgsi_exec_machine *mach,
+                              const struct tgsi_token *tokens,
+                              uint numSamplers,
+                              struct tgsi_sampler **samplers,
+                              uint numResources,
+                              struct tgsi_resource **resources)
 {
    uint k;
    struct tgsi_parse_context parse;
@@ -564,6 +565,7 @@ tgsi_exec_machine_bind_shader(
 
    mach->Tokens = tokens;
    mach->Samplers = samplers;
+   mach->Resources = resources;
 
    k = tgsi_parse_init (&parse, mach->Tokens);
    if (k != TGSI_PARSE_OK) {
@@ -1503,7 +1505,107 @@ emit_primitive(struct tgsi_exec_machine *mach)
  * Fetch a four texture samples using STR texture coordinates.
  */
 static void
-fetch_texel( struct tgsi_sampler *sampler,
+fetch_texel(struct tgsi_resource *resource,
+            const union tgsi_exec_channel *i,
+            const union tgsi_exec_channel *j,
+            const union tgsi_exec_channel *k,
+            const union tgsi_exec_channel *lod,
+            union tgsi_exec_channel *r,
+            union tgsi_exec_channel *g,
+            union tgsi_exec_channel *b,
+            union tgsi_exec_channel *a)
+{
+   uint q;
+   float rgba[NUM_CHANNELS][QUAD_SIZE];
+
+   resource->fetch3D(resource, i->i, j->i, k->i, lod->i, rgba);
+
+   for (q = 0; q < QUAD_SIZE; q++) {
+      r->f[q] = rgba[0][q];
+      g->f[q] = rgba[1][q];
+      b->f[q] = rgba[2][q];
+      a->f[q] = rgba[3][q];
+   }
+}
+
+static void
+exec_txf(struct tgsi_exec_machine *mach,
+         const struct tgsi_full_instruction *inst)
+{
+   const uint unit = inst->Src[0].Register.Index;
+   union tgsi_exec_channel r[4];
+   uint chan;
+
+   switch (mach->ResourceDecls[unit].Texture) {
+   case TGSI_TEXTURE_1D:
+   case TGSI_TEXTURE_SHADOW1D:
+      fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+      fetch_texel(mach->Resources[unit],
+                  &r[0],
+                  &ZeroVec,
+                  &ZeroVec,
+                  &r[3],
+                  &r[0],
+                  &r[1],
+                  &r[2],
+                  &r[3]);
+      break;
+
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_SHADOWRECT:
+      fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+      fetch_texel(mach->Resources[unit],
+                  &r[0],
+                  &r[1],
+                  &ZeroVec,
+                  &r[3],
+                  &r[0],
+                  &r[1],
+                  &r[2],
+                  &r[3]);
+      break;
+
+   case TGSI_TEXTURE_3D:
+   case TGSI_TEXTURE_CUBE:
+      fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_INT);
+      fetch_source(mach, &r[3], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_INT);
+
+      fetch_texel(mach->Resources[unit],
+                  &r[0],
+                  &r[1],
+                  &r[2],
+                  &r[3],
+                  &r[0],
+                  &r[1],
+                  &r[2],
+                  &r[3]);
+      break;
+
+   default:
+      assert(0);
+   }
+
+   for (chan = 0; chan < NUM_CHANNELS; chan++) {
+      if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
+         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
+      }
+   }
+}
+
+/*
+ * Sample four texture samples using STR texture coordinates.
+ */
+static void
+sample_texel(struct tgsi_sampler *sampler,
              const union tgsi_exec_channel *s,
              const union tgsi_exec_channel *t,
              const union tgsi_exec_channel *p,
@@ -1512,14 +1614,14 @@ fetch_texel( struct tgsi_sampler *sampler,
              union tgsi_exec_channel *r,
              union tgsi_exec_channel *g,
              union tgsi_exec_channel *b,
-             union tgsi_exec_channel *a )
+             union tgsi_exec_channel *a)
 {
    uint j;
    float rgba[NUM_CHANNELS][QUAD_SIZE];
 
    sampler->get_samples(sampler, s->f, t->f, p->f, c0->f, control, rgba);
 
-   for (j = 0; j < 4; j++) {
+   for (j = 0; j < QUAD_SIZE; j++) {
       r->f[j] = rgba[0][j];
       g->f[j] = rgba[1][j];
       b->f[j] = rgba[2][j];
@@ -1559,7 +1661,7 @@ exec_tex(struct tgsi_exec_machine *mach,
       control = tgsi_sampler_lod_bias;
    }
 
-   switch (mach->Resources[image_unit].Texture) {
+   switch (mach->ResourceDecls[image_unit].Texture) {
    case TGSI_TEXTURE_1D:
    case TGSI_TEXTURE_SHADOW1D:
       fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
@@ -1568,10 +1670,16 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[0], &r[0], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &ZeroVec, &ZeroVec, lod,  /* S, T, P, LOD */
-                  control,
-                  &r[0], &r[1], &r[2], &r[3]);     /* R, G, B, A */
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &ZeroVec,
+                   &ZeroVec,
+                   lod,
+                   control,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    case TGSI_TEXTURE_2D:
@@ -1588,10 +1696,16 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[2], &r[2], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], lod,     /* S, T, P, LOD */
-                  control,
-                  &r[0], &r[1], &r[2], &r[3]);  /* outputs */
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   lod,
+                   control,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    case TGSI_TEXTURE_3D:
@@ -1606,10 +1720,16 @@ exec_tex(struct tgsi_exec_machine *mach,
          micro_div(&r[2], &r[2], &r[3]);
       }
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], lod,
-                  control,
-                  &r[0], &r[1], &r[2], &r[3]);
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   lod,
+                   control,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    default:
@@ -1618,7 +1738,7 @@ exec_tex(struct tgsi_exec_machine *mach,
 
    for (chan = 0; chan < NUM_CHANNELS; chan++) {
       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
-         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
       }
    }
 }
@@ -1636,15 +1756,21 @@ exec_txd(struct tgsi_exec_machine *mach,
     * XXX: This is fake TXD -- the derivatives are not taken into account, yet.
     */
 
-   switch (mach->Resources[image_unit].Texture) {
+   switch (mach->ResourceDecls[image_unit].Texture) {
    case TGSI_TEXTURE_1D:
    case TGSI_TEXTURE_SHADOW1D:
       fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT);
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &ZeroVec, &ZeroVec, &ZeroVec,   /* S, T, P, BIAS */
-                  tgsi_sampler_lod_bias,
-                  &r[0], &r[1], &r[2], &r[3]);           /* R, G, B, A */
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &ZeroVec,
+                   &ZeroVec,
+                   &ZeroVec,
+                   tgsi_sampler_lod_bias,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    case TGSI_TEXTURE_2D:
@@ -1655,10 +1781,16 @@ exec_txd(struct tgsi_exec_machine *mach,
       fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
       fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,   /* inputs */
-                  tgsi_sampler_lod_bias,
-                  &r[0], &r[1], &r[2], &r[3]);     /* outputs */
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &ZeroVec,
+                   tgsi_sampler_lod_bias,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    case TGSI_TEXTURE_3D:
@@ -1667,10 +1799,16 @@ exec_txd(struct tgsi_exec_machine *mach,
       fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT);
       fetch_source(mach, &r[2], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT);
 
-      fetch_texel(mach->Samplers[sampler_unit],
-                  &r[0], &r[1], &r[2], &ZeroVec,
-                  tgsi_sampler_lod_bias,
-                  &r[0], &r[1], &r[2], &r[3]);
+      sample_texel(mach->Samplers[sampler_unit],
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &ZeroVec,
+                   tgsi_sampler_lod_bias,
+                   &r[0],
+                   &r[1],
+                   &r[2],
+                   &r[3]);
       break;
 
    default:
@@ -1679,7 +1817,7 @@ exec_txd(struct tgsi_exec_machine *mach,
 
    for (chan = 0; chan < NUM_CHANNELS; chan++) {
       if (inst->Dst[0].Register.WriteMask & (1 << chan)) {
-         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT);
+         store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_UINT);
       }
    }
 }
@@ -1757,7 +1895,7 @@ exec_declaration(struct tgsi_exec_machine *mach,
                  const struct tgsi_full_declaration *decl)
 {
    if (decl->Declaration.File == TGSI_FILE_RESOURCE) {
-      mach->Resources[decl->Range.First] = decl->Resource;
+      mach->ResourceDecls[decl->Range.First] = decl->Resource;
       return;
    }
 
@@ -3249,7 +3387,10 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_TXF:
-      assert (0);
+      /* texture fetch */
+      /* src[0] = resource */
+      /* src[1] = texcoord */
+      exec_txf(mach, inst);
       break;
 
    case TGSI_OPCODE_TXQ:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 61189fe..d5d558a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -94,6 +94,15 @@ struct tgsi_sampler
                        float rgba[NUM_CHANNELS][QUAD_SIZE]);
 };
 
+struct tgsi_resource {
+   void (* fetch3D)(struct tgsi_resource *resource,
+                    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]);
+};
+
 /**
  * For branching/calling subroutines.
  */
@@ -331,7 +340,8 @@ struct tgsi_exec_machine
 
    struct tgsi_exec_labels Labels;
 
-   struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES];
+   struct tgsi_declaration_resource ResourceDecls[PIPE_MAX_SHADER_RESOURCES];
+   struct tgsi_resource **Resources;
 };
 
 struct tgsi_exec_machine *
@@ -341,12 +351,13 @@ void
 tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach);
 
 
-void 
-tgsi_exec_machine_bind_shader(
-   struct tgsi_exec_machine *mach,
-   const struct tgsi_token *tokens,
-   uint numSamplers,
-   struct tgsi_sampler **samplers);
+void
+tgsi_exec_machine_bind_shader(struct tgsi_exec_machine *mach,
+                              const struct tgsi_token *tokens,
+                              uint numSamplers,
+                              struct tgsi_sampler **samplers,
+                              uint numResources,
+                              struct tgsi_resource **resources);
 
 uint
 tgsi_exec_machine_run(
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 27fa126..a12a249 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -60,19 +60,22 @@ sp_exec_fragment_shader(const struct sp_fragment_shader *base)
 
 
 static void
-exec_prepare( const struct sp_fragment_shader *base,
-	      struct tgsi_exec_machine *machine,
-	      struct tgsi_sampler **samplers )
+exec_prepare(const struct sp_fragment_shader *base,
+             struct tgsi_exec_machine *machine,
+             struct tgsi_sampler **samplers,
+             struct tgsi_resource **resources)
 {
    /*
     * Bind tokens/shader to the interpreter's machine state.
     * Avoid redundant binding.
     */
    if (machine->Tokens != base->shader.tokens) {
-      tgsi_exec_machine_bind_shader( machine,
-                                     base->shader.tokens,
-                                     PIPE_MAX_SAMPLERS,
-                                     samplers );
+      tgsi_exec_machine_bind_shader(machine,
+                                    base->shader.tokens,
+                                    PIPE_MAX_SAMPLERS,
+                                    samplers,
+                                    PIPE_MAX_SHADER_RESOURCES,
+                                    resources);
    }
 }
 
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index f912950..882eb11 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -68,11 +68,13 @@ sp_sse_fragment_shader(const struct sp_fragment_shader *base)
 
 
 static void
-fs_sse_prepare( const struct sp_fragment_shader *base,
-		struct tgsi_exec_machine *machine,
-		struct tgsi_sampler **samplers )
+fs_sse_prepare(const struct sp_fragment_shader *base,
+               struct tgsi_exec_machine *machine,
+               struct tgsi_sampler **samplers,
+               struct tgsi_resource **resources)
 {
    machine->Samplers = samplers;
+   machine->Resources = resources;
 }
 
 
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 1e7533d..7a32b5f 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -142,10 +142,10 @@ shade_begin(struct quad_stage *qs)
    struct quad_shade_stage *qss = quad_shade_stage(qs);
    struct softpipe_context *softpipe = qs->softpipe;
 
-   softpipe->fs->prepare( softpipe->fs, 
-			  qss->machine,
-			  (struct tgsi_sampler **)
-                             softpipe->tgsi.frag_samplers_list );
+   softpipe->fs->prepare(softpipe->fs,
+                         qss->machine,
+                         (struct tgsi_sampler **)softpipe->tgsi.frag_samplers_list,
+                         NULL);
 
    qs->next->begin(qs->next);
 }
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 9b18dac..b994640 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -68,9 +68,10 @@ struct sp_fragment_shader {
 
    struct tgsi_shader_info info;
 
-   void (*prepare)( const struct sp_fragment_shader *shader,
-		    struct tgsi_exec_machine *machine,
-		    struct tgsi_sampler **samplers);
+   void (*prepare)(const struct sp_fragment_shader *shader,
+                   struct tgsi_exec_machine *machine,
+                   struct tgsi_sampler **samplers,
+                   struct tgsi_resource **resources);
 
    /* Run the shader - this interface will get cleaned up in the
     * future:




More information about the mesa-commit mailing list