brw_sf.c

Go to the documentation of this file.
00001 /*
00002  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
00003  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
00004  develop this 3D driver.
00005 
00006  Permission is hereby granted, free of charge, to any person obtaining
00007  a copy of this software and associated documentation files (the
00008  "Software"), to deal in the Software without restriction, including
00009  without limitation the rights to use, copy, modify, merge, publish,
00010  distribute, sublicense, and/or sell copies of the Software, and to
00011  permit persons to whom the Software is furnished to do so, subject to
00012  the following conditions:
00013 
00014  The above copyright notice and this permission notice (including the
00015  next paragraph) shall be included in all copies or substantial
00016  portions of the Software.
00017 
00018  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00019  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00021  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
00022  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00023  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00024  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025 
00026  **********************************************************************/
00027  /*
00028   * Authors:
00029   *   Keith Whitwell <keith@tungstengraphics.com>
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    /* Begin the compilation:
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; /* +1 for position */
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    /* Which primitive?  Or all three?
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    /* get the program
00093     */
00094    program = brw_get_program(&c.func, &program_size);
00095 
00096    /* Upload
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 /* Calculate interpolants for triangle and line rasterization.
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    /* Populate the key, noting state dependencies:
00131     */
00132    /* CACHE_NEW_VS_PROG */
00133    key.vp_output_count = brw->vs.prog_data->outputs_written;
00134 
00135    /* BRW_NEW_FS */
00136    key.fp_input_count = brw->attribs.FragmentProgram->info.file_max[TGSI_FILE_INPUT] + 1;
00137 
00138 
00139    /* BRW_NEW_REDUCED_PRIMITIVE */
00140    switch (brw->reduced_primitive) {
00141    case PIPE_PRIM_TRIANGLES:
00142 //      if (key.attrs & (1<<VERT_RESULT_EDGE))
00143 //       key.primitive = SF_UNFILLED_TRIS;
00144 //      else
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    /* Scan fp inputs to figure out what interpolation modes are
00158     * required for each incoming vp output.  There is an assumption
00159     * that the state tracker makes sure there is a 1:1 linkage between
00160     * these sets of attributes (XXX: position??)
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             //int semantic = parse.FullToken.FullDeclaration.Semantic.SemanticName;
00176             //int semantic_index = parse.FullToken.FullDeclaration.Semantic.SemanticIndex;
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             /* Also need stuff for flat shading, twosided color.
00198              */
00199 
00200          }
00201          break;
00202       default:
00203          done = 1;
00204          break;
00205       }
00206    }
00207 
00208    /* Hack: Adjust for position.  Optimize away when not required (ie
00209     * for perspective interpolation).
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 //   key.do_point_sprite = brw->attribs.Point->PointSprite;
00222 //   key.SpriteOrigin = brw->attribs.Point->SpriteOrigin;
00223 
00224 //   key.do_flat_shading = (brw->attribs.Raster->flatshade);
00225 //   key.do_twoside_color = (brw->attribs.Light->Enabled && brw->attribs.Light->Model.TwoSide);
00226 
00227 //   if (key.do_twoside_color)
00228 //      key.frontface_ccw = (brw->attribs.Polygon->FrontFace == GL_CCW);
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 /* Build a struct like the one we'd like the state tracker to pass to
00251  * us.
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    /* Then scan vp outputs
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    /* Now match based on semantic information.
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

Generated on Tue Sep 29 06:25:16 2009 for Gallium3D by  doxygen 1.5.4