From: Christian König Date: Sun, 10 Mar 2013 12:44:25 +0000 (+0100) Subject: tgsi/ureg: implement support for array temporaries X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=506d40027566fb5ad0718f3f20e42cb8fbc1e742;p=mesa.git tgsi/ureg: implement support for array temporaries Don't bother with free temporaries, just allocate them at the end and also emit them in their own declaration. Signed-off-by: Christian König --- diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 72657ae9f15..88acdcb12cd 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -153,6 +153,7 @@ struct ureg_program struct util_bitmask *free_temps; struct util_bitmask *local_temps; + struct util_bitmask *decl_temps; unsigned nr_temps; struct const_decl const_decls; @@ -547,13 +548,18 @@ static struct ureg_dst alloc_temporary( struct ureg_program *ureg, /* Or allocate a new one. */ - if (i == UTIL_BITMASK_INVALID_INDEX) + if (i == UTIL_BITMASK_INVALID_INDEX) { i = ureg->nr_temps++; - util_bitmask_clear(ureg->free_temps, i); + if (local) + util_bitmask_set(ureg->local_temps, i); - if (local) - util_bitmask_set(ureg->local_temps, i); + /* Start a new declaration when the local flag changes */ + if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local) + util_bitmask_set(ureg->decl_temps, i); + } + + util_bitmask_clear(ureg->free_temps, i); return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); } @@ -568,6 +574,24 @@ struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg ) return alloc_temporary(ureg, TRUE); } +struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg, + unsigned size, + boolean local ) +{ + unsigned i = ureg->nr_temps; + struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i ); + + if (local) + util_bitmask_set(ureg->local_temps, i); + + util_bitmask_set(ureg->decl_temps, i); + + ureg->nr_temps += size; + util_bitmask_set(ureg->decl_temps, ureg->nr_temps); + + return dst; +} + void ureg_release_temporary( struct ureg_program *ureg, struct ureg_dst tmp ) { @@ -856,11 +880,11 @@ ureg_emit_src( struct ureg_program *ureg, } if (src.Dimension) { + out[0].src.Dimension = 1; + out[n].dim.Dimension = 0; + out[n].dim.Padding = 0; if (src.DimIndirect) { - out[0].src.Dimension = 1; out[n].dim.Indirect = 1; - out[n].dim.Dimension = 0; - out[n].dim.Padding = 0; out[n].dim.Index = src.DimensionIndex; n++; out[n].value = 0; @@ -871,10 +895,7 @@ ureg_emit_src( struct ureg_program *ureg, out[n].src.SwizzleW = src.DimIndSwizzle; out[n].src.Index = src.DimIndIndex; } else { - out[0].src.Dimension = 1; out[n].dim.Indirect = 0; - out[n].dim.Dimension = 0; - out[n].dim.Padding = 0; out[n].dim.Index = src.DimensionIndex; } n++; @@ -1536,9 +1557,10 @@ static void emit_decls( struct ureg_program *ureg ) if (ureg->nr_temps) { for (i = 0; i < ureg->nr_temps;) { boolean local = util_bitmask_get(ureg->local_temps, i); - unsigned first = i++; - while (i < ureg->nr_temps && local == util_bitmask_get(ureg->local_temps, i)) - ++i; + unsigned first = i; + i = util_bitmask_get_next_index(ureg->decl_temps, i + 1); + if (i == UTIL_BITMASK_INVALID_INDEX) + i = ureg->nr_temps; emit_decl_temps( ureg, first, i - 1, local ); } @@ -1707,8 +1729,14 @@ struct ureg_program *ureg_create( unsigned processor ) if (ureg->local_temps == NULL) goto no_local_temps; + ureg->decl_temps = util_bitmask_create(); + if (ureg->decl_temps == NULL) + goto no_decl_temps; + return ureg; +no_decl_temps: + util_bitmask_destroy(ureg->local_temps); no_local_temps: util_bitmask_destroy(ureg->free_temps); no_free_temps: @@ -1730,6 +1758,7 @@ void ureg_destroy( struct ureg_program *ureg ) util_bitmask_destroy(ureg->free_temps); util_bitmask_destroy(ureg->local_temps); + util_bitmask_destroy(ureg->decl_temps); FREE(ureg); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index fb663e9c07e..cd140de6ba9 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -71,17 +71,17 @@ struct ureg_src */ struct ureg_dst { - unsigned File : 4; /* TGSI_FILE_ */ - unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ - unsigned Indirect : 1; /* BOOL */ - unsigned Saturate : 1; /* BOOL */ - unsigned Predicate : 1; - unsigned PredNegate : 1; /* BOOL */ - unsigned PredSwizzleX: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleY: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleZ: 2; /* TGSI_SWIZZLE_ */ - unsigned PredSwizzleW: 2; /* TGSI_SWIZZLE_ */ - int Index : 16; /* SINT */ + unsigned File : 4; /* TGSI_FILE_ */ + unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ + unsigned Indirect : 1; /* BOOL */ + unsigned Saturate : 1; /* BOOL */ + unsigned Predicate : 1; + unsigned PredNegate : 1; /* BOOL */ + unsigned PredSwizzleX : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleY : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleZ : 2; /* TGSI_SWIZZLE_ */ + unsigned PredSwizzleW : 2; /* TGSI_SWIZZLE_ */ + int Index : 16; /* SINT */ int IndirectIndex : 16; /* SINT */ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */ }; @@ -280,6 +280,14 @@ ureg_DECL_temporary( struct ureg_program * ); struct ureg_dst ureg_DECL_local_temporary( struct ureg_program * ); +/** + * Declare "size" continuous temporary registers. + */ +struct ureg_dst +ureg_DECL_array_temporary( struct ureg_program *, + unsigned size, + boolean local ); + void ureg_release_temporary( struct ureg_program *ureg, struct ureg_dst tmp ); @@ -1093,6 +1101,14 @@ ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr, return reg; } +static INLINE struct ureg_dst +ureg_dst_array_offset( struct ureg_dst reg, int offset ) +{ + assert(reg.File == TGSI_FILE_TEMPORARY); + reg.Index += offset; + return reg; +} + static INLINE struct ureg_dst ureg_dst( struct ureg_src src ) {