summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2010-06-18 13:41:20 -0400
committerZack Rusin <[email protected]>2010-06-18 13:46:44 -0400
commit101f792a2af9c9a19a050afba8b60caa689466a5 (patch)
treed79405c3da0da947a90d70dc7670b03a9855b237 /src
parent2b221e11da7a8bf759e3c359f22ba6f49d5f0997 (diff)
gallium: add a temporary array register file
like normal temporaries, but allows to define a number of distinct arrays, all of which make it explicit that they contain /indexable/ registers. as a side-effect we're adding support for multi-dimensional destination registers. The whole thing looks like this: DCL TEMPX[0][0..128] # 0 array with 128 registers ADD TEMPX[0][0], IN[0], IMM[0] ADD TEMPX[0][1], IN[0], IMM[0] ABS OUT[0], TEMPX[0][TEMP[0]]
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c45
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c93
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c96
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c23
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c18
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c175
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h1
10 files changed, 325 insertions, 131 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 89e020adaca..6dbedf15ca8 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -632,6 +632,7 @@ tgsi_build_full_instruction(
reg->Register.File,
reg->Register.WriteMask,
reg->Register.Indirect,
+ reg->Register.Dimension,
reg->Register.Index,
instruction,
header );
@@ -659,6 +660,46 @@ tgsi_build_full_instruction(
instruction,
header );
}
+
+ if( reg->Register.Dimension ) {
+ struct tgsi_dimension *dim;
+
+ assert( !reg->Dimension.Dimension );
+
+ if( maxsize <= size )
+ return 0;
+ dim = (struct tgsi_dimension *) &tokens[size];
+ size++;
+
+ *dim = tgsi_build_dimension(
+ reg->Dimension.Indirect,
+ reg->Dimension.Index,
+ instruction,
+ header );
+
+ if( reg->Dimension.Indirect ) {
+ struct tgsi_src_register *ind;
+
+ if( maxsize <= size )
+ return 0;
+ ind = (struct tgsi_src_register *) &tokens[size];
+ size++;
+
+ *ind = tgsi_build_src_register(
+ reg->DimIndirect.File,
+ reg->DimIndirect.SwizzleX,
+ reg->DimIndirect.SwizzleY,
+ reg->DimIndirect.SwizzleZ,
+ reg->DimIndirect.SwizzleW,
+ reg->DimIndirect.Negate,
+ reg->DimIndirect.Absolute,
+ reg->DimIndirect.Indirect,
+ reg->DimIndirect.Dimension,
+ reg->DimIndirect.Index,
+ instruction,
+ header );
+ }
+ }
}
for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) {
@@ -978,6 +1019,7 @@ tgsi_build_dst_register(
unsigned file,
unsigned mask,
unsigned indirect,
+ unsigned dimension,
int index,
struct tgsi_instruction *instruction,
struct tgsi_header *header )
@@ -993,6 +1035,7 @@ tgsi_build_dst_register(
dst_register.WriteMask = mask;
dst_register.Index = index;
dst_register.Indirect = indirect;
+ dst_register.Dimension = dimension;
instruction_grow( instruction, header );
@@ -1006,6 +1049,8 @@ tgsi_default_full_dst_register( void )
full_dst_register.Register = tgsi_default_dst_register();
full_dst_register.Indirect = tgsi_default_src_register();
+ full_dst_register.Dimension = tgsi_default_dimension();
+ full_dst_register.DimIndirect = tgsi_default_src_register();
return full_dst_register;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 13d7f5272d6..112107a0881 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -263,6 +263,7 @@ tgsi_build_dst_register(
unsigned file,
unsigned mask,
unsigned indirect,
+ unsigned dimension,
int index,
struct tgsi_instruction *instruction,
struct tgsi_header *header );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 82443d96115..9fcc28f4c96 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -102,7 +102,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"IMM",
"PRED",
"SV",
- "IMMX"
+ "IMMX",
+ "TEMPX"
};
static const char *interpolate_names[] =
@@ -192,20 +193,6 @@ static const char *fs_coord_pixel_center_names[] =
static void
-_dump_register_dst(
- struct dump_ctx *ctx,
- uint file,
- int index)
-{
- ENM( file, file_names );
-
- CHR( '[' );
- SID( index );
- CHR( ']' );
-}
-
-
-static void
_dump_register_src(
struct dump_ctx *ctx,
const struct tgsi_full_src_register *src )
@@ -251,30 +238,52 @@ _dump_register_src(
}
}
+
static void
-_dump_register_ind(
+_dump_register_dst(
struct dump_ctx *ctx,
- uint file,
- int index,
- uint ind_file,
- int ind_index,
- uint ind_swizzle )
+ const struct tgsi_full_dst_register *dst )
{
- ENM( file, file_names );
- CHR( '[' );
- ENM( ind_file, file_names );
- CHR( '[' );
- SID( ind_index );
- TXT( "]." );
- ENM( ind_swizzle, swizzle_names );
- if (index != 0) {
- if (index > 0)
- CHR( '+' );
- SID( index );
+ ENM(dst->Register.File, file_names);
+ if (dst->Register.Dimension) {
+ if (dst->Dimension.Indirect) {
+ CHR( '[' );
+ ENM( dst->DimIndirect.File, file_names );
+ CHR( '[' );
+ SID( dst->DimIndirect.Index );
+ TXT( "]." );
+ ENM( dst->DimIndirect.SwizzleX, swizzle_names );
+ if (dst->Dimension.Index != 0) {
+ if (dst->Dimension.Index > 0)
+ CHR( '+' );
+ SID( dst->Dimension.Index );
+ }
+ CHR( ']' );
+ } else {
+ CHR('[');
+ SID(dst->Dimension.Index);
+ CHR(']');
+ }
+ }
+ if (dst->Register.Indirect) {
+ CHR( '[' );
+ ENM( dst->Indirect.File, file_names );
+ CHR( '[' );
+ SID( dst->Indirect.Index );
+ TXT( "]." );
+ ENM( dst->Indirect.SwizzleX, swizzle_names );
+ if (dst->Register.Index != 0) {
+ if (dst->Register.Index > 0)
+ CHR( '+' );
+ SID( dst->Register.Index );
+ }
+ CHR( ']' );
+ } else {
+ CHR( '[' );
+ SID( dst->Register.Index );
+ CHR( ']' );
}
- CHR( ']' );
}
-
static void
_dump_writemask(
struct dump_ctx *ctx,
@@ -603,21 +612,7 @@ iter_instruction(
CHR( ',' );
CHR( ' ' );
- if (dst->Register.Indirect) {
- _dump_register_ind(
- ctx,
- dst->Register.File,
- dst->Register.Index,
- dst->Indirect.File,
- dst->Indirect.Index,
- dst->Indirect.SwizzleX );
- }
- else {
- _dump_register_dst(
- ctx,
- dst->Register.File,
- dst->Register.Index );
- }
+ _dump_register_dst( ctx, dst );
_dump_writemask( ctx, dst->Register.WriteMask );
first_reg = FALSE;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 335fd34604c..5275faa5e22 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1065,7 +1065,9 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i],
index2D->i[i], index->i[i]);
}*/
- chan->u[i] = mach->Inputs[index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]].xyzw[swizzle].u[i];
+ chan->u[i] = mach->Inputs[index2D->i[i] *
+ TGSI_EXEC_MAX_INPUT_ATTRIBS +
+ index->i[i]].xyzw[swizzle].u[i];
}
break;
@@ -1078,6 +1080,16 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach,
}
break;
+ case TGSI_FILE_TEMPORARY_ARRAY:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index->i[i] < TGSI_EXEC_NUM_TEMPS);
+ assert(index2D->i[i] < TGSI_EXEC_NUM_TEMP_ARRAYS);
+
+ chan->u[i] =
+ mach->TempArray[index2D->i[i]][index->i[i]].xyzw[swizzle].u[i];
+ }
+ break;
+
case TGSI_FILE_IMMEDIATE:
for (i = 0; i < QUAD_SIZE; i++) {
assert(index->i[i] >= 0 && index->i[i] < (int)mach->ImmLimit);
@@ -1306,6 +1318,7 @@ store_dest(struct tgsi_exec_machine *mach,
uint i;
union tgsi_exec_channel null;
union tgsi_exec_channel *dst;
+ union tgsi_exec_channel index2D;
uint execmask = mach->ExecMask;
int offset = 0; /* indirection offset */
int index;
@@ -1351,6 +1364,77 @@ store_dest(struct tgsi_exec_machine *mach,
offset = indir_index.i[0];
}
+ /* There is an extra source register that is a second
+ * subscript to a register file. Effectively it means that
+ * the register file is actually a 2D array of registers.
+ *
+ * file[3][1],
+ * where:
+ * [3] = Dimension.Index
+ */
+ if (reg->Register.Dimension) {
+ index2D.i[0] =
+ index2D.i[1] =
+ index2D.i[2] =
+ index2D.i[3] = reg->Dimension.Index;
+
+ /* Again, the second subscript index can be addressed indirectly
+ * identically to the first one.
+ * Nothing stops us from indirectly addressing the indirect register,
+ * but there is no need for that, so we won't exercise it.
+ *
+ * file[ind[4].y+3][1],
+ * where:
+ * ind = DimIndirect.File
+ * [4] = DimIndirect.Index
+ * .y = DimIndirect.SwizzleX
+ */
+ if (reg->Dimension.Indirect) {
+ union tgsi_exec_channel index2;
+ union tgsi_exec_channel indir_index;
+ const uint execmask = mach->ExecMask;
+ unsigned swizzle;
+ uint i;
+
+ index2.i[0] =
+ index2.i[1] =
+ index2.i[2] =
+ index2.i[3] = reg->DimIndirect.Index;
+
+ swizzle = tgsi_util_get_src_register_swizzle( &reg->DimIndirect, CHAN_X );
+ fetch_src_file_channel(mach,
+ reg->DimIndirect.File,
+ swizzle,
+ &index2,
+ &ZeroVec,
+ &indir_index);
+
+ index2D.i[0] += indir_index.i[0];
+ index2D.i[1] += indir_index.i[1];
+ index2D.i[2] += indir_index.i[2];
+ index2D.i[3] += indir_index.i[3];
+
+ /* for disabled execution channels, zero-out the index to
+ * avoid using a potential garbage value.
+ */
+ for (i = 0; i < QUAD_SIZE; i++) {
+ if ((execmask & (1 << i)) == 0) {
+ index2D.i[i] = 0;
+ }
+ }
+ }
+
+ /* If by any chance there was a need for a 3D array of register
+ * files, we would have to check whether Dimension is followed
+ * by a dimension register and continue the saga.
+ */
+ } else {
+ index2D.i[0] =
+ index2D.i[1] =
+ index2D.i[2] =
+ index2D.i[3] = 0;
+ }
+
switch (reg->Register.File) {
case TGSI_FILE_NULL:
dst = &null;
@@ -1377,6 +1461,16 @@ store_dest(struct tgsi_exec_machine *mach,
dst = &mach->Temps[offset + index].xyzw[chan_index];
break;
+ case TGSI_FILE_TEMPORARY_ARRAY:
+ index = reg->Register.Index;
+ assert( index < TGSI_EXEC_NUM_TEMPS );
+ assert( index2D.i[0] < TGSI_EXEC_NUM_TEMP_ARRAYS );
+ /* XXX we use index2D.i[0] here but somehow we might
+ * end up with someone trying to store indirectly in
+ * different buffers */
+ dst = &mach->TempArray[index2D.i[0]][offset + index].xyzw[chan_index];
+ break;
+
case TGSI_FILE_ADDRESS:
index = reg->Register.Index;
dst = &mach->Addrs[index].xyzw[chan_index];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index b54ca2355fe..ccf80ca6fd9 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -93,6 +93,7 @@ struct tgsi_sampler
#define TGSI_EXEC_NUM_TEMPS 128
#define TGSI_EXEC_NUM_IMMEDIATES 256
+#define TGSI_EXEC_NUM_TEMP_ARRAYS 8
/*
* Locations of various utility registers (_I = Index, _C = Channel)
@@ -237,6 +238,7 @@ struct tgsi_exec_machine
*/
struct tgsi_exec_vector Temps[TGSI_EXEC_NUM_TEMPS +
TGSI_EXEC_NUM_TEMP_EXTRAS];
+ struct tgsi_exec_vector TempArray[TGSI_EXEC_NUM_TEMP_ARRAYS][TGSI_EXEC_NUM_TEMPS];
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index ae8c868dcb7..db9a3422203 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -192,11 +192,6 @@ tgsi_parse_token(
next_token( ctx, &inst->Dst[i].Register );
- /*
- * No support for indirect or multi-dimensional addressing.
- */
- assert( !inst->Dst[i].Register.Dimension );
-
if( inst->Dst[i].Register.Indirect ) {
next_token( ctx, &inst->Dst[i].Indirect );
@@ -206,6 +201,24 @@ tgsi_parse_token(
assert( !inst->Dst[i].Indirect.Dimension );
assert( !inst->Dst[i].Indirect.Indirect );
}
+ if( inst->Dst[i].Register.Dimension ) {
+ next_token( ctx, &inst->Dst[i].Dimension );
+
+ /*
+ * No support for multi-dimensional addressing.
+ */
+ assert( !inst->Dst[i].Dimension.Dimension );
+
+ if( inst->Dst[i].Dimension.Indirect ) {
+ next_token( ctx, &inst->Dst[i].DimIndirect );
+
+ /*
+ * No support for indirect or multi-dimensional addressing.
+ */
+ assert( !inst->Dst[i].Indirect.Indirect );
+ assert( !inst->Dst[i].Indirect.Dimension );
+ }
+ }
}
assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 3f4965e6d59..36de8807b44 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -44,6 +44,8 @@ struct tgsi_full_dst_register
{
struct tgsi_dst_register Register;
struct tgsi_src_register Indirect;
+ struct tgsi_dimension Dimension;
+ struct tgsi_src_register DimIndirect;
};
struct tgsi_full_src_register
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index fa6a1a36dd1..97148dbe233 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -90,9 +90,18 @@ static void
scan_register_dst(scan_register *reg,
struct tgsi_full_dst_register *dst)
{
- fill_scan_register1d(reg,
- dst->Register.File,
- dst->Register.Index);
+ if (dst->Register.Dimension) {
+ /*FIXME: right now we don't support indirect
+ * multidimensional addressing */
+ fill_scan_register2d(reg,
+ dst->Register.File,
+ dst->Register.Index,
+ dst->Dimension.Index);
+ } else {
+ fill_scan_register1d(reg,
+ dst->Register.File,
+ dst->Register.Index);
+ }
}
static void
@@ -236,7 +245,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"IMM",
"PRED",
"SV",
- "IMMX"
+ "IMMX",
+ "TEMPX"
};
static boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index 3d838d30fae..55fccba4d8c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -281,7 +281,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"IMM",
"PRED",
"SV",
- "IMMX"
+ "IMMX",
+ "TEMPX"
};
static boolean
@@ -346,12 +347,68 @@ parse_opt_writemask(
return TRUE;
}
+
+/* <register_file_bracket> ::= <file> `['
+ */
+static boolean
+parse_register_file_bracket(
+ struct translate_ctx *ctx,
+ uint *file )
+{
+ if (!parse_file( &ctx->cur, file )) {
+ report_error( ctx, "Unknown register file" );
+ return FALSE;
+ }
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != '[') {
+ report_error( ctx, "Expected `['" );
+ return FALSE;
+ }
+ ctx->cur++;
+ return TRUE;
+}
+
+/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
+ */
+static boolean
+parse_register_file_bracket_index(
+ struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ uint uindex;
+
+ if (!parse_register_file_bracket( ctx, file ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (!parse_uint( &ctx->cur, &uindex )) {
+ report_error( ctx, "Expected literal unsigned integer" );
+ return FALSE;
+ }
+ *index = (int) uindex;
+ return TRUE;
+}
+
+/* Parse simple 1d register operand.
+ * <register_dst> ::= <register_file_bracket_index> `]'
+ */
static boolean
-parse_register_dst( struct translate_ctx *ctx,
- uint *file,
- int *index );
+parse_register_1d(struct translate_ctx *ctx,
+ uint *file,
+ int *index )
+{
+ if (!parse_register_file_bracket_index( ctx, file, index ))
+ return FALSE;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ']') {
+ report_error( ctx, "Expected `]'" );
+ return FALSE;
+ }
+ ctx->cur++;
+ return TRUE;
+}
-struct parsed_src_bracket {
+struct parsed_bracket {
int index;
uint ind_file;
@@ -361,21 +418,21 @@ struct parsed_src_bracket {
static boolean
-parse_register_src_bracket(
+parse_register_bracket(
struct translate_ctx *ctx,
- struct parsed_src_bracket *brackets)
+ struct parsed_bracket *brackets)
{
const char *cur;
uint uindex;
- memset(brackets, 0, sizeof(struct parsed_src_bracket));
+ memset(brackets, 0, sizeof(struct parsed_bracket));
eat_opt_white( &ctx->cur );
cur = ctx->cur;
if (parse_file( &cur, &brackets->ind_file )) {
- if (!parse_register_dst( ctx, &brackets->ind_file,
- &brackets->ind_index ))
+ if (!parse_register_1d( ctx, &brackets->ind_file,
+ &brackets->ind_index ))
return FALSE;
eat_opt_white( &ctx->cur );
@@ -444,7 +501,7 @@ parse_register_src_bracket(
static boolean
parse_opt_register_src_bracket(
struct translate_ctx *ctx,
- struct parsed_src_bracket *brackets,
+ struct parsed_bracket *brackets,
int *parsed_brackets)
{
const char *cur = ctx->cur;
@@ -456,7 +513,7 @@ parse_opt_register_src_bracket(
++cur;
ctx->cur = cur;
- if (!parse_register_src_bracket(ctx, brackets))
+ if (!parse_register_bracket(ctx, brackets))
return FALSE;
*parsed_brackets = 1;
@@ -465,46 +522,6 @@ parse_opt_register_src_bracket(
return TRUE;
}
-/* <register_file_bracket> ::= <file> `['
- */
-static boolean
-parse_register_file_bracket(
- struct translate_ctx *ctx,
- uint *file )
-{
- if (!parse_file( &ctx->cur, file )) {
- report_error( ctx, "Unknown register file" );
- return FALSE;
- }
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != '[') {
- report_error( ctx, "Expected `['" );
- return FALSE;
- }
- ctx->cur++;
- return TRUE;
-}
-
-/* <register_file_bracket_index> ::= <register_file_bracket> <uint>
- */
-static boolean
-parse_register_file_bracket_index(
- struct translate_ctx *ctx,
- uint *file,
- int *index )
-{
- uint uindex;
-
- if (!parse_register_file_bracket( ctx, file ))
- return FALSE;
- eat_opt_white( &ctx->cur );
- if (!parse_uint( &ctx->cur, &uindex )) {
- report_error( ctx, "Expected literal unsigned integer" );
- return FALSE;
- }
- *index = (int) uindex;
- return TRUE;
-}
/* Parse source register operand.
* <register_src> ::= <register_file_bracket_index> `]' |
@@ -516,13 +533,12 @@ static boolean
parse_register_src(
struct translate_ctx *ctx,
uint *file,
- struct parsed_src_bracket *brackets)
+ struct parsed_bracket *brackets)
{
-
brackets->ind_comp = TGSI_SWIZZLE_X;
if (!parse_register_file_bracket( ctx, file ))
return FALSE;
- if (!parse_register_src_bracket( ctx, brackets ))
+ if (!parse_register_bracket( ctx, brackets ))
return FALSE;
return TRUE;
@@ -630,23 +646,19 @@ parse_register_dcl(
}
-/* Parse destination register operand.
- * <register_dst> ::= <register_file_bracket_index> `]'
- */
+/* Parse destination register operand.*/
static boolean
parse_register_dst(
struct translate_ctx *ctx,
uint *file,
- int *index )
+ struct parsed_bracket *brackets)
{
- if (!parse_register_file_bracket_index( ctx, file, index ))
- return FALSE;
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != ']') {
- report_error( ctx, "Expected `]'" );
+ brackets->ind_comp = TGSI_SWIZZLE_X;
+ if (!parse_register_file_bracket( ctx, file ))
return FALSE;
- }
- ctx->cur++;
+ if (!parse_register_bracket( ctx, brackets ))
+ return FALSE;
+
return TRUE;
}
@@ -656,11 +668,14 @@ parse_dst_operand(
struct tgsi_full_dst_register *dst )
{
uint file;
- int index;
uint writemask;
const char *cur;
+ struct parsed_bracket bracket[2];
+ int parsed_opt_brackets;
- if (!parse_register_dst( ctx, &file, &index ))
+ if (!parse_register_dst( ctx, &file, &bracket[0] ))
+ return FALSE;
+ if (!parse_opt_register_src_bracket(ctx, &bracket[1], &parsed_opt_brackets))
return FALSE;
cur = ctx->cur;
@@ -670,8 +685,24 @@ parse_dst_operand(
return FALSE;
dst->Register.File = file;
- dst->Register.Index = index;
+ if (parsed_opt_brackets) {
+ dst->Register.Dimension = 1;
+ dst->Dimension.Indirect = 0;
+ dst->Dimension.Dimension = 0;
+ dst->Dimension.Index = bracket[0].index;
+ bracket[0] = bracket[1];
+ }
+ dst->Register.Index = bracket[0].index;
dst->Register.WriteMask = writemask;
+ if (bracket[0].ind_file != TGSI_FILE_NULL) {
+ dst->Register.Indirect = 1;
+ dst->Indirect.File = bracket[0].ind_file;
+ dst->Indirect.Index = bracket[0].ind_index;
+ dst->Indirect.SwizzleX = bracket[0].ind_comp;
+ dst->Indirect.SwizzleY = bracket[0].ind_comp;
+ dst->Indirect.SwizzleZ = bracket[0].ind_comp;
+ dst->Indirect.SwizzleW = bracket[0].ind_comp;
+ }
return TRUE;
}
@@ -720,7 +751,7 @@ parse_src_operand(
uint file;
uint swizzle[4];
boolean parsed_swizzle;
- struct parsed_src_bracket bracket[2];
+ struct parsed_bracket bracket[2];
int parsed_opt_brackets;
if (*ctx->cur == '-') {
@@ -836,7 +867,7 @@ parse_instruction(
inst.Predicate.Negate = 1;
}
- if (!parse_register_dst( ctx, &file, &index ))
+ if (!parse_register_1d( ctx, &file, &index ))
return FALSE;
if (parse_optional_swizzle( ctx, swizzle, &parsed_swizzle )) {
@@ -1064,7 +1095,7 @@ static boolean parse_declaration( struct translate_ctx *ctx )
decl.Dim.Index2D = brackets[0].first;
}
- is_vs_input = (file == TGSI_FILE_INPUT &&
+ is_vs_input = (file == TGSI_FILE_INPUT &&
ctx->processor == TGSI_PROCESSOR_VERTEX);
is_imm_array = (file == TGSI_FILE_IMMEDIATE_ARRAY);
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 184a582cf7a..9df20ea8581 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -76,6 +76,7 @@ enum tgsi_file_type {
TGSI_FILE_PREDICATE =8,
TGSI_FILE_SYSTEM_VALUE =9,
TGSI_FILE_IMMEDIATE_ARRAY =10,
+ TGSI_FILE_TEMPORARY_ARRAY =11,
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
};