Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / drivers / nv10 / nv10_context.c
1 #include "draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_winsys.h"
4 #include "pipe/p_util.h"
5
6 #include "nv10_context.h"
7 #include "nv10_screen.h"
8
9 static void
10 nv10_flush(struct pipe_context *pipe, unsigned flags)
11 {
12 struct nv10_context *nv10 = nv10_context(pipe);
13 struct nouveau_winsys *nvws = nv10->nvws;
14
15 if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
16 BEGIN_RING(celsius, 0x1fd8, 1);
17 OUT_RING (2);
18 BEGIN_RING(celsius, 0x1fd8, 1);
19 OUT_RING (1);
20 }
21
22 if (flags & PIPE_FLUSH_WAIT) {
23 nvws->notifier_reset(nv10->sync, 0);
24 BEGIN_RING(celsius, 0x104, 1);
25 OUT_RING (0);
26 BEGIN_RING(celsius, 0x100, 1);
27 OUT_RING (0);
28 }
29
30 FIRE_RING();
31
32 if (flags & PIPE_FLUSH_WAIT)
33 nvws->notifier_wait(nv10->sync, 0, 0, 2000);
34 }
35
36 static void
37 nv10_destroy(struct pipe_context *pipe)
38 {
39 struct nv10_context *nv10 = nv10_context(pipe);
40 struct nouveau_winsys *nvws = nv10->nvws;
41
42 if (nv10->draw)
43 draw_destroy(nv10->draw);
44
45 nvws->res_free(&nv10->vertprog.exec_heap);
46 nvws->res_free(&nv10->vertprog.data_heap);
47
48 nvws->notifier_free(&nv10->sync);
49
50 nvws->grobj_free(&nv10->celsius);
51
52 free(nv10);
53 }
54
55 static boolean
56 nv10_init_hwctx(struct nv10_context *nv10, int celsius_class)
57 {
58 struct nouveau_winsys *nvws = nv10->nvws;
59 int ret;
60 int i;
61
62 ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius);
63 if (ret) {
64 NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
65 return FALSE;
66 }
67
68 BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1);
69 OUT_RING (nv10->sync->handle);
70 BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2);
71 OUT_RING (nvws->channel->vram->handle);
72 OUT_RING (nvws->channel->gart->handle);
73 BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2);
74 OUT_RING (nvws->channel->vram->handle);
75 OUT_RING (nvws->channel->vram->handle);
76
77 BEGIN_RING(celsius, NV10TCL_NOP, 1);
78 OUT_RING (0);
79
80 BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2);
81 OUT_RING (0);
82 OUT_RING (0);
83
84 BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
85 OUT_RING ((0x7ff<<16)|0x800);
86 BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
87 OUT_RING ((0x7ff<<16)|0x800);
88
89 for (i=1;i<8;i++) {
90 BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1);
91 OUT_RING (0);
92 BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1);
93 OUT_RING (0);
94 }
95
96 BEGIN_RING(celsius, 0x290, 1);
97 OUT_RING ((0x10<<16)|1);
98 BEGIN_RING(celsius, 0x3f4, 1);
99 OUT_RING (0);
100
101 BEGIN_RING(celsius, NV10TCL_NOP, 1);
102 OUT_RING (0);
103
104 if (celsius_class != NV10TCL) {
105 /* For nv11, nv17 */
106 BEGIN_RING(celsius, 0x120, 3);
107 OUT_RING (0);
108 OUT_RING (1);
109 OUT_RING (2);
110
111 BEGIN_RING(celsius, NV10TCL_NOP, 1);
112 OUT_RING (0);
113 }
114
115 BEGIN_RING(celsius, NV10TCL_NOP, 1);
116 OUT_RING (0);
117
118 /* Set state */
119 BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1);
120 OUT_RING (0);
121 BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
122 OUT_RING (0);
123 BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2);
124 OUT_RING (0x207);
125 OUT_RING (0);
126 BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2);
127 OUT_RING (0);
128 OUT_RING (0);
129 BEGIN_RING(celsius, NV10TCL_RC_OUT_ALPHA(0), 6);
130 OUT_RING (0x00000c00);
131 OUT_RING (0);
132 OUT_RING (0x00000c00);
133 OUT_RING (0x18000000);
134 OUT_RING (0x300c0000);
135 OUT_RING (0x00001c80);
136 BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1);
137 OUT_RING (0);
138 BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2);
139 OUT_RING (1);
140 OUT_RING (0);
141 BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
142 OUT_RING (0);
143 BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2);
144 OUT_RING (0);
145 OUT_RING (0);
146 BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4);
147 OUT_RING (1);
148 OUT_RING (0);
149 OUT_RING (0);
150 OUT_RING (0x8006);
151 BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8);
152 OUT_RING (0xff);
153 OUT_RING (0x207);
154 OUT_RING (0);
155 OUT_RING (0xff);
156 OUT_RING (0x1e00);
157 OUT_RING (0x1e00);
158 OUT_RING (0x1e00);
159 OUT_RING (0x1d01);
160 BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1);
161 OUT_RING (0);
162 BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2);
163 OUT_RING (0);
164 OUT_RING (0);
165 BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1);
166 OUT_RING (0);
167 BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1);
168 OUT_RING (0);
169 BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1);
170 OUT_RING (0);
171 BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
172 OUT_RING (0);
173 OUT_RING (0);
174 OUT_RING (0);
175 BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1);
176 OUT_RING (0x201);
177 BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
178 OUT_RING (0);
179 BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
180 OUT_RING (0);
181 BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2);
182 OUT_RING (0);
183 OUT_RING (0);
184 BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1);
185 OUT_RING (8);
186 BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2);
187 OUT_RING (0);
188 OUT_RING (0);
189 BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1);
190 OUT_RING (8);
191 BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
192 OUT_RING (0);
193 BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
194 OUT_RING (0x1b02);
195 OUT_RING (0x1b02);
196 BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2);
197 OUT_RING (0x405);
198 OUT_RING (0x901);
199 BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1);
200 OUT_RING (0);
201 BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1);
202 OUT_RING (0);
203 BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8);
204 for (i=0;i<8;i++) {
205 OUT_RING (0);
206 }
207 BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
208 OUT_RING (0x3fc00000); /* -1.50 */
209 OUT_RING (0xbdb8aa0a); /* -0.09 */
210 OUT_RING (0); /* 0.00 */
211
212 BEGIN_RING(celsius, NV10TCL_NOP, 1);
213 OUT_RING (0);
214
215 BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2);
216 OUT_RING (0x802);
217 OUT_RING (2);
218 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
219 * using texturing, except when using the texture matrix
220 */
221 BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1);
222 OUT_RING (6);
223 BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1);
224 OUT_RING (0x01010101);
225
226 /* Set vertex component */
227 BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4);
228 OUT_RINGf (1.0);
229 OUT_RINGf (1.0);
230 OUT_RINGf (1.0);
231 OUT_RINGf (1.0);
232 BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3);
233 OUT_RING (0);
234 OUT_RING (0);
235 OUT_RING (0);
236 BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3);
237 OUT_RING (0);
238 OUT_RING (0);
239 OUT_RINGf (1.0);
240 BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4);
241 OUT_RINGf (0.0);
242 OUT_RINGf (0.0);
243 OUT_RINGf (0.0);
244 OUT_RINGf (1.0);
245 BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4);
246 OUT_RINGf (0.0);
247 OUT_RINGf (0.0);
248 OUT_RINGf (0.0);
249 OUT_RINGf (1.0);
250 BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1);
251 OUT_RINGf (0.0);
252 BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1);
253 OUT_RING (1);
254
255
256 FIRE_RING ();
257 return TRUE;
258 }
259
260 struct pipe_context *
261 nv10_create(struct pipe_screen *screen, unsigned pctx_id)
262 {
263 struct pipe_winsys *pipe_winsys = screen->winsys;
264 struct nouveau_winsys *nvws = nv10_screen(screen)->nvws;
265 unsigned chipset = nv10_screen(screen)->chipset;
266 struct nv10_context *nv10;
267 int celsius_class = 0, ret;
268
269 if (chipset>=0x20)
270 celsius_class=NV11TCL;
271 else if (chipset>=0x17)
272 celsius_class=NV17TCL;
273 else if (chipset>=0x11)
274 celsius_class=NV11TCL;
275 else
276 celsius_class=NV10TCL;
277
278 nv10 = CALLOC_STRUCT(nv10_context);
279 if (!nv10)
280 return NULL;
281 nv10->chipset = chipset;
282 nv10->nvws = nvws;
283
284 /* Notifier for sync purposes */
285 ret = nvws->notifier_alloc(nvws, 1, &nv10->sync);
286 if (ret) {
287 NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
288 nv10_destroy(&nv10->pipe);
289 return NULL;
290 }
291
292 /* Vtxprog resources */
293 if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) ||
294 nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) {
295 nv10_destroy(&nv10->pipe);
296 return NULL;
297 }
298
299 /* Static celsius initialisation */
300 if (!nv10_init_hwctx(nv10, celsius_class)) {
301 nv10_destroy(&nv10->pipe);
302 return NULL;
303 }
304
305 /* Pipe context setup */
306 nv10->pipe.winsys = pipe_winsys;
307
308 nv10->pipe.destroy = nv10_destroy;
309
310 nv10->pipe.draw_arrays = nv10_draw_arrays;
311 nv10->pipe.draw_elements = nv10_draw_elements;
312 nv10->pipe.clear = nv10_clear;
313
314 nv10->pipe.flush = nv10_flush;
315
316 nv10_init_surface_functions(nv10);
317 nv10_init_state_functions(nv10);
318
319 nv10->draw = draw_create();
320 assert(nv10->draw);
321 draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10));
322
323 return &nv10->pipe;
324 }
325