summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c34
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c28
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c51
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c12
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c7
7 files changed, 117 insertions, 17 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index a1891a140ac..d272533d63c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -139,8 +139,8 @@ tgsi_build_declaration(
{
struct tgsi_declaration declaration;
- assert( file <= TGSI_FILE_IMMEDIATE );
- assert( interpolate <= TGSI_INTERPOLATE_PERSPECTIVE );
+ assert( file < TGSI_FILE_COUNT );
+ assert( interpolate < TGSI_INTERPOLATE_COUNT );
declaration = tgsi_default_declaration();
declaration.File = file;
@@ -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++ ) {
@@ -973,7 +996,7 @@ tgsi_build_src_register(
{
struct tgsi_src_register src_register;
- assert( file <= TGSI_FILE_IMMEDIATE );
+ assert( file < TGSI_FILE_COUNT );
assert( swizzle_x <= TGSI_SWIZZLE_W );
assert( swizzle_y <= TGSI_SWIZZLE_W );
assert( swizzle_z <= TGSI_SWIZZLE_W );
@@ -1194,13 +1217,14 @@ struct tgsi_dst_register
tgsi_build_dst_register(
unsigned file,
unsigned mask,
+ unsigned indirect,
int index,
struct tgsi_instruction *instruction,
struct tgsi_header *header )
{
struct tgsi_dst_register dst_register;
- assert( file <= TGSI_FILE_IMMEDIATE );
+ assert( file < TGSI_FILE_COUNT );
assert( mask <= TGSI_WRITEMASK_XYZW );
assert( index >= -32768 && index <= 32767 );
@@ -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 =
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 0fd6fabd83d..9a3a077cf2b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -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 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index 76a09af18ee..a6994ecd48b 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -28,6 +28,7 @@
#include "util/u_debug.h"
#include "util/u_string.h"
#include "util/u_math.h"
+#include "util/u_memory.h"
#include "tgsi_dump.h"
#include "tgsi_info.h"
#include "tgsi_iterate.h"
@@ -108,7 +109,8 @@ static const char *semantic_names[] =
"FOG",
"PSIZE",
"GENERIC",
- "NORMAL"
+ "NORMAL",
+ "FACE"
};
static const char *immediate_type_names[] =
@@ -224,6 +226,9 @@ iter_declaration(
{
struct dump_ctx *ctx = (struct dump_ctx *)iter;
+ assert(Elements(semantic_names) == TGSI_SEMANTIC_COUNT);
+ assert(Elements(interpolate_names) == TGSI_INTERPOLATE_COUNT);
+
TXT( "DCL " );
_dump_register(
@@ -355,11 +360,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 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index aba7a3f9374..5cb322a5fa2 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -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( &reg->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:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 0081f74ffc4..7f2cfb7988f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -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 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 054350712d8..a289e26e3ac 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -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;
};
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index a40fcab2126..a76bbc91400 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -26,6 +26,7 @@
**************************************************************************/
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "tgsi_text.h"
#include "tgsi_build.h"
#include "tgsi_info.h"
@@ -927,7 +928,8 @@ static const char *semantic_names[TGSI_SEMANTIC_COUNT] =
"FOG",
"PSIZE",
"GENERIC",
- "NORMAL"
+ "NORMAL",
+ "FACE"
};
static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] =
@@ -947,6 +949,9 @@ static boolean parse_declaration( struct translate_ctx *ctx )
const char *cur;
uint advance;
+ assert(Elements(semantic_names) == TGSI_SEMANTIC_COUNT);
+ assert(Elements(interpolate_names) == TGSI_INTERPOLATE_COUNT);
+
if (!eat_white( &ctx->cur )) {
report_error( ctx, "Syntax error" );
return FALSE;