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.
This commit is contained in:
@@ -64,7 +64,7 @@ def generate_sigs(g, tex_inst, sampler_type, use_proj = False, unused_fields = 0
|
|||||||
print "(var_ref P)",
|
print "(var_ref P)",
|
||||||
|
|
||||||
# Offset
|
# Offset
|
||||||
print "(0 0 0)",
|
print "0",
|
||||||
|
|
||||||
if tex_inst != "txf":
|
if tex_inst != "txf":
|
||||||
# Projective divisor
|
# Projective divisor
|
||||||
|
@@ -1190,21 +1190,21 @@ enum ir_texture_opcode {
|
|||||||
* selected from \c ir_texture_opcodes. In the printed IR, these will
|
* selected from \c ir_texture_opcodes. In the printed IR, these will
|
||||||
* appear as:
|
* appear as:
|
||||||
*
|
*
|
||||||
* Texel offset
|
* Texel offset (0 or an expression)
|
||||||
* | Projection divisor
|
* | Projection divisor
|
||||||
* | | Shadow comparitor
|
* | | Shadow comparitor
|
||||||
* | | |
|
* | | |
|
||||||
* v v v
|
* v v v
|
||||||
* (tex (sampler) (coordinate) (0 0 0) (1) ( ))
|
* (tex <sampler> <coordinate> 0 1 ( ))
|
||||||
* (txb (sampler) (coordinate) (0 0 0) (1) ( ) (bias))
|
* (txb <sampler> <coordinate> 0 1 ( ) <bias>)
|
||||||
* (txl (sampler) (coordinate) (0 0 0) (1) ( ) (lod))
|
* (txl <sampler> <coordinate> 0 1 ( ) <lod>)
|
||||||
* (txd (sampler) (coordinate) (0 0 0) (1) ( ) (dPdx dPdy))
|
* (txd <sampler> <coordinate> 0 1 ( ) (dPdx dPdy))
|
||||||
* (txf (sampler) (coordinate) (0 0 0) (lod))
|
* (txf <sampler> <coordinate> 0 <lod>)
|
||||||
*/
|
*/
|
||||||
class ir_texture : public ir_rvalue {
|
class ir_texture : public ir_rvalue {
|
||||||
public:
|
public:
|
||||||
ir_texture(enum ir_texture_opcode op)
|
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;
|
this->ir_type = ir_type_texture;
|
||||||
}
|
}
|
||||||
@@ -1258,8 +1258,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
ir_rvalue *shadow_comparitor;
|
ir_rvalue *shadow_comparitor;
|
||||||
|
|
||||||
/** Explicit texel offsets. */
|
/** Texel offset. */
|
||||||
signed char offsets[3];
|
ir_rvalue *offset;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
ir_rvalue *lod; /**< Floating point LOD */
|
ir_rvalue *lod; /**< Floating point LOD */
|
||||||
|
@@ -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);
|
new_tex->shadow_comparitor = this->shadow_comparitor->clone(mem_ctx, ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
if (this->offset != NULL)
|
||||||
new_tex->offsets[i] = this->offsets[i];
|
new_tex->offset = this->offset->clone(mem_ctx, ht);
|
||||||
|
|
||||||
switch (this->op) {
|
switch (this->op) {
|
||||||
case ir_tex:
|
case ir_tex:
|
||||||
|
@@ -187,6 +187,12 @@ ir_texture::accept(ir_hierarchical_visitor *v)
|
|||||||
return (s == visit_continue_with_parent) ? visit_continue : s;
|
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) {
|
switch (this->op) {
|
||||||
case ir_tex:
|
case ir_tex:
|
||||||
break;
|
break;
|
||||||
|
@@ -192,7 +192,15 @@ void ir_print_visitor::visit(ir_texture *ir)
|
|||||||
|
|
||||||
ir->coordinate->accept(this);
|
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->op != ir_txf) {
|
||||||
if (ir->projector)
|
if (ir->projector)
|
||||||
|
@@ -869,7 +869,7 @@ ir_reader::read_texture(s_expression *expr)
|
|||||||
s_symbol *tag = NULL;
|
s_symbol *tag = NULL;
|
||||||
s_expression *s_sampler = NULL;
|
s_expression *s_sampler = NULL;
|
||||||
s_expression *s_coord = NULL;
|
s_expression *s_coord = NULL;
|
||||||
s_list *s_offset = NULL;
|
s_expression *s_offset = NULL;
|
||||||
s_expression *s_proj = NULL;
|
s_expression *s_proj = NULL;
|
||||||
s_list *s_shadow = NULL;
|
s_list *s_shadow = NULL;
|
||||||
s_expression *s_lod = NULL;
|
s_expression *s_lod = NULL;
|
||||||
@@ -915,18 +915,15 @@ ir_reader::read_texture(s_expression *expr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read texel offset, i.e. (0 0 0)
|
// Read texel offset - either 0 or an rvalue.
|
||||||
s_int *offset_x;
|
s_int *si_offset = SX_AS_INT(s_offset);
|
||||||
s_int *offset_y;
|
if (si_offset == NULL || si_offset->value() != 0) {
|
||||||
s_int *offset_z;
|
tex->offset = read_rvalue(s_offset);
|
||||||
s_pattern offset_pat[] = { offset_x, offset_y, offset_z };
|
if (tex->offset == NULL) {
|
||||||
if (!MATCH(s_offset, offset_pat)) {
|
ir_read_error(s_offset, "expected 0 or an expression");
|
||||||
ir_read_error(s_offset, "expected (<int> <int> <int>)");
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
}
|
||||||
tex->offsets[0] = offset_x->value();
|
|
||||||
tex->offsets[1] = offset_y->value();
|
|
||||||
tex->offsets[2] = offset_z->value();
|
|
||||||
|
|
||||||
if (op != ir_txf) {
|
if (op != ir_txf) {
|
||||||
s_int *proj_as_int = SX_AS_INT(s_proj);
|
s_int *proj_as_int = SX_AS_INT(s_proj);
|
||||||
|
@@ -53,6 +53,7 @@ ir_rvalue_visitor::visit_leave(ir_texture *ir)
|
|||||||
handle_rvalue(&ir->coordinate);
|
handle_rvalue(&ir->coordinate);
|
||||||
handle_rvalue(&ir->projector);
|
handle_rvalue(&ir->projector);
|
||||||
handle_rvalue(&ir->shadow_comparitor);
|
handle_rvalue(&ir->shadow_comparitor);
|
||||||
|
handle_rvalue(&ir->offset);
|
||||||
|
|
||||||
switch (ir->op) {
|
switch (ir->op) {
|
||||||
case ir_tex:
|
case ir_tex:
|
||||||
|
@@ -245,6 +245,7 @@ ir_tree_grafting_visitor::visit_enter(ir_texture *ir)
|
|||||||
{
|
{
|
||||||
if (do_graft(&ir->coordinate) ||
|
if (do_graft(&ir->coordinate) ||
|
||||||
do_graft(&ir->projector) ||
|
do_graft(&ir->projector) ||
|
||||||
|
do_graft(&ir->offset) ||
|
||||||
do_graft(&ir->shadow_comparitor))
|
do_graft(&ir->shadow_comparitor))
|
||||||
return visit_stop;
|
return visit_stop;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user