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]]
This commit is contained in:
parent
2b221e11da
commit
101f792a2a
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -102,7 +102,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
|
|||
"IMM",
|
||||
"PRED",
|
||||
"SV",
|
||||
"IMMX"
|
||||
"IMMX",
|
||||
"TEMPX"
|
||||
};
|
||||
|
||||
static const char *interpolate_names[] =
|
||||
|
@ -191,20 +192,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,
|
||||
|
@ -251,30 +238,52 @@ _dump_register_src(
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_dump_register_ind(
|
||||
struct dump_ctx *ctx,
|
||||
uint file,
|
||||
int index,
|
||||
uint ind_file,
|
||||
int ind_index,
|
||||
uint ind_swizzle )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
CHR( ']' );
|
||||
}
|
||||
|
||||
static void
|
||||
_dump_register_dst(
|
||||
struct dump_ctx *ctx,
|
||||
const struct tgsi_full_dst_register *dst )
|
||||
{
|
||||
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( ']' );
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -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( ®->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];
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
static boolean
|
||||
parse_register_dst( struct translate_ctx *ctx,
|
||||
uint *file,
|
||||
int *index );
|
||||
|
||||
struct parsed_src_bracket {
|
||||
/* <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_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_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 ))
|
||||
brackets->ind_comp = TGSI_SWIZZLE_X;
|
||||
if (!parse_register_file_bracket( ctx, file ))
|
||||
return FALSE;
|
||||
eat_opt_white( &ctx->cur );
|
||||
if (*ctx->cur != ']') {
|
||||
report_error( ctx, "Expected `]'" );
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue