diff options
author | Brian Paul <[email protected]> | 2008-04-11 14:18:07 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-04-11 14:19:32 -0600 |
commit | e3cf0cd6a9f3f072594e5712763b98ce7e579bcf (patch) | |
tree | bb18e92a88664a595623ef96a1af7ba93eb005c2 | |
parent | 097301395d33d57d19bc942f236b4a8c912cc0cc (diff) |
gallium: implement immediates (aka literals) for SSE fragment shaders
-rwxr-xr-x | src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c | 82 | ||||
-rwxr-xr-x | src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_fs_sse.c | 10 |
3 files changed, 88 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c index 93813f36cbe..748c53dbfc9 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.c @@ -225,6 +225,15 @@ get_coef_base( void ) return get_output_base(); } +static struct x86_reg +get_immediate_base( void ) +{ + return x86_make_reg( + file_REG32, + reg_DI ); +} + + /** * Data access helpers. */ @@ -239,6 +248,16 @@ get_argument( } static struct x86_reg +get_immediate( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_immediate_base(), + (vec * 4 + chan) * 4 ); +} + +static struct x86_reg get_const( unsigned vec, unsigned chan ) @@ -572,6 +591,25 @@ emit_const( SHUF( 0, 0, 0, 0 ) ); } +static void +emit_immediate( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + emit_movss( + func, + make_xmm( xmm ), + get_immediate( vec, chan ) ); + emit_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + + /** * Copy a shader input to xmm register * \param xmm the destination xmm register @@ -1191,6 +1229,14 @@ emit_fetch( swizzle ); break; + case TGSI_FILE_IMMEDIATE: + emit_immediate( + func, + xmm, + reg->SrcRegister.Index, + swizzle ); + break; + case TGSI_FILE_INPUT: emit_inputf( func, @@ -2343,15 +2389,21 @@ tgsi_emit_sse2( * DECLARATION and INSTRUCTION phase. * GP register holding the output argument is aliased with the coeff argument, * as outputs are not needed in the DECLARATION phase. + * + * \param tokens the TGSI input shader + * \param func the output SSE code/function + * \param immediates buffer to place immediates, later passed to SSE func */ unsigned tgsi_emit_sse2_fs( struct tgsi_token *tokens, - struct x86_function *func ) + struct x86_function *func, + float (*immediates)[4]) { struct tgsi_parse_context parse; boolean instruction_phase = FALSE; unsigned ok = 1; + uint num_immediates = 0; DUMP_START(); @@ -2362,6 +2414,7 @@ tgsi_emit_sse2_fs( func, get_input_base(), get_argument( 0 ) ); + /* skipping outputs argument here */ emit_mov( func, get_const_base(), @@ -2374,6 +2427,10 @@ tgsi_emit_sse2_fs( func, get_coef_base(), get_argument( 4 ) ); + emit_mov( + func, + get_immediate_base(), + get_argument( 5 ) ); tgsi_parse_init( &parse, tokens ); @@ -2407,9 +2464,26 @@ tgsi_emit_sse2_fs( break; case TGSI_TOKEN_TYPE_IMMEDIATE: - /* XXX implement this */ - ok = 0; - debug_printf("failed to emit immediate value to SSE\n"); + /* simply copy the immediate values into the next immediates[] slot */ + { + const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; + uint i; + assert(size <= 4); + assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); + for( i = 0; i < size; i++ ) { + immediates[num_immediates][i] = + parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float; + } +#if 0 + debug_printf("SSE FS immediate[%d] = %f %f %f %f\n", + num_immediates, + immediates[num_immediates][0], + immediates[num_immediates][1], + immediates[num_immediates][2], + immediates[num_immediates][3]); +#endif + num_immediates++; + } break; default: diff --git a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h index 63b8ef39112..fde06047fe8 100755 --- a/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h +++ b/src/gallium/auxiliary/tgsi/exec/tgsi_sse2.h @@ -16,7 +16,9 @@ tgsi_emit_sse2( unsigned tgsi_emit_sse2_fs( struct tgsi_token *tokens, - struct x86_function *function ); + struct x86_function *function, + float (*immediates)[4] + ); #if defined __cplusplus } diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c index 8095d662ee6..9c7948264fe 100644 --- a/src/gallium/drivers/softpipe/sp_fs_sse.c +++ b/src/gallium/drivers/softpipe/sp_fs_sse.c @@ -51,7 +51,8 @@ typedef void (XSTDCALL *codegen_function)( struct tgsi_exec_vector *output, float (*constant)[4], struct tgsi_exec_vector *temporary, - const struct tgsi_interp_coef *coef + const struct tgsi_interp_coef *coef, + float (*immediates)[4] //, const struct tgsi_exec_vector *quadPos ); @@ -60,6 +61,7 @@ struct sp_sse_fragment_shader { struct sp_fragment_shader base; struct x86_function sse2_program; codegen_function func; + float immediates[TGSI_EXEC_NUM_IMMEDIATES][4]; }; @@ -96,7 +98,8 @@ fs_sse_run( struct sp_fragment_shader *base, machine->Outputs, machine->Consts, machine->Temps, - machine->InterpCoefs + machine->InterpCoefs, + shader->immediates // , &machine->QuadPos ); @@ -129,7 +132,8 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe, x86_init_func( &shader->sse2_program ); - if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program )) { + if (!tgsi_emit_sse2_fs( templ->tokens, &shader->sse2_program, + shader->immediates)) { FREE(shader); return NULL; } |