Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5564 | serge | 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 |
||
30 | */ |
||
31 | |||
32 | #include "main/glheader.h" |
||
33 | #include "main/macros.h" |
||
34 | #include "main/enums.h" |
||
35 | |||
36 | #include "intel_batchbuffer.h" |
||
37 | |||
38 | #include "brw_defines.h" |
||
39 | #include "brw_context.h" |
||
40 | #include "brw_eu.h" |
||
41 | #include "brw_util.h" |
||
42 | #include "brw_state.h" |
||
43 | #include "brw_clip.h" |
||
44 | |||
45 | #include "util/ralloc.h" |
||
46 | |||
47 | #define FRONT_UNFILLED_BIT 0x1 |
||
48 | #define BACK_UNFILLED_BIT 0x2 |
||
49 | |||
50 | |||
51 | static void compile_clip_prog( struct brw_context *brw, |
||
52 | struct brw_clip_prog_key *key ) |
||
53 | { |
||
54 | struct brw_clip_compile c; |
||
55 | const GLuint *program; |
||
56 | void *mem_ctx; |
||
57 | GLuint program_size; |
||
58 | |||
59 | memset(&c, 0, sizeof(c)); |
||
60 | |||
61 | mem_ctx = ralloc_context(NULL); |
||
62 | |||
63 | /* Begin the compilation: |
||
64 | */ |
||
65 | brw_init_codegen(brw->intelScreen->devinfo, &c.func, mem_ctx); |
||
66 | |||
67 | c.func.single_program_flow = 1; |
||
68 | |||
69 | c.key = *key; |
||
70 | c.vue_map = brw->vue_map_geom_out; |
||
71 | |||
72 | c.has_flat_shading = |
||
73 | brw_any_flat_varyings(&key->interpolation_mode); |
||
74 | c.has_noperspective_shading = |
||
75 | brw_any_noperspective_varyings(&key->interpolation_mode); |
||
76 | |||
77 | /* nr_regs is the number of registers filled by reading data from the VUE. |
||
78 | * This program accesses the entire VUE, so nr_regs needs to be the size of |
||
79 | * the VUE (measured in pairs, since two slots are stored in each |
||
80 | * register). |
||
81 | */ |
||
82 | c.nr_regs = (c.vue_map.num_slots + 1)/2; |
||
83 | |||
84 | c.prog_data.clip_mode = c.key.clip_mode; /* XXX */ |
||
85 | |||
86 | /* For some reason the thread is spawned with only 4 channels |
||
87 | * unmasked. |
||
88 | */ |
||
89 | brw_set_default_mask_control(&c.func, BRW_MASK_DISABLE); |
||
90 | |||
91 | |||
92 | /* Would ideally have the option of producing a program which could |
||
93 | * do all three: |
||
94 | */ |
||
95 | switch (key->primitive) { |
||
96 | case GL_TRIANGLES: |
||
97 | if (key->do_unfilled) |
||
98 | brw_emit_unfilled_clip( &c ); |
||
99 | else |
||
100 | brw_emit_tri_clip( &c ); |
||
101 | break; |
||
102 | case GL_LINES: |
||
103 | brw_emit_line_clip( &c ); |
||
104 | break; |
||
105 | case GL_POINTS: |
||
106 | brw_emit_point_clip( &c ); |
||
107 | break; |
||
108 | default: |
||
109 | unreachable("not reached"); |
||
110 | } |
||
111 | |||
112 | brw_compact_instructions(&c.func, 0, 0, NULL); |
||
113 | |||
114 | /* get the program |
||
115 | */ |
||
116 | program = brw_get_program(&c.func, &program_size); |
||
117 | |||
118 | if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) { |
||
119 | fprintf(stderr, "clip:\n"); |
||
120 | brw_disassemble(brw->intelScreen->devinfo, c.func.store, |
||
121 | 0, program_size, stderr); |
||
122 | fprintf(stderr, "\n"); |
||
123 | } |
||
124 | |||
125 | brw_upload_cache(&brw->cache, |
||
126 | BRW_CACHE_CLIP_PROG, |
||
127 | &c.key, sizeof(c.key), |
||
128 | program, program_size, |
||
129 | &c.prog_data, sizeof(c.prog_data), |
||
130 | &brw->clip.prog_offset, &brw->clip.prog_data); |
||
131 | ralloc_free(mem_ctx); |
||
132 | } |
||
133 | |||
134 | /* Calculate interpolants for triangle and line rasterization. |
||
135 | */ |
||
136 | static void |
||
137 | brw_upload_clip_prog(struct brw_context *brw) |
||
138 | { |
||
139 | struct gl_context *ctx = &brw->ctx; |
||
140 | struct brw_clip_prog_key key; |
||
141 | |||
142 | memset(&key, 0, sizeof(key)); |
||
143 | |||
144 | /* Populate the key: |
||
145 | */ |
||
146 | |||
147 | /* BRW_NEW_INTERPOLATION_MAP */ |
||
148 | key.interpolation_mode = brw->interpolation_mode; |
||
149 | |||
150 | /* BRW_NEW_REDUCED_PRIMITIVE */ |
||
151 | key.primitive = brw->reduced_primitive; |
||
152 | /* BRW_NEW_VUE_MAP_GEOM_OUT */ |
||
153 | key.attrs = brw->vue_map_geom_out.slots_valid; |
||
154 | |||
155 | /* _NEW_LIGHT */ |
||
156 | key.pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION); |
||
157 | /* _NEW_TRANSFORM (also part of VUE map)*/ |
||
158 | if (ctx->Transform.ClipPlanesEnabled) |
||
159 | key.nr_userclip = _mesa_logbase2(ctx->Transform.ClipPlanesEnabled) + 1; |
||
160 | |||
161 | if (brw->gen == 5) |
||
162 | key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP; |
||
163 | else |
||
164 | key.clip_mode = BRW_CLIPMODE_NORMAL; |
||
165 | |||
166 | /* _NEW_POLYGON */ |
||
167 | if (key.primitive == GL_TRIANGLES) { |
||
168 | if (ctx->Polygon.CullFlag && |
||
169 | ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) |
||
170 | key.clip_mode = BRW_CLIPMODE_REJECT_ALL; |
||
171 | else { |
||
172 | GLuint fill_front = CLIP_CULL; |
||
173 | GLuint fill_back = CLIP_CULL; |
||
174 | GLuint offset_front = 0; |
||
175 | GLuint offset_back = 0; |
||
176 | |||
177 | if (!ctx->Polygon.CullFlag || |
||
178 | ctx->Polygon.CullFaceMode != GL_FRONT) { |
||
179 | switch (ctx->Polygon.FrontMode) { |
||
180 | case GL_FILL: |
||
181 | fill_front = CLIP_FILL; |
||
182 | offset_front = 0; |
||
183 | break; |
||
184 | case GL_LINE: |
||
185 | fill_front = CLIP_LINE; |
||
186 | offset_front = ctx->Polygon.OffsetLine; |
||
187 | break; |
||
188 | case GL_POINT: |
||
189 | fill_front = CLIP_POINT; |
||
190 | offset_front = ctx->Polygon.OffsetPoint; |
||
191 | break; |
||
192 | } |
||
193 | } |
||
194 | |||
195 | if (!ctx->Polygon.CullFlag || |
||
196 | ctx->Polygon.CullFaceMode != GL_BACK) { |
||
197 | switch (ctx->Polygon.BackMode) { |
||
198 | case GL_FILL: |
||
199 | fill_back = CLIP_FILL; |
||
200 | offset_back = 0; |
||
201 | break; |
||
202 | case GL_LINE: |
||
203 | fill_back = CLIP_LINE; |
||
204 | offset_back = ctx->Polygon.OffsetLine; |
||
205 | break; |
||
206 | case GL_POINT: |
||
207 | fill_back = CLIP_POINT; |
||
208 | offset_back = ctx->Polygon.OffsetPoint; |
||
209 | break; |
||
210 | } |
||
211 | } |
||
212 | |||
213 | if (ctx->Polygon.BackMode != GL_FILL || |
||
214 | ctx->Polygon.FrontMode != GL_FILL) { |
||
215 | key.do_unfilled = 1; |
||
216 | |||
217 | /* Most cases the fixed function units will handle. Cases where |
||
218 | * one or more polygon faces are unfilled will require help: |
||
219 | */ |
||
220 | key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; |
||
221 | |||
222 | if (offset_back || offset_front) { |
||
223 | /* _NEW_POLYGON, _NEW_BUFFERS */ |
||
224 | key.offset_units = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD * 2; |
||
225 | key.offset_factor = ctx->Polygon.OffsetFactor * ctx->DrawBuffer->_MRD; |
||
226 | } |
||
227 | |||
228 | if (!ctx->Polygon._FrontBit) { |
||
229 | key.fill_ccw = fill_front; |
||
230 | key.fill_cw = fill_back; |
||
231 | key.offset_ccw = offset_front; |
||
232 | key.offset_cw = offset_back; |
||
233 | if (ctx->Light.Model.TwoSide && |
||
234 | key.fill_cw != CLIP_CULL) |
||
235 | key.copy_bfc_cw = 1; |
||
236 | } else { |
||
237 | key.fill_cw = fill_front; |
||
238 | key.fill_ccw = fill_back; |
||
239 | key.offset_cw = offset_front; |
||
240 | key.offset_ccw = offset_back; |
||
241 | if (ctx->Light.Model.TwoSide && |
||
242 | key.fill_ccw != CLIP_CULL) |
||
243 | key.copy_bfc_ccw = 1; |
||
244 | } |
||
245 | } |
||
246 | } |
||
247 | } |
||
248 | |||
249 | if (!brw_search_cache(&brw->cache, BRW_CACHE_CLIP_PROG, |
||
250 | &key, sizeof(key), |
||
251 | &brw->clip.prog_offset, &brw->clip.prog_data)) { |
||
252 | compile_clip_prog( brw, &key ); |
||
253 | } |
||
254 | } |
||
255 | |||
256 | |||
257 | const struct brw_tracked_state brw_clip_prog = { |
||
258 | .dirty = { |
||
259 | .mesa = _NEW_BUFFERS | |
||
260 | _NEW_LIGHT | |
||
261 | _NEW_POLYGON | |
||
262 | _NEW_TRANSFORM, |
||
263 | .brw = BRW_NEW_INTERPOLATION_MAP | |
||
264 | BRW_NEW_REDUCED_PRIMITIVE | |
||
265 | BRW_NEW_VUE_MAP_GEOM_OUT, |
||
266 | }, |
||
267 | .emit = brw_upload_clip_prog |
||
268 | }; |