diff options
author | Keith Whitwell <keithw@vmware.com> | 2009-08-13 17:22:16 +0100 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2009-08-13 17:32:25 +0100 |
commit | f2fcd5822a0b308e8b9410061996377c0b4a0a91 (patch) | |
tree | c8e9012f36e56c8d1def17fe350a34b51071e4ac /src/gallium/auxiliary | |
parent | b56d2ba7b2e685e8c551788577b382480e77025a (diff) |
tgsi: add simple facility for releasing and reusing temporaries
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 40 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.h | 4 |
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 368b7a6f9e..ba84a82b2b 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 ad7cd8e69c..0a976fd63b 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 * ); |