summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <[email protected]>2013-03-10 13:44:25 +0100
committerChristian König <[email protected]>2013-03-19 13:38:32 +0100
commit506d40027566fb5ad0718f3f20e42cb8fbc1e742 (patch)
tree92ffd9a0363a50996fe4c1ddbb5d6266be453371
parent52947b93b22cad46f4a010468cd0179662419b6a (diff)
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 <[email protected]>
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c55
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h38
2 files changed, 69 insertions, 24 deletions
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 );
@@ -1094,6 +1102,14 @@ ureg_src_dimension_indirect( struct ureg_src reg, struct ureg_src addr,
}
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 )
{
struct ureg_dst dst;