Mesa (master): glsl: Change texel offsets to a single vector rvalue.

Kenneth Graunke kwg at kemper.freedesktop.org
Mon Jan 31 19:53:19 UTC 2011


Module: Mesa
Branch: master
Commit: c5a27b5939427bdc95c926b450ed3de1ff4baafb
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c5a27b5939427bdc95c926b450ed3de1ff4baafb

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Sat Jan  8 23:49:23 2011 -0800

glsl: Change texel offsets to a single vector rvalue.

Having these as actual integer values makes it difficult to implement
the texture*Offset built-in functions, since the offset is actually a
function parameter (which doesn't have a constant value).

The original rationale was that some hardware needs these offset baked
into the instruction opcode.  However, at least i965 should be able to
support non-constant offsets.  Others should be able to rely on inlining
and constant propagation.

---

 src/glsl/builtins/tools/texture_builtins.py |    2 +-
 src/glsl/ir.h                               |   26 +++++++++++++-------------
 src/glsl/ir_clone.cpp                       |    4 ++--
 src/glsl/ir_hv_accept.cpp                   |    6 ++++++
 src/glsl/ir_print_visitor.cpp               |   10 +++++++++-
 src/glsl/ir_reader.cpp                      |   21 +++++++++------------
 src/glsl/ir_rvalue_visitor.cpp              |    1 +
 src/glsl/opt_tree_grafting.cpp              |    1 +
 8 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/src/glsl/builtins/tools/texture_builtins.py b/src/glsl/builtins/tools/texture_builtins.py
index 8bf708b..d7ac4d3 100755
--- a/src/glsl/builtins/tools/texture_builtins.py
+++ b/src/glsl/builtins/tools/texture_builtins.py
@@ -64,7 +64,7 @@ def generate_sigs(g, tex_inst, sampler_type, use_proj = False, unused_fields = 0
         print "(var_ref P)",
 
     # Offset
-    print "(0 0 0)",
+    print "0",
 
     if tex_inst != "txf":
         # Projective divisor
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 1fce272..878c177 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -1190,21 +1190,21 @@ enum ir_texture_opcode {
  * selected from \c ir_texture_opcodes.  In the printed IR, these will
  * appear as:
  *
- *                              Texel offset
- *                              |       Projection divisor
- *                              |       |   Shadow comparitor
- *                              |       |   |
- *                              v       v   v
- * (tex (sampler) (coordinate) (0 0 0) (1) ( ))
- * (txb (sampler) (coordinate) (0 0 0) (1) ( ) (bias))
- * (txl (sampler) (coordinate) (0 0 0) (1) ( ) (lod))
- * (txd (sampler) (coordinate) (0 0 0) (1) ( ) (dPdx dPdy))
- * (txf (sampler) (coordinate) (0 0 0)         (lod))
+ *                             Texel offset (0 or an expression)
+ *                             | Projection divisor
+ *                             | |  Shadow comparitor
+ *                             | |  |
+ *                             v v  v
+ * (tex <sampler> <coordinate> 0 1 ( ))
+ * (txb <sampler> <coordinate> 0 1 ( ) <bias>)
+ * (txl <sampler> <coordinate> 0 1 ( ) <lod>)
+ * (txd <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
+ * (txf <sampler> <coordinate> 0       <lod>)
  */
 class ir_texture : public ir_rvalue {
 public:
    ir_texture(enum ir_texture_opcode op)
-      : op(op), projector(NULL), shadow_comparitor(NULL)
+      : op(op), projector(NULL), shadow_comparitor(NULL), offset(NULL)
    {
       this->ir_type = ir_type_texture;
    }
@@ -1258,8 +1258,8 @@ public:
     */
    ir_rvalue *shadow_comparitor;
 
-   /** Explicit texel offsets. */
-   signed char offsets[3];
+   /** Texel offset. */
+   ir_rvalue *offset;
 
    union {
       ir_rvalue *lod;		/**< Floating point LOD */
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 20a59b1..2c0574d 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -217,8 +217,8 @@ ir_texture::clone(void *mem_ctx, struct hash_table *ht) const
       new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, ht);
    }
 
-   for (int i = 0; i < 3; i++)
-      new_tex->offsets[i] = this->offsets[i];
+   if (this->offset != NULL)
+      new_tex->offset = this->offset->clone(mem_ctx, ht);
 
    switch (this->op) {
    case ir_tex:
diff --git a/src/glsl/ir_hv_accept.cpp b/src/glsl/ir_hv_accept.cpp
index be8b36a..4a607dc 100644
--- a/src/glsl/ir_hv_accept.cpp
+++ b/src/glsl/ir_hv_accept.cpp
@@ -187,6 +187,12 @@ ir_texture::accept(ir_hierarchical_visitor *v)
 	 return (s == visit_continue_with_parent) ? visit_continue : s;
    }
 
+   if (this->offset) {
+      s = this->offset->accept(v);
+      if (s != visit_continue)
+	 return (s == visit_continue_with_parent) ? visit_continue : s;
+   }
+
    switch (this->op) {
    case ir_tex:
       break;
diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp
index d0373cb..6308500 100644
--- a/src/glsl/ir_print_visitor.cpp
+++ b/src/glsl/ir_print_visitor.cpp
@@ -192,7 +192,15 @@ void ir_print_visitor::visit(ir_texture *ir)
 
    ir->coordinate->accept(this);
 
-   printf(" (%d %d %d) ", ir->offsets[0], ir->offsets[1], ir->offsets[2]);
+   printf(" ");
+
+   if (ir->offset != NULL) {
+      ir->offset->accept(this);
+   } else {
+      printf("0");
+   }
+
+   printf(" ");
 
    if (ir->op != ir_txf) {
       if (ir->projector)
diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp
index bff75ed..9ed3d23 100644
--- a/src/glsl/ir_reader.cpp
+++ b/src/glsl/ir_reader.cpp
@@ -869,7 +869,7 @@ ir_reader::read_texture(s_expression *expr)
    s_symbol *tag = NULL;
    s_expression *s_sampler = NULL;
    s_expression *s_coord = NULL;
-   s_list *s_offset = NULL;
+   s_expression *s_offset = NULL;
    s_expression *s_proj = NULL;
    s_list *s_shadow = NULL;
    s_expression *s_lod = NULL;
@@ -915,18 +915,15 @@ ir_reader::read_texture(s_expression *expr)
       return NULL;
    }
 
-   // Read texel offset, i.e. (0 0 0)
-   s_int *offset_x;
-   s_int *offset_y;
-   s_int *offset_z;
-   s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
-   if (!MATCH(s_offset, offset_pat)) {
-      ir_read_error(s_offset, "expected (<int> <int> <int>)");
-      return NULL;
+   // Read texel offset - either 0 or an rvalue.
+   s_int *si_offset = SX_AS_INT(s_offset);
+   if (si_offset == NULL || si_offset->value() != 0) {
+      tex->offset = read_rvalue(s_offset);
+      if (tex->offset == NULL) {
+	 ir_read_error(s_offset, "expected 0 or an expression");
+	 return NULL;
+      }
    }
-   tex->offsets[0] = offset_x->value();
-   tex->offsets[1] = offset_y->value();
-   tex->offsets[2] = offset_z->value();
 
    if (op != ir_txf) {
       s_int *proj_as_int = SX_AS_INT(s_proj);
diff --git a/src/glsl/ir_rvalue_visitor.cpp b/src/glsl/ir_rvalue_visitor.cpp
index 773bfcf..ed6c7cb 100644
--- a/src/glsl/ir_rvalue_visitor.cpp
+++ b/src/glsl/ir_rvalue_visitor.cpp
@@ -53,6 +53,7 @@ ir_rvalue_visitor::visit_leave(ir_texture *ir)
    handle_rvalue(&ir->coordinate);
    handle_rvalue(&ir->projector);
    handle_rvalue(&ir->shadow_comparitor);
+   handle_rvalue(&ir->offset);
 
    switch (ir->op) {
    case ir_tex:
diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp
index 9917c04..ae77408 100644
--- a/src/glsl/opt_tree_grafting.cpp
+++ b/src/glsl/opt_tree_grafting.cpp
@@ -245,6 +245,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
 {
    if (do_graft(&ir->coordinate) ||
        do_graft(&ir->projector) ||
+       do_graft(&ir->offset) ||
        do_graft(&ir->shadow_comparitor))
 	 return visit_stop;
 




More information about the mesa-commit mailing list