Merge branch 'mesa_7_5_branch'
[mesa.git] / src / gallium / drivers / nv20 / nv20_context.c
1 #include "draw/draw_context.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/internal/p_winsys_screen.h"
4
5 #include "nv20_context.h"
6 #include "nv20_screen.h"
7
8 static void
9 nv20_flush(struct pipe_context *pipe, unsigned flags,
10 struct pipe_fence_handle **fence)
11 {
12 struct nv20_context *nv20 = nv20_context(pipe);
13
14 draw_flush(nv20->draw);
15
16 FIRE_RING(fence);
17 }
18
19 static void
20 nv20_destroy(struct pipe_context *pipe)
21 {
22 struct nv20_context *nv20 = nv20_context(pipe);
23
24 if (nv20->draw)
25 draw_destroy(nv20->draw);
26
27 FREE(nv20);
28 }
29
30 static void nv20_init_hwctx(struct nv20_context *nv20)
31 {
32 struct nv20_screen *screen = nv20->screen;
33 struct nouveau_channel *chan = screen->base.channel;
34 int i;
35 float projectionmatrix[16];
36 const boolean is_nv25tcl = (nv20->screen->kelvin->grclass == NV25TCL);
37
38 BEGIN_RING(kelvin, NV20TCL_DMA_NOTIFY, 1);
39 OUT_RING (screen->sync->handle);
40 BEGIN_RING(kelvin, NV20TCL_DMA_TEXTURE0, 2);
41 OUT_RING (chan->vram->handle);
42 OUT_RING (chan->gart->handle); /* TEXTURE1 */
43 BEGIN_RING(kelvin, NV20TCL_DMA_COLOR, 2);
44 OUT_RING (chan->vram->handle);
45 OUT_RING (chan->vram->handle); /* ZETA */
46
47 BEGIN_RING(kelvin, NV20TCL_DMA_QUERY, 1);
48 OUT_RING (0); /* renouveau: beef0351, unique */
49
50 BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 2);
51 OUT_RING (0);
52 OUT_RING (0);
53
54 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1);
55 OUT_RING ((0xfff << 16) | 0x0);
56 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1);
57 OUT_RING ((0xfff << 16) | 0x0);
58
59 for (i = 1; i < NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE; i++) {
60 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1);
61 OUT_RING (0);
62 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_VERT(i), 1);
63 OUT_RING (0);
64 }
65
66 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_CLIP_MODE, 1);
67 OUT_RING (0);
68
69 BEGIN_RING(kelvin, 0x17e0, 3);
70 OUT_RINGf (0.0);
71 OUT_RINGf (0.0);
72 OUT_RINGf (1.0);
73
74 if (is_nv25tcl) {
75 BEGIN_RING(kelvin, NV20TCL_TX_RCOMP, 1);
76 OUT_RING (NV20TCL_TX_RCOMP_LEQUAL | 0xdb0);
77 } else {
78 BEGIN_RING(kelvin, 0x1e68, 1);
79 OUT_RING (0x4b800000); /* 16777216.000000 */
80 BEGIN_RING(kelvin, NV20TCL_TX_RCOMP, 1);
81 OUT_RING (NV20TCL_TX_RCOMP_LEQUAL);
82 }
83
84 BEGIN_RING(kelvin, 0x290, 1);
85 OUT_RING ((0x10 << 16) | 1);
86 BEGIN_RING(kelvin, 0x9fc, 1);
87 OUT_RING (0);
88 BEGIN_RING(kelvin, 0x1d80, 1);
89 OUT_RING (1);
90 BEGIN_RING(kelvin, 0x9f8, 1);
91 OUT_RING (4);
92 BEGIN_RING(kelvin, 0x17ec, 3);
93 OUT_RINGf (0.0);
94 OUT_RINGf (1.0);
95 OUT_RINGf (0.0);
96
97 if (is_nv25tcl) {
98 BEGIN_RING(kelvin, 0x1d88, 1);
99 OUT_RING (3);
100
101 BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY9, 1);
102 OUT_RING (chan->vram->handle);
103 BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY8, 1);
104 OUT_RING (chan->vram->handle);
105 }
106 BEGIN_RING(kelvin, NV20TCL_DMA_FENCE, 1);
107 OUT_RING (0); /* renouveau: beef1e10 */
108
109 BEGIN_RING(kelvin, 0x1e98, 1);
110 OUT_RING (0);
111 #if 0
112 if (is_nv25tcl) {
113 BEGIN_RING(NvSub3D, NV25TCL_DMA_IN_MEMORY4, 2);
114 OUT_RING (NvDmaTT); /* renouveau: beef0202 */
115 OUT_RING (NvDmaFB); /* renouveau: beef0201 */
116
117 BEGIN_RING(NvSub3D, NV20TCL_DMA_TEXTURE1, 1);
118 OUT_RING (NvDmaTT); /* renouveau: beef0202 */
119 }
120 #endif
121 BEGIN_RING(kelvin, NV20TCL_NOTIFY, 1);
122 OUT_RING (0);
123
124 BEGIN_RING(kelvin, 0x120, 3);
125 OUT_RING (0);
126 OUT_RING (1);
127 OUT_RING (2);
128
129 /* error: ILLEGAL_MTHD, PROTECTION_FAULT
130 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4);
131 OUT_RINGf (0.0);
132 OUT_RINGf (512.0);
133 OUT_RINGf (0.0);
134 OUT_RINGf (0.0);
135 */
136
137 if (is_nv25tcl) {
138 BEGIN_RING(kelvin, 0x022c, 2);
139 OUT_RING (0x280);
140 OUT_RING (0x07d28000);
141 }
142
143 /* * illegal method, protection fault
144 BEGIN_RING(NvSub3D, 0x1c2c, 1);
145 OUT_RING (0); */
146
147 if (is_nv25tcl) {
148 BEGIN_RING(kelvin, 0x1da4, 1);
149 OUT_RING (0);
150 }
151
152 /* * crashes with illegal method, protection fault
153 BEGIN_RING(NvSub3D, 0x1c18, 1);
154 OUT_RING (0x200); */
155
156 BEGIN_RING(kelvin, NV20TCL_RT_HORIZ, 2);
157 OUT_RING ((0 << 16) | 0);
158 OUT_RING ((0 << 16) | 0);
159
160 /* *** Set state *** */
161
162 BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1);
163 OUT_RING (0);
164 BEGIN_RING(kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2);
165 OUT_RING (NV20TCL_ALPHA_FUNC_FUNC_ALWAYS);
166 OUT_RING (0); /* NV20TCL_ALPHA_FUNC_REF */
167
168 for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; ++i) {
169 BEGIN_RING(kelvin, NV20TCL_TX_ENABLE(i), 1);
170 OUT_RING (0);
171 }
172 BEGIN_RING(kelvin, NV20TCL_TX_SHADER_OP, 1);
173 OUT_RING (0);
174 BEGIN_RING(kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1);
175 OUT_RING (0);
176 BEGIN_RING(kelvin, NV20TCL_RC_IN_ALPHA(0), 4);
177 OUT_RING (0x30d410d0);
178 OUT_RING (0);
179 OUT_RING (0);
180 OUT_RING (0);
181 BEGIN_RING(kelvin, NV20TCL_RC_OUT_RGB(0), 4);
182 OUT_RING (0x00000c00);
183 OUT_RING (0);
184 OUT_RING (0);
185 OUT_RING (0);
186 BEGIN_RING(kelvin, NV20TCL_RC_ENABLE, 1);
187 OUT_RING (0x00011101);
188 BEGIN_RING(kelvin, NV20TCL_RC_FINAL0, 2);
189 OUT_RING (0x130e0300);
190 OUT_RING (0x0c091c80);
191 BEGIN_RING(kelvin, NV20TCL_RC_OUT_ALPHA(0), 4);
192 OUT_RING (0x00000c00);
193 OUT_RING (0);
194 OUT_RING (0);
195 OUT_RING (0);
196 BEGIN_RING(kelvin, NV20TCL_RC_IN_RGB(0), 4);
197 OUT_RING (0x20c400c0);
198 OUT_RING (0);
199 OUT_RING (0);
200 OUT_RING (0);
201 BEGIN_RING(kelvin, NV20TCL_RC_COLOR0, 2);
202 OUT_RING (0);
203 OUT_RING (0);
204 BEGIN_RING(kelvin, NV20TCL_RC_CONSTANT_COLOR0(0), 4);
205 OUT_RING (0x035125a0);
206 OUT_RING (0);
207 OUT_RING (0x40002000);
208 OUT_RING (0);
209 BEGIN_RING(kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1);
210 OUT_RING (0xffff0000);
211
212 BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1);
213 OUT_RING (0);
214 BEGIN_RING(kelvin, NV20TCL_DITHER_ENABLE, 1);
215 OUT_RING (0);
216 BEGIN_RING(kelvin, NV20TCL_STENCIL_ENABLE, 1);
217 OUT_RING (0);
218 BEGIN_RING(kelvin, NV20TCL_BLEND_FUNC_SRC, 4);
219 OUT_RING (NV20TCL_BLEND_FUNC_SRC_ONE);
220 OUT_RING (NV20TCL_BLEND_FUNC_DST_ZERO);
221 OUT_RING (0); /* NV20TCL_BLEND_COLOR */
222 OUT_RING (NV20TCL_BLEND_EQUATION_FUNC_ADD);
223 BEGIN_RING(kelvin, NV20TCL_STENCIL_MASK, 7);
224 OUT_RING (0xff);
225 OUT_RING (NV20TCL_STENCIL_FUNC_FUNC_ALWAYS);
226 OUT_RING (0); /* NV20TCL_STENCIL_FUNC_REF */
227 OUT_RING (0xff); /* NV20TCL_STENCIL_FUNC_MASK */
228 OUT_RING (NV20TCL_STENCIL_OP_FAIL_KEEP);
229 OUT_RING (NV20TCL_STENCIL_OP_ZFAIL_KEEP);
230 OUT_RING (NV20TCL_STENCIL_OP_ZPASS_KEEP);
231
232 BEGIN_RING(kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2);
233 OUT_RING (0);
234 OUT_RING (NV20TCL_COLOR_LOGIC_OP_OP_COPY);
235 BEGIN_RING(kelvin, 0x17cc, 1);
236 OUT_RING (0);
237 if (is_nv25tcl) {
238 BEGIN_RING(kelvin, 0x1d84, 1);
239 OUT_RING (1);
240 }
241 BEGIN_RING(kelvin, NV20TCL_LIGHTING_ENABLE, 1);
242 OUT_RING (0);
243 BEGIN_RING(kelvin, NV20TCL_LIGHT_CONTROL, 1);
244 OUT_RING (0x00020000);
245 BEGIN_RING(kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1);
246 OUT_RING (0);
247 BEGIN_RING(kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1);
248 OUT_RING (0);
249 BEGIN_RING(kelvin, NV20TCL_ENABLED_LIGHTS, 1);
250 OUT_RING (0);
251 BEGIN_RING(kelvin, NV20TCL_NORMALIZE_ENABLE, 1);
252 OUT_RING (0);
253 BEGIN_RING(kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0),
254 NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE);
255 for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; ++i) {
256 OUT_RING(0xffffffff);
257 }
258
259 BEGIN_RING(kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
260 OUT_RING (0);
261 OUT_RING (0); /* NV20TCL.POLYGON_OFFSET_LINE_ENABLE */
262 OUT_RING (0); /* NV20TCL.POLYGON_OFFSET_FILL_ENABLE */
263 BEGIN_RING(kelvin, NV20TCL_DEPTH_FUNC, 1);
264 OUT_RING (NV20TCL_DEPTH_FUNC_LESS);
265 BEGIN_RING(kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1);
266 OUT_RING (0);
267 BEGIN_RING(kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1);
268 OUT_RING (0);
269 BEGIN_RING(kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2);
270 OUT_RINGf (0.0);
271 OUT_RINGf (0.0); /* NV20TCL.POLYGON_OFFSET_UNITS */
272 BEGIN_RING(kelvin, NV20TCL_DEPTH_UNK17D8, 1);
273 OUT_RING (1);
274 if (!is_nv25tcl) {
275 BEGIN_RING(kelvin, 0x1d84, 1);
276 OUT_RING (3);
277 }
278 BEGIN_RING(kelvin, NV20TCL_POINT_SIZE, 1);
279 if (!is_nv25tcl) {
280 OUT_RING (8);
281 } else {
282 OUT_RINGf (1.0);
283 }
284 if (!is_nv25tcl) {
285 BEGIN_RING(kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2);
286 OUT_RING (0);
287 OUT_RING (0); /* NV20TCL.POINT_SMOOTH_ENABLE */
288 } else {
289 BEGIN_RING(kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1);
290 OUT_RING (0);
291 BEGIN_RING(kelvin, 0x0a1c, 1);
292 OUT_RING (0x800);
293 }
294 BEGIN_RING(kelvin, NV20TCL_LINE_WIDTH, 1);
295 OUT_RING (8);
296 BEGIN_RING(kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1);
297 OUT_RING (0);
298 BEGIN_RING(kelvin, NV20TCL_POLYGON_MODE_FRONT, 2);
299 OUT_RING (NV20TCL_POLYGON_MODE_FRONT_FILL);
300 OUT_RING (NV20TCL_POLYGON_MODE_BACK_FILL);
301 BEGIN_RING(kelvin, NV20TCL_CULL_FACE, 2);
302 OUT_RING (NV20TCL_CULL_FACE_BACK);
303 OUT_RING (NV20TCL_FRONT_FACE_CCW);
304 BEGIN_RING(kelvin, NV20TCL_POLYGON_SMOOTH_ENABLE, 1);
305 OUT_RING (0);
306 BEGIN_RING(kelvin, NV20TCL_CULL_FACE_ENABLE, 1);
307 OUT_RING (0);
308 BEGIN_RING(kelvin, NV20TCL_SHADE_MODEL, 1);
309 OUT_RING (NV20TCL_SHADE_MODEL_SMOOTH);
310 BEGIN_RING(kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1);
311 OUT_RING (0);
312 BEGIN_RING(kelvin, NV20TCL_TX_GEN_S(0), 4 * NV20TCL_TX_GEN_S__SIZE);
313 for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; ++i) {
314 OUT_RING(0);
315 }
316 BEGIN_RING(kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3);
317 OUT_RINGf (1.5);
318 OUT_RINGf (-0.090168); /* NV20TCL.FOG_EQUATION_LINEAR */
319 OUT_RINGf (0.0); /* NV20TCL.FOG_EQUATION_QUADRATIC */
320 BEGIN_RING(kelvin, NV20TCL_FOG_MODE, 2);
321 OUT_RING (NV20TCL_FOG_MODE_EXP_2);
322 OUT_RING (NV20TCL_FOG_COORD_DIST_COORD_FOG);
323 BEGIN_RING(kelvin, NV20TCL_FOG_ENABLE, 2);
324 OUT_RING (0);
325 OUT_RING (0); /* NV20TCL.FOG_COLOR */
326 BEGIN_RING(kelvin, NV20TCL_ENGINE, 1);
327 OUT_RING (NV20TCL_ENGINE_FIXED);
328
329 for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; ++i) {
330 BEGIN_RING(kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1);
331 OUT_RING (0);
332 }
333
334 BEGIN_RING(kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15);
335 OUT_RINGf(1.0); OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(1.0);
336 OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(1.0); OUT_RINGf(1.0);
337 OUT_RINGf(1.0); OUT_RINGf(1.0); OUT_RINGf(1.0); OUT_RINGf(1.0);
338 for (i = 4; i < 16; ++i) {
339 OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(0.0); OUT_RINGf(1.0);
340 }
341
342 BEGIN_RING(kelvin, NV20TCL_EDGEFLAG_ENABLE, 1);
343 OUT_RING (1);
344 BEGIN_RING(kelvin, NV20TCL_COLOR_MASK, 1);
345 OUT_RING (0x00010101);
346 BEGIN_RING(kelvin, NV20TCL_CLEAR_VALUE, 1);
347 OUT_RING (0);
348
349 memset(projectionmatrix, 0, sizeof(projectionmatrix));
350 projectionmatrix[0*4+0] = 1.0;
351 projectionmatrix[1*4+1] = 1.0;
352 projectionmatrix[2*4+2] = 16777215.0;
353 projectionmatrix[3*4+3] = 1.0;
354 BEGIN_RING(kelvin, NV20TCL_PROJECTION_MATRIX(0), 16);
355 for (i = 0; i < 16; i++) {
356 OUT_RINGf (projectionmatrix[i]);
357 }
358
359 BEGIN_RING(kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2);
360 OUT_RINGf (0.0);
361 OUT_RINGf (16777216.0); /* [0, 1] scaled approx to [0, 2^24] */
362
363 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_SCALE0_X, 4);
364 OUT_RINGf (0.0); /* x-offset, w/2 + 1.031250 */
365 OUT_RINGf (0.0); /* y-offset, h/2 + 0.030762 */
366 OUT_RINGf (0.0);
367 OUT_RINGf (16777215.0);
368
369 BEGIN_RING(kelvin, NV20TCL_VIEWPORT_SCALE1_X, 4);
370 OUT_RINGf (0.0); /* no effect?, w/2 */
371 OUT_RINGf (0.0); /* no effect?, h/2 */
372 OUT_RINGf (16777215.0 * 0.5);
373 OUT_RINGf (65535.0);
374
375 FIRE_RING (NULL);
376 }
377
378 static void
379 nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
380 {
381 }
382
383
384 static unsigned int
385 nv20_is_texture_referenced( struct pipe_context *pipe,
386 struct pipe_texture *texture,
387 unsigned face, unsigned level)
388 {
389 /**
390 * FIXME: Optimize.
391 */
392
393 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
394 }
395
396 static unsigned int
397 nv20_is_buffer_referenced( struct pipe_context *pipe,
398 struct pipe_buffer *buf)
399 {
400 /**
401 * FIXME: Optimize.
402 */
403
404 return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
405 }
406
407 struct pipe_context *
408 nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
409 {
410 struct nv20_screen *screen = nv20_screen(pscreen);
411 struct pipe_winsys *ws = pscreen->winsys;
412 struct nv20_context *nv20;
413 struct nouveau_winsys *nvws = screen->nvws;
414
415 nv20 = CALLOC(1, sizeof(struct nv20_context));
416 if (!nv20)
417 return NULL;
418 nv20->screen = screen;
419 nv20->pctx_id = pctx_id;
420
421 nv20->nvws = nvws;
422
423 nv20->pipe.winsys = ws;
424 nv20->pipe.screen = pscreen;
425 nv20->pipe.destroy = nv20_destroy;
426 nv20->pipe.set_edgeflags = nv20_set_edgeflags;
427 nv20->pipe.draw_arrays = nv20_draw_arrays;
428 nv20->pipe.draw_elements = nv20_draw_elements;
429 nv20->pipe.clear = nv20_clear;
430 nv20->pipe.flush = nv20_flush;
431
432 nv20->pipe.is_texture_referenced = nv20_is_texture_referenced;
433 nv20->pipe.is_buffer_referenced = nv20_is_buffer_referenced;
434
435 nv20_init_surface_functions(nv20);
436 nv20_init_state_functions(nv20);
437
438 nv20->draw = draw_create();
439 assert(nv20->draw);
440 draw_set_rasterize_stage(nv20->draw, nv20_draw_vbuf_stage(nv20));
441
442 nv20_init_hwctx(nv20);
443
444 return &nv20->pipe;
445 }
446