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 | #include "main/transformfeedback.h" |
||
36 | |||
37 | #include "intel_batchbuffer.h" |
||
38 | |||
39 | #include "brw_defines.h" |
||
40 | #include "brw_context.h" |
||
41 | #include "brw_eu.h" |
||
42 | #include "brw_util.h" |
||
43 | #include "brw_state.h" |
||
44 | #include "brw_gs.h" |
||
45 | |||
46 | #include "glsl/ralloc.h" |
||
47 | |||
48 | static void compile_gs_prog( struct brw_context *brw, |
||
49 | struct brw_gs_prog_key *key ) |
||
50 | { |
||
51 | struct brw_gs_compile c; |
||
52 | const GLuint *program; |
||
53 | void *mem_ctx; |
||
54 | GLuint program_size; |
||
55 | |||
56 | memset(&c, 0, sizeof(c)); |
||
57 | |||
58 | c.key = *key; |
||
59 | c.vue_map = brw->vs.prog_data->base.vue_map; |
||
60 | c.nr_regs = (c.vue_map.num_slots + 1)/2; |
||
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 | /* For some reason the thread is spawned with only 4 channels |
||
71 | * unmasked. |
||
72 | */ |
||
73 | brw_set_mask_control(&c.func, BRW_MASK_DISABLE); |
||
74 | |||
75 | if (brw->gen >= 6) { |
||
76 | unsigned num_verts; |
||
77 | bool check_edge_flag; |
||
78 | /* On Sandybridge, we use the GS for implementing transform feedback |
||
79 | * (called "Stream Out" in the PRM). |
||
80 | */ |
||
81 | switch (key->primitive) { |
||
82 | case _3DPRIM_POINTLIST: |
||
83 | num_verts = 1; |
||
84 | check_edge_flag = false; |
||
85 | break; |
||
86 | case _3DPRIM_LINELIST: |
||
87 | case _3DPRIM_LINESTRIP: |
||
88 | case _3DPRIM_LINELOOP: |
||
89 | num_verts = 2; |
||
90 | check_edge_flag = false; |
||
91 | break; |
||
92 | case _3DPRIM_TRILIST: |
||
93 | case _3DPRIM_TRIFAN: |
||
94 | case _3DPRIM_TRISTRIP: |
||
95 | case _3DPRIM_RECTLIST: |
||
96 | num_verts = 3; |
||
97 | check_edge_flag = false; |
||
98 | break; |
||
99 | case _3DPRIM_QUADLIST: |
||
100 | case _3DPRIM_QUADSTRIP: |
||
101 | case _3DPRIM_POLYGON: |
||
102 | num_verts = 3; |
||
103 | check_edge_flag = true; |
||
104 | break; |
||
105 | default: |
||
106 | assert(!"Unexpected primitive type in Gen6 SOL program."); |
||
107 | return; |
||
108 | } |
||
109 | gen6_sol_program(&c, key, num_verts, check_edge_flag); |
||
110 | } else { |
||
111 | /* On Gen4-5, we use the GS to decompose certain types of primitives. |
||
112 | * Note that primitives which don't require a GS program have already |
||
113 | * been weeded out by now. |
||
114 | */ |
||
115 | switch (key->primitive) { |
||
116 | case _3DPRIM_QUADLIST: |
||
117 | brw_gs_quads( &c, key ); |
||
118 | break; |
||
119 | case _3DPRIM_QUADSTRIP: |
||
120 | brw_gs_quad_strip( &c, key ); |
||
121 | break; |
||
122 | case _3DPRIM_LINELOOP: |
||
123 | brw_gs_lines( &c ); |
||
124 | break; |
||
125 | default: |
||
126 | ralloc_free(mem_ctx); |
||
127 | return; |
||
128 | } |
||
129 | } |
||
130 | |||
131 | /* get the program |
||
132 | */ |
||
133 | program = brw_get_program(&c.func, &program_size); |
||
134 | |||
135 | if (unlikely(INTEL_DEBUG & DEBUG_GS)) { |
||
136 | int i; |
||
137 | |||
138 | printf("gs:\n"); |
||
139 | for (i = 0; i < program_size / sizeof(struct brw_instruction); i++) |
||
140 | brw_disasm(stdout, &((struct brw_instruction *)program)[i], |
||
141 | brw->gen); |
||
142 | printf("\n"); |
||
143 | } |
||
144 | |||
145 | brw_upload_cache(&brw->cache, BRW_GS_PROG, |
||
146 | &c.key, sizeof(c.key), |
||
147 | program, program_size, |
||
148 | &c.prog_data, sizeof(c.prog_data), |
||
149 | &brw->gs.prog_offset, &brw->gs.prog_data); |
||
150 | ralloc_free(mem_ctx); |
||
151 | } |
||
152 | |||
153 | static void populate_key( struct brw_context *brw, |
||
154 | struct brw_gs_prog_key *key ) |
||
155 | { |
||
156 | static const unsigned swizzle_for_offset[4] = { |
||
157 | BRW_SWIZZLE4(0, 1, 2, 3), |
||
158 | BRW_SWIZZLE4(1, 2, 3, 3), |
||
159 | BRW_SWIZZLE4(2, 3, 3, 3), |
||
160 | BRW_SWIZZLE4(3, 3, 3, 3) |
||
161 | }; |
||
162 | |||
163 | struct gl_context *ctx = &brw->ctx; |
||
164 | |||
165 | memset(key, 0, sizeof(*key)); |
||
166 | |||
167 | /* CACHE_NEW_VS_PROG (part of VUE map) */ |
||
168 | key->attrs = brw->vs.prog_data->base.vue_map.slots_valid; |
||
169 | |||
170 | /* BRW_NEW_PRIMITIVE */ |
||
171 | key->primitive = brw->primitive; |
||
172 | |||
173 | /* _NEW_LIGHT */ |
||
174 | key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION); |
||
175 | if (key->primitive == _3DPRIM_QUADLIST && ctx->Light.ShadeModel != GL_FLAT) { |
||
176 | /* Provide consistent primitive order with brw_set_prim's |
||
177 | * optimization of single quads to trifans. |
||
178 | */ |
||
179 | key->pv_first = true; |
||
180 | } |
||
181 | |||
182 | if (brw->gen >= 7) { |
||
183 | /* On Gen7 and later, we don't use GS (yet). */ |
||
184 | key->need_gs_prog = false; |
||
185 | } else if (brw->gen == 6) { |
||
186 | /* On Gen6, GS is used for transform feedback. */ |
||
187 | /* BRW_NEW_TRANSFORM_FEEDBACK */ |
||
188 | if (_mesa_is_xfb_active_and_unpaused(ctx)) { |
||
189 | const struct gl_shader_program *shaderprog = |
||
190 | ctx->Shader.CurrentVertexProgram; |
||
191 | const struct gl_transform_feedback_info *linked_xfb_info = |
||
192 | &shaderprog->LinkedTransformFeedback; |
||
193 | int i; |
||
194 | |||
195 | /* Make sure that the VUE slots won't overflow the unsigned chars in |
||
196 | * key->transform_feedback_bindings[]. |
||
197 | */ |
||
198 | STATIC_ASSERT(BRW_VARYING_SLOT_COUNT <= 256); |
||
199 | |||
200 | /* Make sure that we don't need more binding table entries than we've |
||
201 | * set aside for use in transform feedback. (We shouldn't, since we |
||
202 | * set aside enough binding table entries to have one per component). |
||
203 | */ |
||
204 | assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS); |
||
205 | |||
206 | key->need_gs_prog = true; |
||
207 | key->num_transform_feedback_bindings = linked_xfb_info->NumOutputs; |
||
208 | for (i = 0; i < key->num_transform_feedback_bindings; ++i) { |
||
209 | key->transform_feedback_bindings[i] = |
||
210 | linked_xfb_info->Outputs[i].OutputRegister; |
||
211 | key->transform_feedback_swizzles[i] = |
||
212 | swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset]; |
||
213 | } |
||
214 | } |
||
215 | } else { |
||
216 | /* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP |
||
217 | * into simpler primitives. |
||
218 | */ |
||
219 | key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST || |
||
220 | brw->primitive == _3DPRIM_QUADSTRIP || |
||
221 | brw->primitive == _3DPRIM_LINELOOP); |
||
222 | } |
||
223 | } |
||
224 | |||
225 | /* Calculate interpolants for triangle and line rasterization. |
||
226 | */ |
||
227 | static void |
||
228 | brw_upload_gs_prog(struct brw_context *brw) |
||
229 | { |
||
230 | struct brw_gs_prog_key key; |
||
231 | /* Populate the key: |
||
232 | */ |
||
233 | populate_key(brw, &key); |
||
234 | |||
235 | if (brw->gs.prog_active != key.need_gs_prog) { |
||
236 | brw->state.dirty.cache |= CACHE_NEW_GS_PROG; |
||
237 | brw->gs.prog_active = key.need_gs_prog; |
||
238 | } |
||
239 | |||
240 | if (brw->gs.prog_active) { |
||
241 | if (!brw_search_cache(&brw->cache, BRW_GS_PROG, |
||
242 | &key, sizeof(key), |
||
243 | &brw->gs.prog_offset, &brw->gs.prog_data)) { |
||
244 | compile_gs_prog( brw, &key ); |
||
245 | } |
||
246 | } |
||
247 | } |
||
248 | |||
249 | |||
250 | const struct brw_tracked_state brw_gs_prog = { |
||
251 | .dirty = { |
||
252 | .mesa = (_NEW_LIGHT), |
||
253 | .brw = (BRW_NEW_PRIMITIVE | |
||
254 | BRW_NEW_TRANSFORM_FEEDBACK), |
||
255 | .cache = CACHE_NEW_VS_PROG |
||
256 | }, |
||
257 | .emit = brw_upload_gs_prog |
||
258 | };>=>=>> |