From 2b221e11da7a8bf759e3c359f22ba6f49d5f0997 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Fri, 18 Jun 2010 09:39:16 -0400 Subject: [PATCH] gallium: add a new register file - immediate array allows one to specify a safe (bound checked) array filled with immediates. it works just like a const array and declares much like our current immediates. --- src/gallium/auxiliary/tgsi/tgsi_build.c | 21 +++- src/gallium/auxiliary/tgsi/tgsi_dump.c | 103 +++++++++++++----- src/gallium/auxiliary/tgsi/tgsi_exec.c | 21 ++++ src/gallium/auxiliary/tgsi/tgsi_exec.h | 2 + src/gallium/auxiliary/tgsi/tgsi_parse.c | 11 ++ src/gallium/auxiliary/tgsi/tgsi_parse.h | 6 ++ src/gallium/auxiliary/tgsi/tgsi_sanity.c | 3 +- src/gallium/auxiliary/tgsi/tgsi_text.c | 119 +++++++++++++++------ src/gallium/include/pipe/p_shader_tokens.h | 25 ++--- 9 files changed, 240 insertions(+), 71 deletions(-) diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 0890078cd05..89e020adaca 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -164,6 +164,7 @@ tgsi_default_full_declaration( void ) 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; } @@ -180,7 +181,7 @@ tgsi_build_full_declaration( struct tgsi_declaration_range *dr; if( maxsize <= size ) - return 0; + return 0; declaration = (struct tgsi_declaration *) &tokens[size]; size++; @@ -235,6 +236,24 @@ tgsi_build_full_declaration( 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; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index de6d4419464..82443d96115 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "ADDR", "IMM", "PRED", - "SV" + "SV", + "IMMX" }; static const char *interpolate_names[] = @@ -292,6 +293,39 @@ _dump_writemask( } } +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, @@ -372,6 +406,43 @@ iter_declaration( } } + 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; @@ -445,33 +516,11 @@ iter_immediate( { 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(); @@ -502,12 +551,12 @@ iter_instruction( 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( '(' ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 2b0809b6eba..335fd34604c 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -699,6 +699,19 @@ tgsi_exec_machine_bind_shader( ++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])); @@ -1074,6 +1087,14 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, } 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); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 3caf820af67..b54ca2355fe 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -240,6 +240,8 @@ struct tgsi_exec_machine 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]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index 7e19e1fe36f..ae8c868dcb7 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -117,6 +117,17 @@ tgsi_parse_token( 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; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index b45ccee2f63..3f4965e6d59 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -54,12 +54,18 @@ struct tgsi_full_src_register 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 diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index c2fd6b6e434..fa6a1a36dd1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -235,7 +235,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "ADDR", "IMM", "PRED", - "SV" + "SV", + "IMMX" }; static boolean diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 527b7d7b226..3d838d30fae 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -280,7 +280,8 @@ static const char *file_names[TGSI_FILE_COUNT] = "ADDR", "IMM", "PRED", - "SV" + "SV", + "IMMX" }; static boolean @@ -985,6 +986,45 @@ static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] = "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; @@ -995,6 +1035,7 @@ static boolean parse_declaration( struct translate_ctx *ctx ) 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); @@ -1025,6 +1066,7 @@ static boolean parse_declaration( struct translate_ctx *ctx ) 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 ); @@ -1067,6 +1109,44 @@ static boolean parse_declaration( struct translate_ctx *ctx ) 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; @@ -1097,6 +1177,10 @@ static boolean parse_declaration( struct translate_ctx *ctx ) 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; @@ -1107,7 +1191,6 @@ static boolean parse_declaration( struct translate_ctx *ctx ) static boolean parse_immediate( struct translate_ctx *ctx ) { struct tgsi_full_immediate imm; - uint i; float values[4]; uint advance; @@ -1115,37 +1198,13 @@ static boolean parse_immediate( struct translate_ctx *ctx ) 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; diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h index c46c7e3d14e..184a582cf7a 100644 --- a/src/gallium/include/pipe/p_shader_tokens.h +++ b/src/gallium/include/pipe/p_shader_tokens.h @@ -65,16 +65,17 @@ struct tgsi_token }; 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 */ }; @@ -159,9 +160,9 @@ struct tgsi_declaration_semantic 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 -- 2.30.2