summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2011-01-08 23:49:23 -0800
committerKenneth Graunke <kenneth@whitecape.org>2011-01-31 11:10:59 -0800
commitc5a27b5939427bdc95c926b450ed3de1ff4baafb (patch)
treeed0518338cbec7badc6a699a94167dbec5248429
parent60c8e91c795dc604c08977d5773f96a4de8e402b (diff)
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.
-rwxr-xr-xsrc/glsl/builtins/tools/texture_builtins.py2
-rw-r--r--src/glsl/ir.h26
-rw-r--r--src/glsl/ir_clone.cpp4
-rw-r--r--src/glsl/ir_hv_accept.cpp6
-rw-r--r--src/glsl/ir_print_visitor.cpp10
-rw-r--r--src/glsl/ir_reader.cpp21
-rw-r--r--src/glsl/ir_rvalue_visitor.cpp1
-rw-r--r--src/glsl/opt_tree_grafting.cpp1
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 8bf708b5aa..d7ac4d3e85 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 1fce272756..878c1779d8 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 20a59b1e43..2c0574dc6b 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 be8b36a7cf..4a607dc874 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 d0373cb631..630850048f 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 bff75ed0e8..9ed3d23508 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 773bfcfa3e..ed6c7cb6a1 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 9917c045b1..ae77408dbe 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;