Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / dri / i965 / brw_gs.c
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 <keith@tungstengraphics.com>
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_gs.h"
44
45
46
47 static void compile_gs_prog( struct brw_context *brw,
48 struct brw_gs_prog_key *key )
49 {
50 struct intel_context *intel = &brw->intel;
51 struct brw_gs_compile c;
52 const GLuint *program;
53 GLuint program_size;
54
55 memset(&c, 0, sizeof(c));
56
57 c.key = *key;
58 /* Need to locate the two positions present in vertex + header.
59 * These are currently hardcoded:
60 */
61 c.nr_attrs = brw_count_bits(c.key.attrs);
62
63 if (intel->gen >= 5)
64 c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
65 else
66 c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
67
68 c.nr_bytes = c.nr_regs * REG_SIZE;
69
70
71 /* Begin the compilation:
72 */
73 brw_init_compile(brw, &c.func);
74
75 c.func.single_program_flow = 1;
76
77 /* For some reason the thread is spawned with only 4 channels
78 * unmasked.
79 */
80 brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
81
82
83 /* Note that primitives which don't require a GS program have
84 * already been weeded out by this stage:
85 */
86 switch (key->primitive) {
87 case GL_QUADS:
88 /* Gen6: VF has already converted into polygon. */
89 if (intel->gen == 6)
90 return;
91 brw_gs_quads( &c, key );
92 break;
93 case GL_QUAD_STRIP:
94 if (intel->gen == 6)
95 return;
96 brw_gs_quad_strip( &c, key );
97 break;
98 case GL_LINE_LOOP:
99 /* XXX fix GS hang issue */
100 assert(intel->gen < 6);
101 brw_gs_lines( &c );
102 break;
103 case GL_LINES:
104 if (key->hint_gs_always)
105 brw_gs_lines( &c );
106 else {
107 return;
108 }
109 break;
110 case GL_TRIANGLES:
111 if (key->hint_gs_always)
112 brw_gs_tris( &c );
113 else {
114 return;
115 }
116 break;
117 case GL_POINTS:
118 if (key->hint_gs_always)
119 brw_gs_points( &c );
120 else {
121 return;
122 }
123 break;
124 default:
125 return;
126 }
127
128 /* get the program
129 */
130 program = brw_get_program(&c.func, &program_size);
131
132 if (INTEL_DEBUG & DEBUG_GS) {
133 int i;
134
135 printf("gs:\n");
136 for (i = 0; i < program_size / sizeof(struct brw_instruction); i++)
137 brw_disasm(stdout, &((struct brw_instruction *)program)[i],
138 intel->gen);
139 printf("\n");
140 }
141
142 /* Upload
143 */
144 drm_intel_bo_unreference(brw->gs.prog_bo);
145 brw->gs.prog_bo = brw_upload_cache_with_auxdata(&brw->cache, BRW_GS_PROG,
146 &c.key, sizeof(c.key),
147 NULL, 0,
148 program, program_size,
149 &c.prog_data,
150 sizeof(c.prog_data),
151 &brw->gs.prog_data);
152 }
153
154 static const GLenum gs_prim[GL_POLYGON+1] = {
155 GL_POINTS,
156 GL_LINES,
157 GL_LINE_LOOP,
158 GL_LINES,
159 GL_TRIANGLES,
160 GL_TRIANGLES,
161 GL_TRIANGLES,
162 GL_QUADS,
163 GL_QUAD_STRIP,
164 GL_TRIANGLES
165 };
166
167 static void populate_key( struct brw_context *brw,
168 struct brw_gs_prog_key *key )
169 {
170 struct gl_context *ctx = &brw->intel.ctx;
171 memset(key, 0, sizeof(*key));
172
173 /* CACHE_NEW_VS_PROG */
174 key->attrs = brw->vs.prog_data->outputs_written;
175
176 /* BRW_NEW_PRIMITIVE */
177 key->primitive = gs_prim[brw->primitive];
178
179 key->hint_gs_always = 0; /* debug code? */
180
181 /* _NEW_LIGHT */
182 key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
183 if (key->primitive == GL_QUADS && ctx->Light.ShadeModel != GL_FLAT) {
184 /* Provide consistent primitive order with brw_set_prim's
185 * optimization of single quads to trifans.
186 */
187 key->pv_first = GL_TRUE;
188 }
189
190 key->need_gs_prog = (key->hint_gs_always ||
191 brw->primitive == GL_QUADS ||
192 brw->primitive == GL_QUAD_STRIP ||
193 brw->primitive == GL_LINE_LOOP);
194 }
195
196 /* Calculate interpolants for triangle and line rasterization.
197 */
198 static void prepare_gs_prog(struct brw_context *brw)
199 {
200 struct brw_gs_prog_key key;
201 /* Populate the key:
202 */
203 populate_key(brw, &key);
204
205 if (brw->gs.prog_active != key.need_gs_prog) {
206 brw->state.dirty.cache |= CACHE_NEW_GS_PROG;
207 brw->gs.prog_active = key.need_gs_prog;
208 }
209
210 if (brw->gs.prog_active) {
211 drm_intel_bo_unreference(brw->gs.prog_bo);
212 brw->gs.prog_bo = brw_search_cache(&brw->cache, BRW_GS_PROG,
213 &key, sizeof(key),
214 NULL, 0,
215 &brw->gs.prog_data);
216 if (brw->gs.prog_bo == NULL)
217 compile_gs_prog( brw, &key );
218 }
219 }
220
221
222 const struct brw_tracked_state brw_gs_prog = {
223 .dirty = {
224 .mesa = _NEW_LIGHT,
225 .brw = BRW_NEW_PRIMITIVE,
226 .cache = CACHE_NEW_VS_PROG
227 },
228 .prepare = prepare_gs_prog
229 };