full_declaration.Declaration = tgsi_default_declaration();
full_declaration.Range = tgsi_default_declaration_range();
full_declaration.Semantic = tgsi_default_declaration_semantic();
+ full_declaration.ImmediateData.u = NULL;
return full_declaration;
}
struct tgsi_declaration_range *dr;
if( maxsize <= size )
- return 0;
+ return 0;
declaration = (struct tgsi_declaration *) &tokens[size];
size++;
header );
}
+ if (full_decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
+ unsigned i, j;
+ union tgsi_immediate_data *data;
+
+ for (i = 0; i <= dr->Last; ++i) {
+ for (j = 0; j < 4; ++j) {
+ unsigned idx = i*4 + j;
+ if (maxsize <= size)
+ return 0;
+ data = (union tgsi_immediate_data *) &tokens[size];
+ ++size;
+
+ *data = full_decl->ImmediateData.u[idx];
+ declaration_grow( declaration, header );
+ }
+ }
+ }
+
return size;
}
"ADDR",
"IMM",
"PRED",
- "SV"
+ "SV",
+ "IMMX"
};
static const char *interpolate_names[] =
}
}
+static void
+dump_imm_data(struct tgsi_iterate_context *iter,
+ union tgsi_immediate_data *data,
+ unsigned num_tokens,
+ unsigned data_type)
+{
+ struct dump_ctx *ctx = (struct dump_ctx *)iter;
+ unsigned i ;
+
+ TXT( " {" );
+
+ assert( num_tokens <= 4 );
+ for (i = 0; i < num_tokens; i++) {
+ switch (data_type) {
+ case TGSI_IMM_FLOAT32:
+ FLT( data[i].Float );
+ break;
+ case TGSI_IMM_UINT32:
+ UID(data[i].Uint);
+ break;
+ case TGSI_IMM_INT32:
+ SID(data[i].Int);
+ break;
+ default:
+ assert( 0 );
+ }
+
+ if (i < num_tokens - 1)
+ TXT( ", " );
+ }
+ TXT( "}" );
+}
+
static boolean
iter_declaration(
struct tgsi_iterate_context *iter,
}
}
+ if (decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
+ unsigned i;
+ char range_indent[4];
+
+ TXT(" {");
+
+ if (decl->Range.Last < 10)
+ range_indent[0] = '\0';
+ else if (decl->Range.Last < 100) {
+ range_indent[0] = ' ';
+ range_indent[1] = '\0';
+ } else if (decl->Range.Last < 1000) {
+ range_indent[0] = ' ';
+ range_indent[1] = ' ';
+ range_indent[2] = '\0';
+ } else {
+ range_indent[0] = ' ';
+ range_indent[1] = ' ';
+ range_indent[2] = ' ';
+ range_indent[3] = '\0';
+ }
+
+ dump_imm_data(iter, decl->ImmediateData.u,
+ 4, TGSI_IMM_FLOAT32);
+ for(i = 1; i <= decl->Range.Last; ++i) {
+ /* indent by strlen of:
+ * "DCL IMMX[0..1] {" */
+ CHR('\n');
+ TXT( " " );
+ TXT( range_indent );
+ dump_imm_data(iter, decl->ImmediateData.u + i,
+ 4, TGSI_IMM_FLOAT32);
+ }
+
+ TXT(" }");
+ }
+
EOL();
return TRUE;
{
struct dump_ctx *ctx = (struct dump_ctx *) iter;
- uint i;
-
TXT( "IMM " );
ENM( imm->Immediate.DataType, immediate_type_names );
- TXT( " { " );
-
- assert( imm->Immediate.NrTokens <= 4 + 1 );
- for (i = 0; i < imm->Immediate.NrTokens - 1; i++) {
- switch (imm->Immediate.DataType) {
- case TGSI_IMM_FLOAT32:
- FLT( imm->u[i].Float );
- break;
- case TGSI_IMM_UINT32:
- UID(imm->u[i].Uint);
- break;
- case TGSI_IMM_INT32:
- SID(imm->u[i].Int);
- break;
- default:
- assert( 0 );
- }
-
- if (i < imm->Immediate.NrTokens - 2)
- TXT( ", " );
- }
- TXT( " }" );
+ dump_imm_data(iter, imm->u, imm->Immediate.NrTokens - 1,
+ imm->Immediate.DataType);
EOL();
INSTID( instno );
TXT( ": " );
-
+
ctx->indent -= info->pre_dedent;
for(i = 0; (int)i < ctx->indent; ++i)
TXT( " " );
ctx->indent += info->post_indent;
-
+
if (inst->Instruction.Predicate) {
CHR( '(' );
++mach->NumOutputs;
}
}
+ if (parse.FullToken.FullDeclaration.Declaration.File ==
+ TGSI_FILE_IMMEDIATE_ARRAY) {
+ unsigned reg;
+ struct tgsi_full_declaration *decl =
+ &parse.FullToken.FullDeclaration;
+ debug_assert(decl->Range.Last < TGSI_EXEC_NUM_IMMEDIATES);
+ for (reg = decl->Range.First; reg <= decl->Range.Last; ++reg) {
+ for( i = 0; i < 4; i++ ) {
+ int idx = reg * 4 + i;
+ mach->ImmArray[reg][i] = decl->ImmediateData.u[idx].Float;
+ }
+ }
+ }
memcpy(declarations + numDeclarations,
&parse.FullToken.FullDeclaration,
sizeof(declarations[0]));
}
break;
+ case TGSI_FILE_IMMEDIATE_ARRAY:
+ for (i = 0; i < QUAD_SIZE; i++) {
+ assert(index2D->i[i] == 0);
+
+ chan->f[i] = mach->ImmArray[index->i[i]][swizzle];
+ }
+ break;
+
case TGSI_FILE_ADDRESS:
for (i = 0; i < QUAD_SIZE; i++) {
assert(index->i[i] >= 0);
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
+ float ImmArray[TGSI_EXEC_NUM_IMMEDIATES][4];
+
struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES];
next_token( ctx, &decl->Semantic );
}
+ if (decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) {
+ unsigned i, j;
+ decl->ImmediateData.u = (union tgsi_immediate_data*)
+ &ctx->Tokens[ctx->Position];
+ for (i = 0; i <= decl->Range.Last; ++i) {
+ for (j = 0; j < 4; ++j) {
+ ctx->Position++;
+ }
+ }
+ }
+
break;
}
struct tgsi_src_register DimIndirect;
};
+struct tgsi_immediate_array_data
+{
+ union tgsi_immediate_data *u;
+};
+
struct tgsi_full_declaration
{
struct tgsi_declaration Declaration;
struct tgsi_declaration_range Range;
struct tgsi_declaration_dimension Dim;
struct tgsi_declaration_semantic Semantic;
+ struct tgsi_immediate_array_data ImmediateData;
};
struct tgsi_full_immediate
"ADDR",
"IMM",
"PRED",
- "SV"
+ "SV",
+ "IMMX"
};
static boolean
"ADDR",
"IMM",
"PRED",
- "SV"
+ "SV",
+ "IMMX"
};
static boolean
"PERSPECTIVE"
};
+
+/* parses a 4-touple of the form {x, y, z, w}
+ * where x, y, z, w are numbers */
+static boolean parse_immediate_data(struct translate_ctx *ctx,
+ float *values)
+{
+ unsigned i;
+
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != '{') {
+ report_error( ctx, "Expected `{'" );
+ return FALSE;
+ }
+ ctx->cur++;
+ for (i = 0; i < 4; i++) {
+ eat_opt_white( &ctx->cur );
+ if (i > 0) {
+ if (*ctx->cur != ',') {
+ report_error( ctx, "Expected `,'" );
+ return FALSE;
+ }
+ ctx->cur++;
+ eat_opt_white( &ctx->cur );
+ }
+ if (!parse_float( &ctx->cur, &values[i] )) {
+ report_error( ctx, "Expected literal floating point" );
+ return FALSE;
+ }
+ }
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != '}') {
+ report_error( ctx, "Expected `}'" );
+ return FALSE;
+ }
+ ctx->cur++;
+
+ return TRUE;
+}
+
static boolean parse_declaration( struct translate_ctx *ctx )
{
struct tgsi_full_declaration decl;
const char *cur;
uint advance;
boolean is_vs_input;
+ boolean is_imm_array;
assert(Elements(semantic_names) == TGSI_SEMANTIC_COUNT);
assert(Elements(interpolate_names) == TGSI_INTERPOLATE_COUNT);
is_vs_input = (file == TGSI_FILE_INPUT &&
ctx->processor == TGSI_PROCESSOR_VERTEX);
+ is_imm_array = (file == TGSI_FILE_IMMEDIATE_ARRAY);
cur = ctx->cur;
eat_opt_white( &cur );
break;
}
}
+ } else if (is_imm_array) {
+ unsigned i;
+ float *vals_itr;
+ /* we have our immediate data */
+ if (*cur != '{') {
+ report_error( ctx, "Immediate array without data" );
+ return FALSE;
+ }
+ ++cur;
+ ctx->cur = cur;
+
+ decl.ImmediateData.u =
+ MALLOC(sizeof(union tgsi_immediate_data) * 4 *
+ (decl.Range.Last + 1));
+ vals_itr = (float*)decl.ImmediateData.u;
+ for (i = 0; i <= decl.Range.Last; ++i) {
+ if (!parse_immediate_data(ctx, vals_itr)) {
+ FREE(decl.ImmediateData.u);
+ return FALSE;
+ }
+ vals_itr += 4;
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != ',') {
+ if (i != decl.Range.Last) {
+ report_error( ctx, "Not enough data in immediate array!" );
+ FREE(decl.ImmediateData.u);
+ return FALSE;
+ }
+ } else
+ ++ctx->cur;
+ }
+ eat_opt_white( &ctx->cur );
+ if (*ctx->cur != '}') {
+ FREE(decl.ImmediateData.u);
+ report_error( ctx, "Immediate array data missing closing '}'" );
+ return FALSE;
+ }
+ ++ctx->cur;
}
cur = ctx->cur;
ctx->tokens_cur,
ctx->header,
(uint) (ctx->tokens_end - ctx->tokens_cur) );
+
+ if (is_imm_array)
+ FREE(decl.ImmediateData.u);
+
if (advance == 0)
return FALSE;
ctx->tokens_cur += advance;
static boolean parse_immediate( struct translate_ctx *ctx )
{
struct tgsi_full_immediate imm;
- uint i;
float values[4];
uint advance;
report_error( ctx, "Syntax error" );
return FALSE;
}
- if (!str_match_no_case( &ctx->cur, "FLT32" ) || is_digit_alpha_underscore( ctx->cur )) {
+ if (!str_match_no_case( &ctx->cur, "FLT32" ) ||
+ is_digit_alpha_underscore( ctx->cur )) {
report_error( ctx, "Expected `FLT32'" );
return FALSE;
}
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != '{') {
- report_error( ctx, "Expected `{'" );
- return FALSE;
- }
- ctx->cur++;
- for (i = 0; i < 4; i++) {
- eat_opt_white( &ctx->cur );
- if (i > 0) {
- if (*ctx->cur != ',') {
- report_error( ctx, "Expected `,'" );
- return FALSE;
- }
- ctx->cur++;
- eat_opt_white( &ctx->cur );
- }
- if (!parse_float( &ctx->cur, &values[i] )) {
- report_error( ctx, "Expected literal floating point" );
- return FALSE;
- }
- }
- eat_opt_white( &ctx->cur );
- if (*ctx->cur != '}') {
- report_error( ctx, "Expected `}'" );
- return FALSE;
- }
- ctx->cur++;
+
+ parse_immediate_data(ctx, values);
imm = tgsi_default_full_immediate();
imm.Immediate.NrTokens += 4;
};
enum tgsi_file_type {
- TGSI_FILE_NULL =0,
- TGSI_FILE_CONSTANT =1,
- TGSI_FILE_INPUT =2,
- TGSI_FILE_OUTPUT =3,
- TGSI_FILE_TEMPORARY =4,
- TGSI_FILE_SAMPLER =5,
- TGSI_FILE_ADDRESS =6,
- TGSI_FILE_IMMEDIATE =7,
- TGSI_FILE_PREDICATE =8,
- TGSI_FILE_SYSTEM_VALUE =9,
+ TGSI_FILE_NULL =0,
+ TGSI_FILE_CONSTANT =1,
+ TGSI_FILE_INPUT =2,
+ TGSI_FILE_OUTPUT =3,
+ TGSI_FILE_TEMPORARY =4,
+ TGSI_FILE_SAMPLER =5,
+ TGSI_FILE_ADDRESS =6,
+ TGSI_FILE_IMMEDIATE =7,
+ TGSI_FILE_PREDICATE =8,
+ TGSI_FILE_SYSTEM_VALUE =9,
+ TGSI_FILE_IMMEDIATE_ARRAY =10,
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
};
struct tgsi_immediate
{
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_IMMEDIATE */
- unsigned NrTokens : 8; /**< UINT */
+ unsigned NrTokens : 14; /**< UINT */
unsigned DataType : 4; /**< one of TGSI_IMM_x */
- unsigned Padding : 16;
+ unsigned Padding : 10;
};
union tgsi_immediate_data