mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 16:10:09 +01:00
tgis: implement indirect addressing for destination registers
Includes the TGSI interpreter, but not the SSE/PPC/etc code generators.
This commit is contained in:
parent
ca1b71b78d
commit
baa7ff47d5
6 changed files with 101 additions and 11 deletions
|
|
@ -584,6 +584,7 @@ tgsi_build_full_instruction(
|
|||
*dst_register = tgsi_build_dst_register(
|
||||
reg->DstRegister.File,
|
||||
reg->DstRegister.WriteMask,
|
||||
reg->DstRegister.Indirect,
|
||||
reg->DstRegister.Index,
|
||||
instruction,
|
||||
header );
|
||||
|
|
@ -631,6 +632,28 @@ tgsi_build_full_instruction(
|
|||
header );
|
||||
prev_token = (struct tgsi_token *) dst_register_ext_modulate;
|
||||
}
|
||||
|
||||
if( reg->DstRegister.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->DstRegisterInd.File,
|
||||
reg->DstRegisterInd.SwizzleX,
|
||||
reg->DstRegisterInd.SwizzleY,
|
||||
reg->DstRegisterInd.SwizzleZ,
|
||||
reg->DstRegisterInd.SwizzleW,
|
||||
reg->DstRegisterInd.Negate,
|
||||
reg->DstRegisterInd.Indirect,
|
||||
reg->DstRegisterInd.Dimension,
|
||||
reg->DstRegisterInd.Index,
|
||||
instruction,
|
||||
header );
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i < full_inst->Instruction.NumSrcRegs; i++ ) {
|
||||
|
|
@ -1194,6 +1217,7 @@ struct tgsi_dst_register
|
|||
tgsi_build_dst_register(
|
||||
unsigned file,
|
||||
unsigned mask,
|
||||
unsigned indirect,
|
||||
int index,
|
||||
struct tgsi_instruction *instruction,
|
||||
struct tgsi_header *header )
|
||||
|
|
@ -1208,6 +1232,7 @@ tgsi_build_dst_register(
|
|||
dst_register.File = file;
|
||||
dst_register.WriteMask = mask;
|
||||
dst_register.Index = index;
|
||||
dst_register.Indirect = indirect;
|
||||
|
||||
instruction_grow( instruction, header );
|
||||
|
||||
|
|
@ -1220,6 +1245,7 @@ tgsi_default_full_dst_register( void )
|
|||
struct tgsi_full_dst_register full_dst_register;
|
||||
|
||||
full_dst_register.DstRegister = tgsi_default_dst_register();
|
||||
full_dst_register.DstRegisterInd = tgsi_default_src_register();
|
||||
full_dst_register.DstRegisterExtConcode =
|
||||
tgsi_default_dst_register_ext_concode();
|
||||
full_dst_register.DstRegisterExtModulate =
|
||||
|
|
|
|||
|
|
@ -289,6 +289,7 @@ struct tgsi_dst_register
|
|||
tgsi_build_dst_register(
|
||||
unsigned file,
|
||||
unsigned mask,
|
||||
unsigned indirect,
|
||||
int index,
|
||||
struct tgsi_instruction *instruction,
|
||||
struct tgsi_header *header );
|
||||
|
|
|
|||
|
|
@ -355,11 +355,22 @@ iter_instruction(
|
|||
CHR( ',' );
|
||||
CHR( ' ' );
|
||||
|
||||
_dump_register(
|
||||
ctx,
|
||||
dst->DstRegister.File,
|
||||
dst->DstRegister.Index,
|
||||
dst->DstRegister.Index );
|
||||
if (dst->DstRegister.Indirect) {
|
||||
_dump_register_ind(
|
||||
ctx,
|
||||
dst->DstRegister.File,
|
||||
dst->DstRegister.Index,
|
||||
dst->DstRegisterInd.File,
|
||||
dst->DstRegisterInd.Index,
|
||||
dst->DstRegisterInd.SwizzleX );
|
||||
}
|
||||
else {
|
||||
_dump_register(
|
||||
ctx,
|
||||
dst->DstRegister.File,
|
||||
dst->DstRegister.Index,
|
||||
dst->DstRegister.Index );
|
||||
}
|
||||
ENM( dst->DstRegisterExtModulate.Modulate, modulate_names );
|
||||
_dump_writemask( ctx, dst->DstRegister.WriteMask );
|
||||
|
||||
|
|
|
|||
|
|
@ -1395,28 +1395,69 @@ store_dest(
|
|||
union tgsi_exec_channel null;
|
||||
union tgsi_exec_channel *dst;
|
||||
uint execmask = mach->ExecMask;
|
||||
int offset = 0; /* indirection offset */
|
||||
int index;
|
||||
|
||||
#ifdef DEBUG
|
||||
check_inf_or_nan(chan);
|
||||
#endif
|
||||
|
||||
/* There is an extra source register that indirectly subscripts
|
||||
* a register file. The direct index now becomes an offset
|
||||
* that is being added to the indirect register.
|
||||
*
|
||||
* file[ind[2].x+1],
|
||||
* where:
|
||||
* ind = DstRegisterInd.File
|
||||
* [2] = DstRegisterInd.Index
|
||||
* .x = DstRegisterInd.SwizzleX
|
||||
*/
|
||||
if (reg->DstRegister.Indirect) {
|
||||
union tgsi_exec_channel index;
|
||||
union tgsi_exec_channel indir_index;
|
||||
uint swizzle;
|
||||
|
||||
/* which address register (always zero for now) */
|
||||
index.i[0] =
|
||||
index.i[1] =
|
||||
index.i[2] =
|
||||
index.i[3] = reg->DstRegisterInd.Index;
|
||||
|
||||
/* get current value of address register[swizzle] */
|
||||
swizzle = tgsi_util_get_src_register_swizzle( ®->DstRegisterInd, CHAN_X );
|
||||
|
||||
/* fetch values from the address/indirection register */
|
||||
fetch_src_file_channel(
|
||||
mach,
|
||||
reg->DstRegisterInd.File,
|
||||
swizzle,
|
||||
&index,
|
||||
&indir_index );
|
||||
|
||||
/* save indirection offset */
|
||||
offset = (int) indir_index.f[0];
|
||||
}
|
||||
|
||||
switch (reg->DstRegister.File) {
|
||||
case TGSI_FILE_NULL:
|
||||
dst = &null;
|
||||
break;
|
||||
|
||||
case TGSI_FILE_OUTPUT:
|
||||
dst = &mach->Outputs[mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
|
||||
+ reg->DstRegister.Index].xyzw[chan_index];
|
||||
index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
|
||||
+ reg->DstRegister.Index;
|
||||
dst = &mach->Outputs[offset + index].xyzw[chan_index];
|
||||
break;
|
||||
|
||||
case TGSI_FILE_TEMPORARY:
|
||||
assert( reg->DstRegister.Index < TGSI_EXEC_NUM_TEMPS );
|
||||
dst = &mach->Temps[reg->DstRegister.Index].xyzw[chan_index];
|
||||
index = reg->DstRegister.Index;
|
||||
assert( index < TGSI_EXEC_NUM_TEMPS );
|
||||
dst = &mach->Temps[offset + index].xyzw[chan_index];
|
||||
break;
|
||||
|
||||
case TGSI_FILE_ADDRESS:
|
||||
dst = &mach->Addrs[reg->DstRegister.Index].xyzw[chan_index];
|
||||
index = reg->DstRegister.Index;
|
||||
dst = &mach->Addrs[index].xyzw[chan_index];
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ tgsi_parse_token(
|
|||
/*
|
||||
* No support for indirect or multi-dimensional addressing.
|
||||
*/
|
||||
assert( !inst->FullDstRegisters[i].DstRegister.Indirect );
|
||||
assert( !inst->FullDstRegisters[i].DstRegister.Dimension );
|
||||
|
||||
extended = inst->FullDstRegisters[i].DstRegister.Extended;
|
||||
|
|
@ -246,6 +245,17 @@ tgsi_parse_token(
|
|||
|
||||
extended = token.Extended;
|
||||
}
|
||||
|
||||
if( inst->FullDstRegisters[i].DstRegister.Indirect ) {
|
||||
next_token( ctx, &inst->FullDstRegisters[i].DstRegisterInd );
|
||||
|
||||
/*
|
||||
* No support for indirect or multi-dimensional addressing.
|
||||
*/
|
||||
assert( !inst->FullDstRegisters[i].DstRegisterInd.Indirect );
|
||||
assert( !inst->FullDstRegisters[i].DstRegisterInd.Dimension );
|
||||
assert( !inst->FullDstRegisters[i].DstRegisterInd.Extended );
|
||||
}
|
||||
}
|
||||
|
||||
assert( inst->Instruction.NumSrcRegs <= TGSI_FULL_MAX_SRC_REGISTERS );
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ struct tgsi_full_header
|
|||
struct tgsi_full_dst_register
|
||||
{
|
||||
struct tgsi_dst_register DstRegister;
|
||||
struct tgsi_src_register DstRegisterInd;
|
||||
struct tgsi_dst_register_ext_concode DstRegisterExtConcode;
|
||||
struct tgsi_dst_register_ext_modulate DstRegisterExtModulate;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue