diff options
author | michal <michal@michal-laptop.(none)> | 2007-08-15 18:16:11 +0100 |
---|---|---|
committer | michal <michal@michal-laptop.(none)> | 2007-08-15 18:16:11 +0100 |
commit | 058b978a5ae2a56e09fed6335b686c654444f4ac (patch) | |
tree | 717ec3f4ba2089521af5b468e8dea8b715c3105e /src/mesa/pipe/tgsi | |
parent | b9eeb8dccff3b440a299f19a0868a3ff1cda1e09 (diff) |
Add UsageMask to DECLARATION in TGSI.
Interpolate FS attributes in the shader.
Do not copy WPOS in FS.
Diffstat (limited to 'src/mesa/pipe/tgsi')
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_build.c | 4 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_build.h | 1 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_dump.c | 31 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_exec.c | 127 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_exec.h | 52 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/core/tgsi_token.h | 37 | ||||
-rw-r--r-- | src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c | 76 |
7 files changed, 244 insertions, 84 deletions
diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.c b/src/mesa/pipe/tgsi/core/tgsi_build.c index d9c9a45532d..d6f8af656ac 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_build.c +++ b/src/mesa/pipe/tgsi/core/tgsi_build.c @@ -88,6 +88,7 @@ tgsi_default_declaration( void ) declaration.Size = 1; declaration.File = TGSI_FILE_NULL; declaration.Declare = TGSI_DECLARE_RANGE; + declaration.UsageMask = TGSI_WRITEMASK_XYZW; declaration.Interpolate = 0; declaration.Semantic = 0; declaration.Padding = 0; @@ -100,6 +101,7 @@ struct tgsi_declaration tgsi_build_declaration( unsigned file, unsigned declare, + unsigned usage_mask, unsigned interpolate, unsigned semantic, struct tgsi_header *header ) @@ -112,6 +114,7 @@ tgsi_build_declaration( declaration = tgsi_default_declaration(); declaration.File = file; declaration.Declare = declare; + declaration.UsageMask = usage_mask; declaration.Interpolate = interpolate; declaration.Semantic = semantic; @@ -162,6 +165,7 @@ tgsi_build_full_declaration( *declaration = tgsi_build_declaration( full_decl->Declaration.File, full_decl->Declaration.Declare, + full_decl->Declaration.UsageMask, full_decl->Declaration.Interpolate, full_decl->Declaration.Semantic, header ); diff --git a/src/mesa/pipe/tgsi/core/tgsi_build.h b/src/mesa/pipe/tgsi/core/tgsi_build.h index b3eb0715eef..116c78abf34 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_build.h +++ b/src/mesa/pipe/tgsi/core/tgsi_build.h @@ -38,6 +38,7 @@ struct tgsi_declaration tgsi_build_declaration( unsigned file, unsigned declare, + unsigned usage_mask, unsigned interpolate, unsigned semantic, struct tgsi_header *header ); diff --git a/src/mesa/pipe/tgsi/core/tgsi_dump.c b/src/mesa/pipe/tgsi/core/tgsi_dump.c index 5a9f92004ed..622d617e296 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_dump.c +++ b/src/mesa/pipe/tgsi/core/tgsi_dump.c @@ -633,6 +633,22 @@ dump_declaration_short( assert( 0 ); } + if( decl->Declaration.UsageMask != TGSI_WRITEMASK_XYZW ) { + CHR( '.' ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'x' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'w' ); + } + } + if( decl->Declaration.Interpolate ) { TXT( ", " ); ENM( decl->Interpolation.Interpolate, TGSI_INTERPOLATES_SHORT ); @@ -659,6 +675,21 @@ dump_declaration_verbose( ENM( decl->Declaration.File, TGSI_FILES ); TXT( "\nDeclare : " ); ENM( decl->Declaration.Declare, TGSI_DECLARES ); + if( deflt || fd->Declaration.UsageMask != decl->Declaration.UsageMask ) { + TXT( "\nUsageMask : " ); + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_X ) { + CHR( 'X' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Y ) { + CHR( 'Y' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_Z ) { + CHR( 'Z' ); + } + if( decl->Declaration.UsageMask & TGSI_WRITEMASK_W ) { + CHR( 'W' ); + } + } if( deflt || fd->Declaration.Interpolate != decl->Declaration.Interpolate ) { TXT( "\nInterpolate: " ); UID( decl->Declaration.Interpolate ); diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.c b/src/mesa/pipe/tgsi/core/tgsi_exec.c index 0a34754c40b..0ffed20066e 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_exec.c +++ b/src/mesa/pipe/tgsi/core/tgsi_exec.c @@ -62,7 +62,7 @@ void tgsi_exec_machine_init( struct tgsi_exec_machine *mach, - struct tgsi_token *tokens, + const struct tgsi_token *tokens, GLuint numSamplers, struct tgsi_sampler *samplers) { @@ -1063,7 +1063,131 @@ fetch_texel( struct tgsi_sampler *sampler, } } +static void +constant_interpolation( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + mach->Inputs[attrib].xyzw[chan].f[i] = mach->InterpCoefs[attrib].a0[chan]; + } +} + +static void +linear_interpolation( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = mach->Inputs[0].xyzw[0].f[i]; + const float y = mach->Inputs[0].xyzw[1].f[i]; + + mach->Inputs[attrib].xyzw[chan].f[i] = + mach->InterpCoefs[attrib].a0[chan] + + mach->InterpCoefs[attrib].dadx[chan] * x + + mach->InterpCoefs[attrib].dady[chan] * y; + } +} + +static void +perspective_interpolation( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ) +{ + unsigned i; + + for( i = 0; i < QUAD_SIZE; i++ ) { + const float x = mach->Inputs[0].xyzw[0].f[i]; + const float y = mach->Inputs[0].xyzw[1].f[i]; + // WPOS.w here is really 1/w + const float w = 1.0f / mach->Inputs[0].xyzw[3].f[i]; + + mach->Inputs[attrib].xyzw[chan].f[i] = + (mach->InterpCoefs[attrib].a0[chan] + + mach->InterpCoefs[attrib].dadx[chan] * x + + mach->InterpCoefs[attrib].dady[chan] * y) * w; + } +} + +typedef void (* interpolation_func)( + struct tgsi_exec_machine *mach, + unsigned attrib, + unsigned chan ); + +static void +exec_declaration( + struct tgsi_exec_machine *mach, + const struct tgsi_full_declaration *decl ) +{ + if( mach->Processor == TGSI_PROCESSOR_FRAGMENT ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { + unsigned first, last, mask, i, j; + interpolation_func interp; + + assert( decl->Declaration.Declare == TGSI_DECLARE_RANGE ); + + first = decl->u.DeclarationRange.First; + last = decl->u.DeclarationRange.Last; + mask = decl->Declaration.UsageMask; + + /* Do not touch WPOS.xy */ + if( first == 0 ) { + mask &= ~TGSI_WRITEMASK_XY; + if( mask == TGSI_WRITEMASK_NONE ) { + first++; + if( first > last ) { + return; + } + } + } + + switch( decl->Interpolation.Interpolate ) { + case TGSI_INTERPOLATE_CONSTANT: + interp = constant_interpolation; + break; + + case TGSI_INTERPOLATE_LINEAR: + interp = linear_interpolation; + break; + case TGSI_INTERPOLATE_PERSPECTIVE: + interp = perspective_interpolation; + break; + + default: + assert( 0 ); + } + + if( mask == TGSI_WRITEMASK_XYZW ) { + unsigned i, j; + + for( i = first; i <= last; i++ ) { + for( j = 0; j < NUM_CHANNELS; j++ ) { + interp( mach, i, j ); + } + } + } + else { + unsigned i, j; + + for( j = 0; j < NUM_CHANNELS; j++ ) { + if( mask & (1 << j) ) { + for( i = first; i <= last; i++ ) { + interp( mach, i, j ); + } + } + } + } + } + } +} static void exec_instruction( @@ -2161,6 +2285,7 @@ tgsi_exec_machine_run2( tgsi_parse_token( &parse ); switch( parse.FullToken.Token.Type ) { case TGSI_TOKEN_TYPE_DECLARATION: + exec_declaration( mach, &parse.FullToken.FullDeclaration ); break; case TGSI_TOKEN_TYPE_IMMEDIATE: break; diff --git a/src/mesa/pipe/tgsi/core/tgsi_exec.h b/src/mesa/pipe/tgsi/core/tgsi_exec.h index eed2207d7d3..e5e8c3608ed 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_exec.h +++ b/src/mesa/pipe/tgsi/core/tgsi_exec.h @@ -11,23 +11,27 @@ extern "C" { #endif // defined __cplusplus +#define NUM_CHANNELS 4 /* R,G,B,A */ +#define QUAD_SIZE 4 /* 4 pixel/quad */ + union tgsi_exec_channel { - float f[4]; - int i[4]; - unsigned u[4]; + float f[QUAD_SIZE]; + int i[QUAD_SIZE]; + unsigned u[QUAD_SIZE]; }; struct tgsi_exec_vector { - union tgsi_exec_channel xyzw[4]; + union tgsi_exec_channel xyzw[NUM_CHANNELS]; }; - -#define NUM_CHANNELS 4 /* R,G,B,A */ -#ifndef QUAD_SIZE -#define QUAD_SIZE 4 /* 4 pixel/quad */ -#endif +struct tgsi_interp_coef +{ + float a0[NUM_CHANNELS]; /* in an xyzw layout */ + float dadx[NUM_CHANNELS]; + float dady[NUM_CHANNELS]; +}; #define TEX_CACHE_TILE_SIZE 8 #define TEX_CACHE_NUM_ENTRIES 8 @@ -55,8 +59,8 @@ struct tgsi_sampler struct tgsi_exec_labels { - unsigned labels[128][2]; - unsigned count; + unsigned labels[128][2]; + unsigned count; }; #define TGSI_EXEC_TEMP_00000000_I 32 @@ -109,15 +113,15 @@ struct tgsi_exec_cond_state { struct tgsi_exec_cond_regs IfPortion; struct tgsi_exec_cond_regs ElsePortion; - unsigned Condition; - boolean WasElse; + unsigned Condition; + boolean WasElse; }; /* XXX: This is temporary */ struct tgsi_exec_cond_stack { struct tgsi_exec_cond_state States[8]; - unsigned Index; /* into States[] */ + unsigned Index; /* into States[] */ }; struct tgsi_exec_machine @@ -138,15 +142,19 @@ struct tgsi_exec_machine struct tgsi_sampler *Samplers; - float Imms[256][4]; - unsigned ImmLimit; - float (*Consts)[4]; - const struct tgsi_exec_vector *Inputs; + float Imms[256][4]; + unsigned ImmLimit; + float (*Consts)[4]; + struct tgsi_exec_vector *Inputs; struct tgsi_exec_vector *Outputs; - struct tgsi_token *Tokens; - unsigned Processor; + const struct tgsi_token *Tokens; + unsigned Processor; + + /* GEOMETRY processor only. */ + unsigned *Primitives; - unsigned *Primitives; + /* FRAGMENT processor only. */ + const struct tgsi_interp_coef *InterpCoefs; struct tgsi_exec_cond_stack CondStack; #if XXX_SSE @@ -157,7 +165,7 @@ struct tgsi_exec_machine void tgsi_exec_machine_init( struct tgsi_exec_machine *mach, - struct tgsi_token *tokens, + const struct tgsi_token *tokens, unsigned numSamplers, struct tgsi_sampler *samplers); diff --git a/src/mesa/pipe/tgsi/core/tgsi_token.h b/src/mesa/pipe/tgsi/core/tgsi_token.h index f72c7dc4be4..3ed341fb7b1 100644 --- a/src/mesa/pipe/tgsi/core/tgsi_token.h +++ b/src/mesa/pipe/tgsi/core/tgsi_token.h @@ -52,15 +52,33 @@ struct tgsi_token #define TGSI_DECLARE_RANGE 0 #define TGSI_DECLARE_MASK 1 +#define TGSI_WRITEMASK_NONE 0x00 +#define TGSI_WRITEMASK_X 0x01 +#define TGSI_WRITEMASK_Y 0x02 +#define TGSI_WRITEMASK_XY 0x03 +#define TGSI_WRITEMASK_Z 0x04 +#define TGSI_WRITEMASK_XZ 0x05 +#define TGSI_WRITEMASK_YZ 0x06 +#define TGSI_WRITEMASK_XYZ 0x07 +#define TGSI_WRITEMASK_W 0x08 +#define TGSI_WRITEMASK_XW 0x09 +#define TGSI_WRITEMASK_YW 0x0A +#define TGSI_WRITEMASK_XYW 0x0B +#define TGSI_WRITEMASK_ZW 0x0C +#define TGSI_WRITEMASK_XZW 0x0D +#define TGSI_WRITEMASK_YZW 0x0E +#define TGSI_WRITEMASK_XYZW 0x0F + struct tgsi_declaration { unsigned Type : 4; /* TGSI_TOKEN_TYPE_DECLARATION */ unsigned Size : 8; /* UINT */ unsigned File : 4; /* TGSI_FILE_ */ unsigned Declare : 4; /* TGSI_DECLARE_ */ + unsigned UsageMask : 4; /* TGSI_WRITEMASK_ */ unsigned Interpolate : 1; /* BOOL */ unsigned Semantic : 1; /* BOOL */ - unsigned Padding : 9; + unsigned Padding : 5; unsigned Extended : 1; /* BOOL */ }; @@ -1226,23 +1244,6 @@ struct tgsi_instruction_ext_texture unsigned Extended : 1; /* BOOL */ }; -#define TGSI_WRITEMASK_NONE 0x00 -#define TGSI_WRITEMASK_X 0x01 -#define TGSI_WRITEMASK_Y 0x02 -#define TGSI_WRITEMASK_XY 0x03 -#define TGSI_WRITEMASK_Z 0x04 -#define TGSI_WRITEMASK_XZ 0x05 -#define TGSI_WRITEMASK_YZ 0x06 -#define TGSI_WRITEMASK_XYZ 0x07 -#define TGSI_WRITEMASK_W 0x08 -#define TGSI_WRITEMASK_XW 0x09 -#define TGSI_WRITEMASK_YW 0x0A -#define TGSI_WRITEMASK_XYW 0x0B -#define TGSI_WRITEMASK_ZW 0x0C -#define TGSI_WRITEMASK_XZW 0x0D -#define TGSI_WRITEMASK_YZW 0x0E -#define TGSI_WRITEMASK_XYZW 0x0F - struct tgsi_instruction_ext_predicate { unsigned Type : 4; /* TGSI_INSTRUCTION_EXT_TYPE_PREDICATE */ diff --git a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c index 609d3292428..2ac04e8d56f 100644 --- a/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c +++ b/src/mesa/pipe/tgsi/mesa/mesa_to_tgsi.c @@ -467,13 +467,15 @@ static struct tgsi_full_declaration make_frag_input_decl(
GLuint first,
GLuint last,
- GLuint interpolate )
+ GLuint interpolate,
+ GLuint usage_mask )
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Declare = TGSI_DECLARE_RANGE;
+ decl.Declaration.UsageMask = usage_mask;
decl.Declaration.Interpolate = 1;
decl.u.DeclarationRange.First = first;
decl.u.DeclarationRange.Last = last;
@@ -485,13 +487,15 @@ make_frag_input_decl( static struct tgsi_full_declaration
make_frag_output_decl(
GLuint index,
- GLuint semantic_name )
+ GLuint semantic_name,
+ GLuint usage_mask )
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
decl.Declaration.Declare = TGSI_DECLARE_RANGE;
+ decl.Declaration.UsageMask = usage_mask;
decl.Declaration.Semantic = 1;
decl.u.DeclarationRange.First = index;
decl.u.DeclarationRange.Last = index;
@@ -514,6 +518,7 @@ tgsi_mesa_compile_fp_program( struct tgsi_full_dst_register *fulldst;
struct tgsi_full_src_register *fullsrc;
GLuint inputs_read;
+ GLboolean reads_wpos;
GLuint preamble_size = 0;
*(struct tgsi_version *) &tokens[0] = tgsi_build_version();
@@ -523,19 +528,33 @@ tgsi_mesa_compile_fp_program( ti = 2;
- /*
- * Input 0 is always read, at least implicitly by the MOV instruction generated
- * below, so mark it as used.
- */
- inputs_read = program->Base.InputsRead | 1;
+ reads_wpos = program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS);
+ inputs_read = program->Base.InputsRead | (1 << FRAG_ATTRIB_WPOS);
/*
* Declare input attributes. Note that we do not interpolate fragment position.
*/
+
+ /* Fragment position. */
+ if( reads_wpos ) {
+ fulldecl = make_frag_input_decl(
+ 0,
+ 0,
+ TGSI_INTERPOLATE_CONSTANT,
+ TGSI_WRITEMASK_XY );
+ ti += tgsi_build_full_declaration(
+ &fulldecl,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+ }
+
+ /* Fragment zw. */
fulldecl = make_frag_input_decl(
0,
0,
- TGSI_INTERPOLATE_CONSTANT );
+ TGSI_INTERPOLATE_LINEAR,
+ reads_wpos ? TGSI_WRITEMASK_ZW : TGSI_WRITEMASK_Z );
ti += tgsi_build_full_declaration(
&fulldecl,
&tokens[ti],
@@ -552,7 +571,8 @@ tgsi_mesa_compile_fp_program( fulldecl = make_frag_input_decl(
1,
1 + count - 1,
- TGSI_INTERPOLATE_LINEAR );
+ TGSI_INTERPOLATE_LINEAR,
+ TGSI_WRITEMASK_XYZW );
ti += tgsi_build_full_declaration(
&fulldecl,
&tokens[ti],
@@ -569,7 +589,8 @@ tgsi_mesa_compile_fp_program( fulldecl = make_frag_output_decl(
0,
- TGSI_SEMANTIC_DEPTH );
+ TGSI_SEMANTIC_DEPTH,
+ TGSI_WRITEMASK_Z );
ti += tgsi_build_full_declaration(
&fulldecl,
&tokens[ti],
@@ -579,7 +600,8 @@ tgsi_mesa_compile_fp_program( if( program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR) ) {
fulldecl = make_frag_output_decl(
1,
- TGSI_SEMANTIC_COLOR );
+ TGSI_SEMANTIC_COLOR,
+ TGSI_WRITEMASK_XYZW );
ti += tgsi_build_full_declaration(
&fulldecl,
&tokens[ti],
@@ -587,38 +609,6 @@ tgsi_mesa_compile_fp_program( maxTokens - ti );
}
- /*
- * Copy input fragment xyz to output xyz.
- * If the shader writes depth, do not copy the z component.
- */
-
- fullinst = tgsi_default_full_instruction();
-
- fullinst.Instruction.Opcode = TGSI_OPCODE_MOV;
- fullinst.Instruction.NumDstRegs = 1;
- fullinst.Instruction.NumSrcRegs = 1;
-
- fulldst = &fullinst.FullDstRegisters[0];
- fulldst->DstRegister.File = TGSI_FILE_OUTPUT;
- fulldst->DstRegister.Index = 0;
- if( program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR) ) {
- fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XY;
- }
- else {
- fulldst->DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
- }
-
- fullsrc = &fullinst.FullSrcRegisters[0];
- fullsrc->SrcRegister.File = TGSI_FILE_INPUT;
- fullsrc->SrcRegister.Index = 0;
-
- ti += tgsi_build_full_instruction(
- &fullinst,
- &tokens[ti],
- header,
- maxTokens - ti );
- preamble_size++;
-
for( i = 0; i < program->Base.NumInstructions; i++ ) {
if( compile_instruction(
&program->Base.Instructions[i],
|