00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "sp_context.h"
00030 #include "sp_state.h"
00031 #include "sp_fs.h"
00032 #include "sp_headers.h"
00033
00034
00035 #include "pipe/p_state.h"
00036 #include "pipe/p_defines.h"
00037 #include "util/u_memory.h"
00038 #include "pipe/p_inlines.h"
00039 #include "tgsi/tgsi_exec.h"
00040 #include "tgsi/tgsi_sse2.h"
00041
00042
00043 #ifdef PIPE_ARCH_X86
00044
00045 #include "rtasm/rtasm_x86sse.h"
00046
00047
00048
00049 typedef void (PIPE_CDECL *codegen_function)(
00050 const struct tgsi_exec_vector *input,
00051 struct tgsi_exec_vector *output,
00052 const float (*constant)[4],
00053 struct tgsi_exec_vector *temporary,
00054 const struct tgsi_interp_coef *coef,
00055 float (*immediates)[4]
00056
00057 );
00058
00059
00060 struct sp_sse_fragment_shader {
00061 struct sp_fragment_shader base;
00062 struct x86_function sse2_program;
00063 codegen_function func;
00064 float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
00065 };
00066
00067
00068
00069 static void
00070 fs_sse_prepare( const struct sp_fragment_shader *base,
00071 struct tgsi_exec_machine *machine,
00072 struct tgsi_sampler *samplers )
00073 {
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 static unsigned
00083 fs_sse_run( const struct sp_fragment_shader *base,
00084 struct tgsi_exec_machine *machine,
00085 struct quad_header *quad )
00086 {
00087 struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base;
00088
00089
00090 sp_setup_pos_vector(quad->posCoef,
00091 (float)quad->input.x0, (float)quad->input.y0,
00092 machine->Temps);
00093
00094
00095 tgsi_set_kill_mask(machine, 0x0);
00096 tgsi_set_exec_mask(machine, 1, 1, 1, 1);
00097
00098 shader->func( machine->Inputs,
00099 machine->Outputs,
00100 machine->Consts,
00101 machine->Temps,
00102 machine->InterpCoefs,
00103 shader->immediates
00104
00105 );
00106
00107 return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
00108 }
00109
00110
00111 static void
00112 fs_sse_delete( struct sp_fragment_shader *base )
00113 {
00114 struct sp_sse_fragment_shader *shader = (struct sp_sse_fragment_shader *) base;
00115
00116 x86_release_func( &shader->sse2_program );
00117 FREE(shader);
00118 }
00119
00120
00121 struct sp_fragment_shader *
00122 softpipe_create_fs_sse(struct softpipe_context *softpipe,
00123 const struct pipe_shader_state *templ)
00124 {
00125 struct sp_sse_fragment_shader *shader;
00126
00127 if (!softpipe->use_sse)
00128 return NULL;
00129
00130 shader = CALLOC_STRUCT(sp_sse_fragment_shader);
00131 if (!shader)
00132 return NULL;
00133
00134 x86_init_func( &shader->sse2_program );
00135
00136 if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program,
00137 shader->immediates, FALSE )) {
00138 FREE(shader);
00139 return NULL;
00140 }
00141
00142 shader->func = (codegen_function) x86_get_func( &shader->sse2_program );
00143 if (!shader->func) {
00144 x86_release_func( &shader->sse2_program );
00145 FREE(shader);
00146 return NULL;
00147 }
00148
00149 shader->base.shader = *templ;
00150 shader->base.prepare = fs_sse_prepare;
00151 shader->base.run = fs_sse_run;
00152 shader->base.delete = fs_sse_delete;
00153
00154 return &shader->base;
00155 }
00156
00157
00158 #else
00159
00160
00161
00162 struct sp_fragment_shader *
00163 softpipe_create_fs_sse(struct softpipe_context *softpipe,
00164 const struct pipe_shader_state *templ)
00165 {
00166 return NULL;
00167 }
00168
00169 #endif