Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | Copyright (C) Intel Corp. 2006. All Rights Reserved. |
||
3 | Intel funded Tungsten Graphics (http://www.tungstengraphics.com) 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 "glsl/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 | GLuint i; |
||
59 | |||
60 | memset(&c, 0, sizeof(c)); |
||
61 | |||
62 | mem_ctx = ralloc_context(NULL); |
||
63 | |||
64 | /* Begin the compilation: |
||
65 | */ |
||
66 | brw_init_compile(brw, &c.func, mem_ctx); |
||
67 | |||
68 | c.func.single_program_flow = 1; |
||
69 | |||
70 | c.key = *key; |
||
71 | c.vue_map = brw->vue_map_geom_out; |
||
72 | |||
73 | /* nr_regs is the number of registers filled by reading data from the VUE. |
||
74 | * This program accesses the entire VUE, so nr_regs needs to be the size of |
||
75 | * the VUE (measured in pairs, since two slots are stored in each |
||
76 | * register). |
||
77 | */ |
||
78 | c.nr_regs = (c.vue_map.num_slots + 1)/2; |
||
79 | |||
80 | c.prog_data.clip_mode = c.key.clip_mode; /* XXX */ |
||
81 | |||
82 | /* For some reason the thread is spawned with only 4 channels |
||
83 | * unmasked. |
||
84 | */ |
||
85 | brw_set_mask_control(&c.func, BRW_MASK_DISABLE); |
||
86 | |||
87 | |||
88 | /* Would ideally have the option of producing a program which could |
||
89 | * do all three: |
||
90 | */ |
||
91 | switch (key->primitive) { |
||
92 | case GL_TRIANGLES: |
||
93 | if (key->do_unfilled) |
||
94 | brw_emit_unfilled_clip( &c ); |
||
95 | else |
||
96 | brw_emit_tri_clip( &c ); |
||
97 | break; |
||
98 | case GL_LINES: |
||
99 | brw_emit_line_clip( &c ); |
||
100 | break; |
||
101 | case GL_POINTS: |
||
102 | brw_emit_point_clip( &c ); |
||
103 | break; |
||
104 | default: |
||
105 | assert(0); |
||
106 | return; |
||
107 | } |
||
108 | |||
109 | |||
110 | |||
111 | /* get the program |
||
112 | */ |
||
113 | program = brw_get_program(&c.func, &program_size); |
||
114 | |||
115 | if (unlikely(INTEL_DEBUG & DEBUG_CLIP)) { |
||
116 | printf("clip:\n"); |
||
117 | for (i = 0; i < program_size / sizeof(struct brw_instruction); i++) |
||
118 | brw_disasm(stdout, &((struct brw_instruction *)program)[i], |
||
119 | brw->gen); |
||
120 | printf("\n"); |
||
121 | } |
||
122 | |||
123 | brw_upload_cache(&brw->cache, |
||
124 | BRW_CLIP_PROG, |
||
125 | &c.key, sizeof(c.key), |
||
126 | program, program_size, |
||
127 | &c.prog_data, sizeof(c.prog_data), |
||
128 | &brw->clip.prog_offset, &brw->clip.prog_data); |
||
129 | ralloc_free(mem_ctx); |
||
130 | } |
||
131 | |||
132 | /* Calculate interpolants for triangle and line rasterization. |
||
133 | */ |
||
134 | static void |
||
135 | brw_upload_clip_prog(struct brw_context *brw) |
||
136 | { |
||
137 | struct gl_context *ctx = &brw->ctx; |
||
138 | struct brw_clip_prog_key key; |
||
139 | |||
140 | memset(&key, 0, sizeof(key)); |
||
141 | |||
142 | /* Populate the key: |
||
143 | */ |
||
144 | /* BRW_NEW_REDUCED_PRIMITIVE */ |
||
145 | key.primitive = brw->reduced_primitive; |
||
146 | /* BRW_NEW_VUE_MAP_GEOM_OUT */ |
||
147 | key.attrs = brw->vue_map_geom_out.slots_valid; |
||
148 | /* _NEW_LIGHT */ |
||
149 | key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT); |
||
150 | key.pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION); |
||
151 | /* _NEW_TRANSFORM (also part of VUE map)*/ |
||
152 | key.nr_userclip = _mesa_bitcount_64(ctx->Transform.ClipPlanesEnabled); |
||
153 | |||
154 | if (brw->gen == 5) |
||
155 | key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP; |
||
156 | else |
||
157 | key.clip_mode = BRW_CLIPMODE_NORMAL; |
||
158 | |||
159 | /* _NEW_POLYGON */ |
||
160 | if (key.primitive == GL_TRIANGLES) { |
||
161 | if (ctx->Polygon.CullFlag && |
||
162 | ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) |
||
163 | key.clip_mode = BRW_CLIPMODE_REJECT_ALL; |
||
164 | else { |
||
165 | GLuint fill_front = CLIP_CULL; |
||
166 | GLuint fill_back = CLIP_CULL; |
||
167 | GLuint offset_front = 0; |
||
168 | GLuint offset_back = 0; |
||
169 | |||
170 | if (!ctx->Polygon.CullFlag || |
||
171 | ctx->Polygon.CullFaceMode != GL_FRONT) { |
||
172 | switch (ctx->Polygon.FrontMode) { |
||
173 | case GL_FILL: |
||
174 | fill_front = CLIP_FILL; |
||
175 | offset_front = 0; |
||
176 | break; |
||
177 | case GL_LINE: |
||
178 | fill_front = CLIP_LINE; |
||
179 | offset_front = ctx->Polygon.OffsetLine; |
||
180 | break; |
||
181 | case GL_POINT: |
||
182 | fill_front = CLIP_POINT; |
||
183 | offset_front = ctx->Polygon.OffsetPoint; |
||
184 | break; |
||
185 | } |
||
186 | } |
||
187 | |||
188 | if (!ctx->Polygon.CullFlag || |
||
189 | ctx->Polygon.CullFaceMode != GL_BACK) { |
||
190 | switch (ctx->Polygon.BackMode) { |
||
191 | case GL_FILL: |
||
192 | fill_back = CLIP_FILL; |
||
193 | offset_back = 0; |
||
194 | break; |
||
195 | case GL_LINE: |
||
196 | fill_back = CLIP_LINE; |
||
197 | offset_back = ctx->Polygon.OffsetLine; |
||
198 | break; |
||
199 | case GL_POINT: |
||
200 | fill_back = CLIP_POINT; |
||
201 | offset_back = ctx->Polygon.OffsetPoint; |
||
202 | break; |
||
203 | } |
||
204 | } |
||
205 | |||
206 | if (ctx->Polygon.BackMode != GL_FILL || |
||
207 | ctx->Polygon.FrontMode != GL_FILL) { |
||
208 | key.do_unfilled = 1; |
||
209 | |||
210 | /* Most cases the fixed function units will handle. Cases where |
||
211 | * one or more polygon faces are unfilled will require help: |
||
212 | */ |
||
213 | key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; |
||
214 | |||
215 | if (offset_back || offset_front) { |
||
216 | /* _NEW_POLYGON, _NEW_BUFFERS */ |
||
217 | key.offset_units = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD * 2; |
||
218 | key.offset_factor = ctx->Polygon.OffsetFactor * ctx->DrawBuffer->_MRD; |
||
219 | } |
||
220 | |||
221 | switch (ctx->Polygon.FrontFace) { |
||
222 | case GL_CCW: |
||
223 | key.fill_ccw = fill_front; |
||
224 | key.fill_cw = fill_back; |
||
225 | key.offset_ccw = offset_front; |
||
226 | key.offset_cw = offset_back; |
||
227 | if (ctx->Light.Model.TwoSide && |
||
228 | key.fill_cw != CLIP_CULL) |
||
229 | key.copy_bfc_cw = 1; |
||
230 | break; |
||
231 | case GL_CW: |
||
232 | key.fill_cw = fill_front; |
||
233 | key.fill_ccw = fill_back; |
||
234 | key.offset_cw = offset_front; |
||
235 | key.offset_ccw = offset_back; |
||
236 | if (ctx->Light.Model.TwoSide && |
||
237 | key.fill_ccw != CLIP_CULL) |
||
238 | key.copy_bfc_ccw = 1; |
||
239 | break; |
||
240 | } |
||
241 | } |
||
242 | } |
||
243 | } |
||
244 | |||
245 | if (!brw_search_cache(&brw->cache, BRW_CLIP_PROG, |
||
246 | &key, sizeof(key), |
||
247 | &brw->clip.prog_offset, &brw->clip.prog_data)) { |
||
248 | compile_clip_prog( brw, &key ); |
||
249 | } |
||
250 | } |
||
251 | |||
252 | |||
253 | const struct brw_tracked_state brw_clip_prog = { |
||
254 | .dirty = { |
||
255 | .mesa = (_NEW_LIGHT | |
||
256 | _NEW_TRANSFORM | |
||
257 | _NEW_POLYGON | |
||
258 | _NEW_BUFFERS), |
||
259 | .brw = (BRW_NEW_REDUCED_PRIMITIVE | BRW_NEW_VUE_MAP_GEOM_OUT) |
||
260 | }, |
||
261 | .emit = brw_upload_clip_prog |
||
262 | };> |