summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2005-05-10 08:58:44 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2005-05-10 08:58:44 +0000
commitecb6bfc0ce33b1daa84093dceeb58a4b741283e9 (patch)
treeb78814c4e9e99ab3064b12ba9563b50dd31b1e5c
parentfee163a61ac42e7ea00c8c7e708e0e879cc10ab0 (diff)
Try not to use the same temp reg as a TXP destination more than once,
as this also constitutes a texture indirection. Reported by Ben Skeggs.
-rw-r--r--src/mesa/main/texenvprogram.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index efc406b72a..ede3df2a0b 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -82,6 +82,10 @@ struct texenv_fragment_program {
struct fragment_program *program;
GLcontext *ctx;
+ GLuint tex_temp_flag; /* Temps which have been the result of a texture
+ * operation.
+ */
+
GLuint temp_flag; /* Tracks temporary regs which are in
* use.
*/
@@ -135,15 +139,49 @@ static GLboolean is_undef( struct ureg reg )
return reg.file == 0xf;
}
+
static struct ureg get_temp( struct texenv_fragment_program *p )
{
- int bit = ffs( ~p->temp_flag );
+ int bit;
+
+ /* First try and reuse texture results:
+ */
+ bit = ffs( ~(p->temp_flag & p->tex_temp_flag) );
+
+ /* Then any unused temporary:
+ */
+ if (!bit)
+ bit = ffs( ~p->temp_flag );
+
+ if (!bit) {
+ fprintf(stderr, "%s: out of temporaries\n", __FILE__);
+ exit(1);
+ }
+
+ p->temp_flag |= 1<<(bit-1);
+ return make_ureg(PROGRAM_TEMPORARY, (bit-1));
+}
+
+static struct ureg get_tex_temp( struct texenv_fragment_program *p )
+{
+ int bit;
+
+ /* First try to find temp not previously used as a texture result:
+ */
+ bit = ffs( ~(p->temp_flag & ~p->tex_temp_flag) );
+
+ /* Then any unused temporary:
+ */
+ if (!bit)
+ bit = ffs( ~p->temp_flag );
+
if (!bit) {
fprintf(stderr, "%s: out of temporaries\n", __FILE__);
exit(1);
}
p->temp_flag |= 1<<(bit-1);
+ p->tex_temp_flag |= 1<<(bit-1);
return make_ureg(PROGRAM_TEMPORARY, (bit-1));
}
@@ -339,7 +377,7 @@ static struct ureg get_source( struct texenv_fragment_program *p,
GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
- struct ureg tmp = get_temp( p );
+ struct ureg tmp = get_tex_temp( p );
/* TODO: Use D0_MASK_XY where possible.
*/