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 #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
00055
00056 brw_init_compile(&c.func);
00057
00058 c.func.single_program_flow = 1;
00059
00060 c.key = *key;
00061
00062
00063
00064
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;
00076 c.nr_bytes = c.nr_regs * REG_SIZE;
00077
00078 c.prog_data.clip_mode = c.key.clip_mode;
00079
00080
00081
00082
00083 brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
00084
00085
00086
00087
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
00112
00113 program = brw_get_program(&c.func, &program_size);
00114
00115
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
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
00148
00149
00150 key.primitive = brw->reduced_primitive;
00151
00152 key.attrs = brw->vs.prog_data->outputs_written;
00153
00154 key.do_flat_shading = (brw->attribs.Raster->flatshade);
00155
00156 key.nr_userclip = brw->attribs.Clip.nr;
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
00170
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 };