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
00030
00031
00032
00033 #include "brw_defines.h"
00034 #include "brw_context.h"
00035 #include "brw_eu.h"
00036 #include "brw_util.h"
00037 #include "brw_sf.h"
00038 #include "brw_state.h"
00039 #include "tgsi/tgsi_parse.h"
00040
00041
00042 static void compile_sf_prog( struct brw_context *brw,
00043 struct brw_sf_prog_key *key )
00044 {
00045 struct brw_sf_compile c;
00046 const unsigned *program;
00047 unsigned program_size;
00048
00049 memset(&c, 0, sizeof(c));
00050
00051
00052
00053 brw_init_compile(&c.func);
00054
00055 c.key = *key;
00056
00057
00058 c.nr_attrs = c.key.vp_output_count;
00059 c.nr_attr_regs = (c.nr_attrs+1)/2;
00060
00061 c.nr_setup_attrs = c.key.fp_input_count + 1;
00062 c.nr_setup_regs = (c.nr_setup_attrs+1)/2;
00063
00064 c.prog_data.urb_read_length = c.nr_attr_regs;
00065 c.prog_data.urb_entry_size = c.nr_setup_regs * 2;
00066
00067
00068
00069
00070 switch (key->primitive) {
00071 case SF_TRIANGLES:
00072 c.nr_verts = 3;
00073 brw_emit_tri_setup( &c );
00074 break;
00075 case SF_LINES:
00076 c.nr_verts = 2;
00077 brw_emit_line_setup( &c );
00078 break;
00079 case SF_POINTS:
00080 c.nr_verts = 1;
00081 brw_emit_point_setup( &c );
00082 break;
00083
00084 case SF_UNFILLED_TRIS:
00085 default:
00086 assert(0);
00087 return;
00088 }
00089
00090
00091
00092
00093
00094 program = brw_get_program(&c.func, &program_size);
00095
00096
00097
00098 brw->sf.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_SF_PROG],
00099 &c.key,
00100 sizeof(c.key),
00101 program,
00102 program_size,
00103 &c.prog_data,
00104 &brw->sf.prog_data );
00105 }
00106
00107
00108 static boolean search_cache( struct brw_context *brw,
00109 struct brw_sf_prog_key *key )
00110 {
00111 return brw_search_cache(&brw->cache[BRW_SF_PROG],
00112 key, sizeof(*key),
00113 &brw->sf.prog_data,
00114 &brw->sf.prog_gs_offset);
00115 }
00116
00117
00118
00119
00120 static void upload_sf_prog( struct brw_context *brw )
00121 {
00122 const struct brw_fragment_program *fs = brw->attribs.FragmentProgram;
00123 struct brw_sf_prog_key key;
00124 struct tgsi_parse_context parse;
00125 int i, done = 0;
00126
00127
00128 memset(&key, 0, sizeof(key));
00129
00130
00131
00132
00133 key.vp_output_count = brw->vs.prog_data->outputs_written;
00134
00135
00136 key.fp_input_count = brw->attribs.FragmentProgram->info.file_max[TGSI_FILE_INPUT] + 1;
00137
00138
00139
00140 switch (brw->reduced_primitive) {
00141 case PIPE_PRIM_TRIANGLES:
00142
00143
00144
00145 key.primitive = SF_TRIANGLES;
00146 break;
00147 case PIPE_PRIM_LINES:
00148 key.primitive = SF_LINES;
00149 break;
00150 case PIPE_PRIM_POINTS:
00151 key.primitive = SF_POINTS;
00152 break;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162 tgsi_parse_init( &parse, fs->program.tokens );
00163 while( !done &&
00164 !tgsi_parse_end_of_tokens( &parse ) )
00165 {
00166 tgsi_parse_token( &parse );
00167
00168 switch( parse.FullToken.Token.Type ) {
00169 case TGSI_TOKEN_TYPE_DECLARATION:
00170 if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
00171 {
00172 int first = parse.FullToken.FullDeclaration.DeclarationRange.First;
00173 int last = parse.FullToken.FullDeclaration.DeclarationRange.Last;
00174 int interp_mode = parse.FullToken.FullDeclaration.Declaration.Interpolate;
00175
00176
00177
00178 debug_printf("fs input %d..%d interp mode %d\n", first, last, interp_mode);
00179
00180 switch (interp_mode) {
00181 case TGSI_INTERPOLATE_CONSTANT:
00182 for (i = first; i <= last; i++)
00183 key.const_mask |= (1 << i);
00184 break;
00185 case TGSI_INTERPOLATE_LINEAR:
00186 for (i = first; i <= last; i++)
00187 key.linear_mask |= (1 << i);
00188 break;
00189 case TGSI_INTERPOLATE_PERSPECTIVE:
00190 for (i = first; i <= last; i++)
00191 key.persp_mask |= (1 << i);
00192 break;
00193 default:
00194 break;
00195 }
00196
00197
00198
00199
00200 }
00201 break;
00202 default:
00203 done = 1;
00204 break;
00205 }
00206 }
00207
00208
00209
00210
00211 key.persp_mask <<= 1;
00212 key.linear_mask <<= 1;
00213 key.linear_mask |= 1;
00214 key.const_mask <<= 1;
00215
00216 debug_printf("key.persp_mask: %x\n", key.persp_mask);
00217 debug_printf("key.linear_mask: %x\n", key.linear_mask);
00218 debug_printf("key.const_mask: %x\n", key.const_mask);
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 if (!search_cache(brw, &key))
00232 compile_sf_prog( brw, &key );
00233 }
00234
00235
00236 const struct brw_tracked_state brw_sf_prog = {
00237 .dirty = {
00238 .brw = (BRW_NEW_RASTERIZER |
00239 BRW_NEW_REDUCED_PRIMITIVE |
00240 BRW_NEW_VS |
00241 BRW_NEW_FS),
00242 .cache = 0,
00243 },
00244 .update = upload_sf_prog
00245 };
00246
00247
00248
00249 #if 0
00250
00251
00252
00253 static void update_sf_linkage( struct brw_context *brw )
00254 {
00255 const struct brw_vertex_program *vs = brw->attribs.VertexProgram;
00256 const struct brw_fragment_program *fs = brw->attribs.FragmentProgram;
00257 struct pipe_setup_linkage state;
00258 struct tgsi_parse_context parse;
00259
00260 int i, j;
00261 int nr_vp_outputs = 0;
00262 int done = 0;
00263
00264 struct {
00265 unsigned semantic:8;
00266 unsigned semantic_index:16;
00267 } fp_semantic[32], vp_semantic[32];
00268
00269 memset(&state, 0, sizeof(state));
00270
00271 state.fp_input_count = 0;
00272
00273
00274
00275
00276
00277
00278 assert(state.fp_input_count == fs->program.num_inputs);
00279
00280
00281
00282
00283 done = 0;
00284 tgsi_parse_init( &parse, vs->program.tokens );
00285 while( !done &&
00286 !tgsi_parse_end_of_tokens( &parse ) )
00287 {
00288 tgsi_parse_token( &parse );
00289
00290 switch( parse.FullToken.Token.Type ) {
00291 case TGSI_TOKEN_TYPE_DECLARATION:
00292 if (parse.FullToken.FullDeclaration.Declaration.File == TGSI_FILE_INPUT)
00293 {
00294 int first = parse.FullToken.FullDeclaration.DeclarationRange.First;
00295 int last = parse.FullToken.FullDeclaration.DeclarationRange.Last;
00296
00297 for (i = first; i < last; i++) {
00298 vp_semantic[i].semantic =
00299 parse.FullToken.FullDeclaration.Semantic.SemanticName;
00300 vp_semantic[i].semantic_index =
00301 parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
00302 }
00303
00304 assert(last > nr_vp_outputs);
00305 nr_vp_outputs = last;
00306 }
00307 break;
00308 default:
00309 done = 1;
00310 break;
00311 }
00312 }
00313
00314
00315
00316
00317 for (i = 0; i< state.fp_input_count; i++) {
00318 for (j = 0; j < nr_vp_outputs; j++) {
00319 if (fp_semantic[i].semantic == vp_semantic[j].semantic &&
00320 fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) {
00321 state.fp_input[i].vp_output = j;
00322 }
00323 }
00324 if (fp_semantic[i].semantic == TGSI_SEMANTIC_COLOR) {
00325 for (j = 0; j < nr_vp_outputs; j++) {
00326 if (TGSI_SEMANTIC_BCOLOR == vp_semantic[j].semantic &&
00327 fp_semantic[i].semantic_index == vp_semantic[j].semantic_index) {
00328 state.fp_input[i].bf_vp_output = j;
00329 }
00330 }
00331 }
00332 }
00333
00334 if (memcmp(&brw->sf.linkage, &state, sizeof(state)) != 0) {
00335 brw->sf.linkage = state;
00336 brw->state.dirty.brw |= BRW_NEW_SF_LINKAGE;
00337 }
00338 }
00339
00340
00341 const struct brw_tracked_state brw_sf_linkage = {
00342 .dirty = {
00343 .brw = (BRW_NEW_VS |
00344 BRW_NEW_FS),
00345 .cache = 0,
00346 },
00347 .update = update_sf_linkage
00348 };
00349
00350
00351 #endif