brw_clip.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 #include "brw_defines.h"
00033 #include "brw_context.h"
00034 #include "brw_eu.h"
00035 #include "brw_util.h"
00036 #include "brw_state.h"
00037 #include "brw_clip.h"
00038 
00039 #define FRONT_UNFILLED_BIT  0x1
00040 #define BACK_UNFILLED_BIT   0x2
00041 
00042 
00043 static void compile_clip_prog( struct brw_context *brw,
00044                              struct brw_clip_prog_key *key )
00045 {
00046    struct brw_clip_compile c;
00047    const unsigned *program;
00048    unsigned program_size;
00049    unsigned delta;
00050    unsigned i;
00051 
00052    memset(&c, 0, sizeof(c));
00053 
00054    /* Begin the compilation:
00055     */
00056    brw_init_compile(&c.func);
00057 
00058    c.func.single_program_flow = 1;
00059 
00060    c.key = *key;
00061 
00062 
00063    /* Need to locate the two positions present in vertex + header.
00064     * These are currently hardcoded:
00065     */
00066    c.header_position_offset = ATTR_SIZE;
00067 
00068    for (i = 0, delta = REG_SIZE; i < PIPE_MAX_SHADER_OUTPUTS; i++)
00069       if (c.key.attrs & (1<<i)) {
00070          c.offset[i] = delta;
00071          delta += ATTR_SIZE;
00072       }
00073 
00074    c.nr_attrs = brw_count_bits(c.key.attrs);
00075    c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
00076    c.nr_bytes = c.nr_regs * REG_SIZE;
00077 
00078    c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
00079 
00080    /* For some reason the thread is spawned with only 4 channels
00081     * unmasked.
00082     */
00083    brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
00084 
00085 
00086    /* Would ideally have the option of producing a program which could
00087     * do all three:
00088     */
00089    switch (key->primitive) {
00090    case PIPE_PRIM_TRIANGLES:
00091 #if 0
00092       if (key->do_unfilled)
00093          brw_emit_unfilled_clip( &c );
00094       else
00095 #endif
00096          brw_emit_tri_clip( &c );
00097       break;
00098    case PIPE_PRIM_LINES:
00099       brw_emit_line_clip( &c );
00100       break;
00101    case PIPE_PRIM_POINTS:
00102       brw_emit_point_clip( &c );
00103       break;
00104    default:
00105       assert(0);
00106       return;
00107    }
00108 
00109 
00110 
00111    /* get the program
00112     */
00113    program = brw_get_program(&c.func, &program_size);
00114 
00115    /* Upload
00116     */
00117    brw->clip.prog_gs_offset = brw_upload_cache( &brw->cache[BRW_CLIP_PROG],
00118                                                 &c.key,
00119                                                 sizeof(c.key),
00120                                                 program,
00121                                                 program_size,
00122                                                 &c.prog_data,
00123                                                 &brw->clip.prog_data );
00124 }
00125 
00126 
00127 static boolean search_cache( struct brw_context *brw,
00128                                struct brw_clip_prog_key *key )
00129 {
00130    return brw_search_cache(&brw->cache[BRW_CLIP_PROG],
00131                            key, sizeof(*key),
00132                            &brw->clip.prog_data,
00133                            &brw->clip.prog_gs_offset);
00134 }
00135 
00136 
00137 
00138 
00139 /* Calculate interpolants for triangle and line rasterization.
00140  */
00141 static void upload_clip_prog(struct brw_context *brw)
00142 {
00143    struct brw_clip_prog_key key;
00144 
00145    memset(&key, 0, sizeof(key));
00146 
00147    /* Populate the key:
00148     */
00149    /* BRW_NEW_REDUCED_PRIMITIVE */
00150    key.primitive = brw->reduced_primitive;
00151    /* CACHE_NEW_VS_PROG */
00152    key.attrs = brw->vs.prog_data->outputs_written;
00153    /* BRW_NEW_RASTER */
00154    key.do_flat_shading = (brw->attribs.Raster->flatshade);
00155    /* BRW_NEW_CLIP */
00156    key.nr_userclip = brw->attribs.Clip.nr; /* XXX */
00157 
00158 #if 0
00159    key.clip_mode = BRW_CLIPMODE_NORMAL;
00160 
00161    if (key.primitive == PIPE_PRIM_TRIANGLES) {
00162       if (brw->attribs.Raster->cull_mode == PIPE_WINDING_BOTH)
00163          key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
00164       else {
00165          if (brw->attribs.Raster->fill_cw != PIPE_POLYGON_MODE_FILL ||
00166              brw->attribs.Raster->fill_ccw != PIPE_POLYGON_MODE_FILL)
00167             key.do_unfilled = 1;
00168 
00169          /* Most cases the fixed function units will handle.  Cases where
00170           * one or more polygon faces are unfilled will require help:
00171           */
00172          if (key.do_unfilled) {
00173             key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
00174 
00175             if (brw->attribs.Raster->offset_cw ||
00176                 brw->attribs.Raster->offset_ccw) {
00177                key.offset_units = brw->attribs.Raster->offset_units;
00178                key.offset_factor = brw->attribs.Raster->offset_scale;
00179             }
00180             key.fill_ccw = brw->attribs.Raster->fill_ccw;
00181             key.fill_cw = brw->attribs.Raster->fill_cw;
00182             key.offset_ccw = brw->attribs.Raster->offset_ccw;
00183             key.offset_cw = brw->attribs.Raster->offset_cw;
00184             if (brw->attribs.Raster->light_twoside &&
00185                 key.fill_cw != CLIP_CULL)
00186                key.copy_bfc_cw = 1;
00187          }
00188       }
00189    }
00190 #else
00191    key.clip_mode = BRW_CLIPMODE_ACCEPT_ALL;
00192 #endif
00193 
00194    if (!search_cache(brw, &key))
00195       compile_clip_prog( brw, &key );
00196 }
00197 
00198 const struct brw_tracked_state brw_clip_prog = {
00199    .dirty = {
00200       .brw   = (BRW_NEW_RASTERIZER |
00201                 BRW_NEW_CLIP |
00202                 BRW_NEW_REDUCED_PRIMITIVE),
00203       .cache = CACHE_NEW_VS_PROG
00204    },
00205    .update = upload_clip_prog
00206 };

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