[Mesa-dev] [PATCH] mesa/st: emit sampler declarations as arrays when indirect accesses are done

Ilia Mirkin imirkin at alum.mit.edu
Mon Aug 11 08:18:39 PDT 2014


Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---

This applies on top of my previous patch to allow dynamic sampler offsets.

Roland, I believe this should address your concerns. The generated code looks
like:

FRAG
PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1
DCL IN[0], GENERIC[0], PERSPECTIVE
DCL OUT[0], COLOR
DCL SAMP[0]
DCL SAMP[1..3]
DCL CONST[4]
DCL TEMP[0..1], LOCAL
DCL ADDR[0..2]
IMM[0] FLT32 {    0.0000,     0.0000,     0.0000,     0.0000}
  0: MOV TEMP[0].xy, IN[0].xyyy
  1: TEX TEMP[0], TEMP[0], SAMP[0], 2D
  2: MOV TEMP[1].xy, IN[0].xyyy
  3: UARL ADDR[2].x, CONST[4].xxxx
  4: TEX TEMP[1], TEMP[1], SAMP[ADDR[2].x+1], 2D
  5: MAD TEMP[0], TEMP[0], IMM[0].xxxx, TEMP[1]
  6: MOV OUT[0], TEMP[0]
  7: END

And for now, the +1 is definitely guaranteed to be the base of the sampler
array. If some future optimization pass materializes, it will have to update
this code since it won't work otherwise. On the bright side, it's unlikely
that it'd poke around in inst->sampler, at least not without fixing things up
first.

 src/gallium/auxiliary/tgsi/tgsi_ureg.c     | 48 +++++++++++++++++++++++-------
 src/gallium/auxiliary/tgsi/tgsi_ureg.h     |  5 ++++
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 16 ++++++----
 3 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 6d3ac91..00c671b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -141,7 +141,10 @@ struct ureg_program
    } immediate[UREG_MAX_IMMEDIATE];
    unsigned nr_immediates;
 
-   struct ureg_src sampler[PIPE_MAX_SAMPLERS];
+   struct {
+      struct ureg_src sampler;
+      unsigned size;
+   } sampler[PIPE_MAX_SAMPLERS];
    unsigned nr_samplers;
 
    struct {
@@ -663,19 +666,43 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
    unsigned i;
 
    for (i = 0; i < ureg->nr_samplers; i++)
-      if (ureg->sampler[i].Index == nr)
-         return ureg->sampler[i];
-   
+      if (ureg->sampler[i].sampler.Index == nr)
+         return ureg->sampler[i].sampler;
+
+   if (i < PIPE_MAX_SAMPLERS) {
+      ureg->sampler[i].sampler = ureg_src_register( TGSI_FILE_SAMPLER, nr );
+      ureg->sampler[i].size = 1;
+      ureg->nr_samplers++;
+      return ureg->sampler[i].sampler;
+   }
+
+   assert( 0 );
+   return ureg->sampler[0].sampler;
+}
+
+struct ureg_src
+ureg_DECL_sampler_array( struct ureg_program *ureg,
+                         unsigned nr,
+                         unsigned elements )
+{
+   unsigned i;
+
+   for (i = 0; i < ureg->nr_samplers; i++)
+      if (ureg->sampler[i].sampler.Index == nr)
+         return ureg->sampler[i].sampler;
+
    if (i < PIPE_MAX_SAMPLERS) {
-      ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
+      ureg->sampler[i].sampler = ureg_src_register( TGSI_FILE_SAMPLER, nr );
+      ureg->sampler[i].size = elements;
       ureg->nr_samplers++;
-      return ureg->sampler[i];
+      return ureg->sampler[i].sampler;
    }
 
    assert( 0 );
-   return ureg->sampler[0];
+   return ureg->sampler[0].sampler;
 }
 
+
 /*
  * Allocate a new shader sampler view.
  */
@@ -1571,9 +1598,10 @@ static void emit_decls( struct ureg_program *ureg )
    }
 
    for (i = 0; i < ureg->nr_samplers; i++) {
-      emit_decl_range( ureg, 
-                       TGSI_FILE_SAMPLER,
-                       ureg->sampler[i].Index, 1 );
+      emit_decl_range(ureg,
+                      TGSI_FILE_SAMPLER,
+                      ureg->sampler[i].sampler.Index,
+                      ureg->sampler[i].size);
    }
 
    for (i = 0; i < ureg->nr_sampler_views; i++) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index f014b53..0512efa 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -325,6 +325,11 @@ ureg_DECL_sampler( struct ureg_program *,
                    unsigned index );
 
 struct ureg_src
+ureg_DECL_sampler_array( struct ureg_program *,
+                         unsigned index,
+                         unsigned elements );
+
+struct ureg_src
 ureg_DECL_sampler_view(struct ureg_program *,
                        unsigned index,
                        unsigned target,
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 1fc229c..29b0742 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -31,6 +31,7 @@
  */
 
 #include <stdio.h>
+#include <map>
 #include "main/compiler.h"
 #include "ir.h"
 #include "ir_visitor.h"
@@ -334,8 +335,10 @@ public:
    unsigned array_sizes[MAX_ARRAYS];
    unsigned next_array;
 
-   int num_address_regs;
    int samplers_used;
+   std::map<int, int> sampler_array_sizes;
+
+   int num_address_regs;
    bool indirect_addr_consts;
    
    int glsl_version;
@@ -3229,9 +3232,12 @@ static void
 count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
 {
    v->samplers_used = 0;
+   v->sampler_array_sizes.clear();
 
    foreach_in_list(glsl_to_tgsi_instruction, inst, &v->instructions) {
       if (is_tex_instruction(inst->op)) {
+         v->sampler_array_sizes.insert(
+               std::make_pair(inst->sampler.index, inst->sampler_array_size));
          for (int i = 0; i < inst->sampler_array_size; i++) {
             v->samplers_used |= 1 << (inst->sampler.index + i);
 
@@ -5115,10 +5121,10 @@ st_translate_program(
    assert(i == program->num_immediates);
 
    /* texture samplers */
-   for (i = 0; i < ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; i++) {
-      if (program->samplers_used & (1 << i)) {
-         t->samplers[i] = ureg_DECL_sampler(ureg, i);
-      }
+   for (std::map<int, int>::const_iterator it = program->sampler_array_sizes.begin();
+        it != program->sampler_array_sizes.end(); ++it) {
+      t->samplers[it->first] = ureg_DECL_sampler_array(
+            ureg, it->first, it->second);
    }
 
    /* Emit each instruction in turn:
-- 
1.8.5.5



More information about the mesa-dev mailing list