• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics to
4  develop this 3D driver.
5 
6  Permission is hereby granted, free of charge, to any person obtaining
7  a copy of this software and associated documentation files (the
8  "Software"), to deal in the Software without restriction, including
9  without limitation the rights to use, copy, modify, merge, publish,
10  distribute, sublicense, and/or sell copies of the Software, and to
11  permit persons to whom the Software is furnished to do so, subject to
12  the following conditions:
13 
14  The above copyright notice and this permission notice (including the
15  next paragraph) shall be included in all copies or substantial
16  portions of the Software.
17 
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26  **********************************************************************/
27  /*
28   * Authors:
29   *   Keith Whitwell <keithw@vmware.com>
30   */
31 
32 #include "main/macros.h"
33 #include "main/enums.h"
34 
35 #include "intel_batchbuffer.h"
36 
37 #include "brw_defines.h"
38 #include "brw_context.h"
39 #include "brw_eu.h"
40 #include "brw_util.h"
41 #include "brw_state.h"
42 #include "brw_clip.h"
43 
44 #include "util/ralloc.h"
45 
46 #define FRONT_UNFILLED_BIT  0x1
47 #define BACK_UNFILLED_BIT   0x2
48 
49 
compile_clip_prog(struct brw_context * brw,struct brw_clip_prog_key * key)50 static void compile_clip_prog( struct brw_context *brw,
51 			     struct brw_clip_prog_key *key )
52 {
53    struct brw_clip_compile c;
54    const GLuint *program;
55    void *mem_ctx;
56    GLuint program_size;
57 
58    memset(&c, 0, sizeof(c));
59 
60    mem_ctx = ralloc_context(NULL);
61 
62    /* Begin the compilation:
63     */
64    brw_init_codegen(&brw->screen->devinfo, &c.func, mem_ctx);
65 
66    c.func.single_program_flow = 1;
67 
68    c.key = *key;
69    c.vue_map = brw->vue_map_geom_out;
70 
71    /* nr_regs is the number of registers filled by reading data from the VUE.
72     * This program accesses the entire VUE, so nr_regs needs to be the size of
73     * the VUE (measured in pairs, since two slots are stored in each
74     * register).
75     */
76    c.nr_regs = (c.vue_map.num_slots + 1)/2;
77 
78    c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
79 
80    /* For some reason the thread is spawned with only 4 channels
81     * unmasked.
82     */
83    brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE);
84 
85 
86    /* Would ideally have the option of producing a program which could
87     * do all three:
88     */
89    switch (key->primitive) {
90    case GL_TRIANGLES:
91       if (key->do_unfilled)
92 	 brw_emit_unfilled_clip( &c );
93       else
94 	 brw_emit_tri_clip( &c );
95       break;
96    case GL_LINES:
97       brw_emit_line_clip( &c );
98       break;
99    case GL_POINTS:
100       brw_emit_point_clip( &c );
101       break;
102    default:
103       unreachable("not reached");
104    }
105 
106    brw_compact_instructions(&c.func, 0, 0, NULL);
107 
108    /* get the program
109     */
110    program = brw_get_program(&c.func, &program_size);
111 
112    if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) {
113       fprintf(stderr, "clip:\n");
114       brw_disassemble(&brw->screen->devinfo, c.func.store,
115                       0, program_size, stderr);
116       fprintf(stderr, "\n");
117    }
118 
119    brw_upload_cache(&brw->cache,
120 		    BRW_CACHE_CLIP_PROG,
121 		    &c.key, sizeof(c.key),
122 		    program, program_size,
123 		    &c.prog_data, sizeof(c.prog_data),
124 		    &brw->clip.prog_offset, &brw->clip.prog_data);
125    ralloc_free(mem_ctx);
126 }
127 
128 /* Calculate interpolants for triangle and line rasterization.
129  */
130 void
brw_upload_clip_prog(struct brw_context * brw)131 brw_upload_clip_prog(struct brw_context *brw)
132 {
133    struct gl_context *ctx = &brw->ctx;
134    struct brw_clip_prog_key key;
135 
136    if (!brw_state_dirty(brw,
137                         _NEW_BUFFERS |
138                         _NEW_LIGHT |
139                         _NEW_POLYGON |
140                         _NEW_TRANSFORM,
141                         BRW_NEW_BLORP |
142                         BRW_NEW_FS_PROG_DATA |
143                         BRW_NEW_REDUCED_PRIMITIVE |
144                         BRW_NEW_VUE_MAP_GEOM_OUT))
145       return;
146 
147    memset(&key, 0, sizeof(key));
148 
149    /* Populate the key:
150     */
151 
152    /* BRW_NEW_FS_PROG_DATA */
153    const struct brw_wm_prog_data *wm_prog_data =
154       brw_wm_prog_data(brw->wm.base.prog_data);
155    if (wm_prog_data) {
156       key.contains_flat_varying = wm_prog_data->contains_flat_varying;
157       key.contains_noperspective_varying =
158          wm_prog_data->contains_noperspective_varying;
159       key.interp_mode = wm_prog_data->interp_mode;
160    }
161 
162    /* BRW_NEW_REDUCED_PRIMITIVE */
163    key.primitive = brw->reduced_primitive;
164    /* BRW_NEW_VUE_MAP_GEOM_OUT */
165    key.attrs = brw->vue_map_geom_out.slots_valid;
166 
167    /* _NEW_LIGHT */
168    key.pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
169    /* _NEW_TRANSFORM (also part of VUE map)*/
170    if (ctx->Transform.ClipPlanesEnabled)
171       key.nr_userclip = _mesa_logbase2(ctx->Transform.ClipPlanesEnabled) + 1;
172 
173    if (brw->gen == 5)
174        key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
175    else
176        key.clip_mode = BRW_CLIPMODE_NORMAL;
177 
178    /* _NEW_POLYGON */
179    if (key.primitive == GL_TRIANGLES) {
180       if (ctx->Polygon.CullFlag &&
181 	  ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
182 	 key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
183       else {
184 	 GLuint fill_front = CLIP_CULL;
185 	 GLuint fill_back = CLIP_CULL;
186 	 GLuint offset_front = 0;
187 	 GLuint offset_back = 0;
188 
189 	 if (!ctx->Polygon.CullFlag ||
190 	     ctx->Polygon.CullFaceMode != GL_FRONT) {
191 	    switch (ctx->Polygon.FrontMode) {
192 	    case GL_FILL:
193 	       fill_front = CLIP_FILL;
194 	       offset_front = 0;
195 	       break;
196 	    case GL_LINE:
197 	       fill_front = CLIP_LINE;
198 	       offset_front = ctx->Polygon.OffsetLine;
199 	       break;
200 	    case GL_POINT:
201 	       fill_front = CLIP_POINT;
202 	       offset_front = ctx->Polygon.OffsetPoint;
203 	       break;
204 	    }
205 	 }
206 
207 	 if (!ctx->Polygon.CullFlag ||
208 	     ctx->Polygon.CullFaceMode != GL_BACK) {
209 	    switch (ctx->Polygon.BackMode) {
210 	    case GL_FILL:
211 	       fill_back = CLIP_FILL;
212 	       offset_back = 0;
213 	       break;
214 	    case GL_LINE:
215 	       fill_back = CLIP_LINE;
216 	       offset_back = ctx->Polygon.OffsetLine;
217 	       break;
218 	    case GL_POINT:
219 	       fill_back = CLIP_POINT;
220 	       offset_back = ctx->Polygon.OffsetPoint;
221 	       break;
222 	    }
223 	 }
224 
225 	 if (ctx->Polygon.BackMode != GL_FILL ||
226 	     ctx->Polygon.FrontMode != GL_FILL) {
227 	    key.do_unfilled = 1;
228 
229 	    /* Most cases the fixed function units will handle.  Cases where
230 	     * one or more polygon faces are unfilled will require help:
231 	     */
232 	    key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
233 
234 	    if (offset_back || offset_front) {
235 	       /* _NEW_POLYGON, _NEW_BUFFERS */
236 	       key.offset_units = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD * 2;
237 	       key.offset_factor = ctx->Polygon.OffsetFactor * ctx->DrawBuffer->_MRD;
238 	       key.offset_clamp = ctx->Polygon.OffsetClamp * ctx->DrawBuffer->_MRD;
239 	    }
240 
241 	    if (!ctx->Polygon._FrontBit) {
242 	       key.fill_ccw = fill_front;
243 	       key.fill_cw = fill_back;
244 	       key.offset_ccw = offset_front;
245 	       key.offset_cw = offset_back;
246 	       if (ctx->Light.Model.TwoSide &&
247 		   key.fill_cw != CLIP_CULL)
248 		  key.copy_bfc_cw = 1;
249 	    } else {
250 	       key.fill_cw = fill_front;
251 	       key.fill_ccw = fill_back;
252 	       key.offset_cw = offset_front;
253 	       key.offset_ccw = offset_back;
254 	       if (ctx->Light.Model.TwoSide &&
255 		   key.fill_ccw != CLIP_CULL)
256 		  key.copy_bfc_ccw = 1;
257 	    }
258 	 }
259       }
260    }
261 
262    if (!brw_search_cache(&brw->cache, BRW_CACHE_CLIP_PROG,
263 			 &key, sizeof(key),
264 			 &brw->clip.prog_offset, &brw->clip.prog_data)) {
265       compile_clip_prog( brw, &key );
266    }
267 }
268