summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-08-13 17:22:16 +0100
committerKeith Whitwell <[email protected]>2009-08-13 17:32:25 +0100
commitf2fcd5822a0b308e8b9410061996377c0b4a0a91 (patch)
treec8e9012f36e56c8d1def17fe350a34b51071e4ac /src
parentb56d2ba7b2e685e8c551788577b382480e77025a (diff)
tgsi: add simple facility for releasing and reusing temporaries
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c40
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h4
2 files changed, 40 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index 368b7a6f9e5..ba84a82b2b0 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -69,6 +69,7 @@ struct ureg_tokens {
#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_IMMEDIATE 32
+#define UREG_MAX_TEMP 256
#define DOMAIN_DECL 0
#define DOMAIN_INSN 1
@@ -94,12 +95,13 @@ struct ureg_program
struct {
float v[4];
unsigned nr;
- } immediate[UREG_MAX_OUTPUT];
+ } immediate[UREG_MAX_IMMEDIATE];
unsigned nr_immediates;
+ unsigned temps_active[UREG_MAX_TEMP / 32];
+ unsigned nr_temps;
unsigned nr_constants;
- unsigned nr_temps;
unsigned nr_samplers;
struct ureg_tokens domain[2];
@@ -303,11 +305,41 @@ struct ureg_src ureg_DECL_constant(struct ureg_program *ureg )
}
-/* Allocate a new temporary. No way to release temporaries in this code.
+/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP
+ * are legal, but will not be released.
*/
struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
{
- return ureg_dst_register( TGSI_FILE_TEMPORARY, ureg->nr_temps++ );
+ unsigned i;
+
+ for (i = 0; i < UREG_MAX_TEMP; i += 32) {
+ int bit = ffs(~ureg->temps_active[i/32]);
+ if (bit != 0) {
+ i += bit - 1;
+ goto out;
+ }
+ }
+
+ /* No reusable temps, so allocate a new one:
+ */
+ i = ureg->nr_temps++;
+
+out:
+ if (i < UREG_MAX_TEMP)
+ ureg->temps_active[i/32] |= 1 << (i % 32);
+
+ if (i >= ureg->nr_temps)
+ ureg->nr_temps = i + 1;
+
+ return ureg_dst_register( TGSI_FILE_TEMPORARY, i );
+}
+
+
+void ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp )
+{
+ if (tmp.Index < UREG_MAX_TEMP)
+ ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32));
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index ad7cd8e69c0..0a976fd63b7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -122,6 +122,10 @@ ureg_DECL_constant( struct ureg_program * );
struct ureg_dst
ureg_DECL_temporary( struct ureg_program * );
+void
+ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp );
+
struct ureg_src
ureg_DECL_sampler( struct ureg_program * );