glsl: Change texel offsets to a single vector rvalue.
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 9 Jan 2011 07:49:23 +0000 (23:49 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 31 Jan 2011 19:10:59 +0000 (11:10 -0800)
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
src/glsl/ir.h
src/glsl/ir_clone.cpp
src/glsl/ir_hv_accept.cpp
src/glsl/ir_print_visitor.cpp
src/glsl/ir_reader.cpp
src/glsl/ir_rvalue_visitor.cpp
src/glsl/opt_tree_grafting.cpp

index 8bf708b5aac7c536a272cdb29e4fbdc80bcc5f8d..d7ac4d3e85a2892cccf1ef00c002c949d56f3db8 100755 (executable)
@@ -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
index 1fce272756e5d607cdfdb1fdb718ed658c9fef65..878c1779d85fac9ebbdf2dffd30c41493e7f1e38 100644 (file)
@@ -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 */
index 20a59b1e435f9501b3454a011472db6e7d8d5850..2c0574dc6bf9bb5059808856cff23a12f191f6f9 100644 (file)
@@ -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:
index be8b36a7cf8f5315c287493829354c648a6e0a53..4a607dc87499b800df7a6fff5c09b09fb49822be 100644 (file)
@@ -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;
index d0373cb6310bcaaa7cac6845b3c8753c70c346cb..630850048f629a35b44cdb526e052297dc61a66a 100644 (file)
@@ -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)
index bff75ed0e8e54d8ac6651bc3247dea62859251ff..9ed3d23508a284d55c72f478302610119d85515b 100644 (file)
@@ -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);
index 773bfcfa3ec9425d20fa82e29b586cdb4d6924e9..ed6c7cb6a1a088e6fb1b2d31a5d15324a72983a9 100644 (file)
@@ -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:
index 9917c045b1db607e0f38f981c44bb34295549b14..ae77408dbeaefd844e537e3d1086d6a7e2cb23a8 100644 (file)
@@ -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;