Merge branch 'mesa_7_7_branch'
[mesa.git] / src / mesa / drivers / dri / ffb / ffb_state.c
1 /*
2 *
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2000, 2001 David S. Miller
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 *
25 * David S. Miller <davem@redhat.com>
26 */
27
28 #include "main/mtypes.h"
29 #include "main/colormac.h"
30 #include "main/enums.h"
31
32 #include "vbo/vbo.h"
33 #include "tnl/tnl.h"
34 #include "tnl/t_pipeline.h"
35 #include "swrast/swrast.h"
36 #include "swrast_setup/swrast_setup.h"
37
38 #include "ffb_dd.h"
39 #include "ffb_span.h"
40 #include "ffb_context.h"
41 #include "ffb_tris.h"
42 #include "ffb_state.h"
43
44 #undef STATE_TRACE
45
46 static unsigned int ffbComputeAlphaFunc(GLcontext *ctx)
47 {
48 unsigned int xclip;
49 GLubyte alphaRef;
50
51 #ifdef STATE_TRACE
52 fprintf(stderr, "ffbDDAlphaFunc: func(%s) ref(%02x)\n",
53 _mesa_lookup_enum_by_nr(ctx->Color.AlphaFunc),
54 ctx->Color.AlphaRef & 0xff);
55 #endif
56
57 switch (ctx->Color.AlphaFunc) {
58 case GL_NEVER: xclip = FFB_XCLIP_TEST_NEVER; break;
59 case GL_LESS: xclip = FFB_XCLIP_TEST_LT; break;
60 case GL_EQUAL: xclip = FFB_XCLIP_TEST_EQ; break;
61 case GL_LEQUAL: xclip = FFB_XCLIP_TEST_LE; break;
62 case GL_GREATER: xclip = FFB_XCLIP_TEST_GT; break;
63 case GL_NOTEQUAL: xclip = FFB_XCLIP_TEST_NE; break;
64 case GL_GEQUAL: xclip = FFB_XCLIP_TEST_GE; break;
65 case GL_ALWAYS: xclip = FFB_XCLIP_TEST_ALWAYS; break;
66
67 default:
68 return FFB_XCLIP_TEST_ALWAYS | 0x00;
69 }
70
71 CLAMPED_FLOAT_TO_UBYTE(alphaRef, ctx->Color.AlphaRef);
72 xclip |= (alphaRef & 0xff);
73
74 return xclip;
75 }
76
77 static void ffbDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
78 {
79 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
80
81 if (ctx->Color.AlphaEnabled) {
82 unsigned int xclip = ffbComputeAlphaFunc(ctx);
83
84 if (fmesa->xclip != xclip) {
85 fmesa->xclip = xclip;
86 FFB_MAKE_DIRTY(fmesa, FFB_STATE_XCLIP, 1);
87 }
88 }
89 }
90
91 static void ffbDDBlendEquationSeparate(GLcontext *ctx,
92 GLenum modeRGB, GLenum modeA)
93 {
94
95 #ifdef STATE_TRACE
96 fprintf(stderr, "ffbDDBlendEquation: mode(%s)\n",
97 _mesa_lookup_enum_by_nr(modeRGB));
98 #endif
99 assert( modeRGB == modeA );
100 FALLBACK( ctx, (modeRGB != GL_FUNC_ADD), FFB_BADATTR_BLENDEQN);
101 }
102
103 static void ffbDDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
104 GLenum dfactorRGB, GLenum sfactorA,
105 GLenum dfactorA)
106 {
107 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
108 unsigned int blendc = 1 << 4;
109
110 #ifdef STATE_TRACE
111 fprintf(stderr, "ffbDDBlendFuncSeparate: sRGB(%s) dRGB(%s) sA(%s) dA(%s)\n",
112 _mesa_lookup_enum_by_nr(sfactorRGB),
113 _mesa_lookup_enum_by_nr(dfactorRGB),
114 _mesa_lookup_enum_by_nr(sfactorA),
115 _mesa_lookup_enum_by_nr(dfactorA));
116 #endif
117 switch (ctx->Color.BlendSrcRGB) {
118 case GL_ZERO:
119 blendc |= (0 << 0);
120 break;
121
122 case GL_ONE:
123 blendc |= (1 << 0);
124 break;
125
126 case GL_ONE_MINUS_SRC_ALPHA:
127 blendc |= (2 << 0);
128 break;
129
130 case GL_SRC_ALPHA:
131 blendc |= (3 << 0);
132 break;
133
134 default:
135 if (ctx->Color.BlendEnabled)
136 FALLBACK( ctx, FFB_BADATTR_BLENDFUNC, GL_TRUE );
137 return;
138 };
139
140 switch (ctx->Color.BlendDstRGB) {
141 case GL_ZERO:
142 blendc |= (0 << 2);
143 break;
144
145 case GL_ONE:
146 blendc |= (1 << 2);
147 break;
148
149 case GL_ONE_MINUS_SRC_ALPHA:
150 blendc |= (2 << 2);
151 break;
152
153 case GL_SRC_ALPHA:
154 blendc |= (3 << 2);
155 break;
156
157 default:
158 if (ctx->Color.BlendEnabled)
159 FALLBACK( ctx, FFB_BADATTR_BLENDFUNC, GL_TRUE );
160 return;
161 };
162
163 if (ctx->Color.BlendEnabled &&
164 ctx->Color.ColorLogicOpEnabled &&
165 ctx->Color.LogicOp != GL_COPY) {
166 /* We could avoid this if sfactor is GL_ONE and
167 * dfactor is GL_ZERO. I do not think that is even
168 * worthwhile to check because if someone is using
169 * blending they use more interesting settings and
170 * also it would add more state tracking to a lot
171 * of the code in this file.
172 */
173 FALLBACK(ctx, FFB_BADATTR_BLENDROP, GL_TRUE);
174 return;
175 }
176
177 FALLBACK( ctx, (FFB_BADATTR_BLENDFUNC|FFB_BADATTR_BLENDROP), GL_FALSE );
178
179 if (blendc != fmesa->blendc) {
180 fmesa->blendc = blendc;
181 FFB_MAKE_DIRTY(fmesa, FFB_STATE_BLEND, 1);
182 }
183 }
184
185 static void ffbDDDepthFunc(GLcontext *ctx, GLenum func)
186 {
187 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
188 GLuint cmp;
189
190 #ifdef STATE_TRACE
191 fprintf(stderr, "ffbDDDepthFunc: func(%s)\n",
192 _mesa_lookup_enum_by_nr(func));
193 #endif
194
195 switch (func) {
196 case GL_NEVER:
197 cmp = FFB_CMP_MAGN_NEVER;
198 break;
199 case GL_ALWAYS:
200 cmp = FFB_CMP_MAGN_ALWAYS;
201 break;
202 case GL_LESS:
203 cmp = FFB_CMP_MAGN_LT;
204 break;
205 case GL_LEQUAL:
206 cmp = FFB_CMP_MAGN_LE;
207 break;
208 case GL_EQUAL:
209 cmp = FFB_CMP_MAGN_EQ;
210 break;
211 case GL_GREATER:
212 cmp = FFB_CMP_MAGN_GT;
213 break;
214 case GL_GEQUAL:
215 cmp = FFB_CMP_MAGN_GE;
216 break;
217 case GL_NOTEQUAL:
218 cmp = FFB_CMP_MAGN_NE;
219 break;
220 default:
221 return;
222 };
223
224 if (! ctx->Depth.Test)
225 cmp = FFB_CMP_MAGN_ALWAYS;
226
227 cmp <<= 16;
228 cmp = (fmesa->cmp & ~(0xff<<16)) | cmp;
229 if (cmp != fmesa->cmp) {
230 fmesa->cmp = cmp;
231 FFB_MAKE_DIRTY(fmesa, FFB_STATE_CMP, 1);
232 }
233 }
234
235 static void ffbDDDepthMask(GLcontext *ctx, GLboolean flag)
236 {
237 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
238 GLuint fbc = fmesa->fbc;
239 GLboolean enabled_now;
240
241 #ifdef STATE_TRACE
242 fprintf(stderr, "ffbDDDepthMask: flag(%d)\n", flag);
243 #endif
244
245 if ((fbc & FFB_FBC_ZE_MASK) == FFB_FBC_ZE_OFF)
246 enabled_now = GL_FALSE;
247 else
248 enabled_now = GL_TRUE;
249
250 if (flag != enabled_now) {
251 fbc &= ~FFB_FBC_ZE_MASK;
252 if (flag) {
253 fbc |= FFB_FBC_WB_C | FFB_FBC_ZE_ON;
254 } else {
255 fbc |= FFB_FBC_ZE_OFF;
256 fbc &= ~FFB_FBC_WB_C;
257 }
258 fmesa->fbc = fbc;
259 FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1);
260 }
261 }
262
263 static void
264 ffbDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,
265 GLint ref, GLuint mask)
266 {
267 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
268 unsigned int stencil, stencilctl, consty;
269
270 /* We will properly update sw/hw state when stenciling is
271 * enabled.
272 */
273 if (! ctx->Stencil._Enabled)
274 return;
275
276 stencilctl = fmesa->stencilctl;
277 stencilctl &= ~(7 << 16);
278
279 switch (func) {
280 case GL_ALWAYS: stencilctl |= (0 << 16); break;
281 case GL_GREATER: stencilctl |= (1 << 16); break;
282 case GL_EQUAL: stencilctl |= (2 << 16); break;
283 case GL_GEQUAL: stencilctl |= (3 << 16); break;
284 case GL_NEVER: stencilctl |= (4 << 16); break;
285 case GL_LEQUAL: stencilctl |= (5 << 16); break;
286 case GL_NOTEQUAL: stencilctl |= (6 << 16); break;
287 case GL_LESS: stencilctl |= (7 << 16); break;
288
289 default:
290 return;
291 };
292
293 consty = ref & 0xf;
294
295 stencil = fmesa->stencil;
296 stencil &= ~(0xf << 20);
297 stencil |= (mask & 0xf) << 20;
298
299 if (fmesa->stencil != stencil ||
300 fmesa->stencilctl != stencilctl ||
301 fmesa->consty != consty) {
302 fmesa->stencil = stencil;
303 fmesa->stencilctl = stencilctl;
304 fmesa->consty = consty;
305 FFB_MAKE_DIRTY(fmesa, FFB_STATE_STENCIL, 6);
306 }
307 }
308
309 static void
310 ffbDDStencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
311 {
312 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
313
314 mask &= 0xf;
315 if (fmesa->ypmask != mask) {
316 fmesa->ypmask = mask;
317 FFB_MAKE_DIRTY(fmesa, FFB_STATE_YPMASK, 1);
318 }
319 }
320
321 static void
322 ffbDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,
323 GLenum zfail, GLenum zpass)
324 {
325 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
326 unsigned int stencilctl;
327
328 /* We will properly update sw/hw state when stenciling is
329 * enabled.
330 */
331 if (! ctx->Stencil._Enabled)
332 return;
333
334 stencilctl = fmesa->stencilctl;
335 stencilctl &= ~(0xfff00000);
336
337 switch (fail) {
338 case GL_ZERO: stencilctl |= (0 << 28); break;
339 case GL_KEEP: stencilctl |= (1 << 28); break;
340 case GL_INVERT: stencilctl |= (2 << 28); break;
341 case GL_REPLACE: stencilctl |= (3 << 28); break;
342 case GL_INCR: stencilctl |= (4 << 28); break;
343 case GL_DECR: stencilctl |= (5 << 28); break;
344
345 default:
346 return;
347 };
348
349 switch (zfail) {
350 case GL_ZERO: stencilctl |= (0 << 24); break;
351 case GL_KEEP: stencilctl |= (1 << 24); break;
352 case GL_INVERT: stencilctl |= (2 << 24); break;
353 case GL_REPLACE: stencilctl |= (3 << 24); break;
354 case GL_INCR: stencilctl |= (4 << 24); break;
355 case GL_DECR: stencilctl |= (5 << 24); break;
356
357 default:
358 return;
359 };
360
361 switch (zpass) {
362 case GL_ZERO: stencilctl |= (0 << 20); break;
363 case GL_KEEP: stencilctl |= (1 << 20); break;
364 case GL_INVERT: stencilctl |= (2 << 20); break;
365 case GL_REPLACE: stencilctl |= (3 << 20); break;
366 case GL_INCR: stencilctl |= (4 << 20); break;
367 case GL_DECR: stencilctl |= (5 << 20); break;
368
369 default:
370 return;
371 };
372
373 if (fmesa->stencilctl != stencilctl) {
374 fmesa->stencilctl = stencilctl;
375 FFB_MAKE_DIRTY(fmesa, FFB_STATE_STENCIL, 6);
376 }
377 }
378
379 static void ffbCalcViewportRegs(GLcontext *ctx)
380 {
381 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
382 __DRIdrawable *dPriv = fmesa->driDrawable;
383 GLuint xmin, xmax, ymin, ymax, zmin, zmax;
384 unsigned int vcmin, vcmax;
385
386 xmin = ctx->Viewport.X + dPriv->x;
387 xmax = xmin + ctx->Viewport.Width;
388 ymax = dPriv->y + dPriv->h - ctx->Viewport.Y;
389 ymin = ymax - ctx->Viewport.Height;
390 if (ctx->Scissor.Enabled) {
391 GLuint sc_xmin, sc_xmax, sc_ymin, sc_ymax;
392
393 sc_xmin = ctx->Viewport.X + dPriv->x;
394 sc_xmax = sc_xmin + ctx->Viewport.Width;
395 sc_ymax = dPriv->y + dPriv->h - ctx->Viewport.Y;
396 sc_ymin = sc_ymax - ctx->Viewport.Height;
397 if (sc_xmin > xmin)
398 xmin = sc_xmin;
399 if (sc_xmax < xmax)
400 xmax = sc_xmax;
401 if (sc_ymin > ymin)
402 ymin = sc_ymin;
403 if (sc_ymax < ymax)
404 ymax = sc_ymax;
405 }
406 zmin = ((GLdouble)ctx->Viewport.Near * 0x0fffffff);
407 zmax = ((GLdouble)ctx->Viewport.Far * 0x0fffffff);
408
409 vcmin = ((ymin & 0xffff) << 16) | (xmin & 0xffff);
410 vcmax = ((ymax & 0xffff) << 16) | (xmax & 0xffff);
411 if (fmesa->vclipmin != vcmin ||
412 fmesa->vclipmax != vcmax ||
413 fmesa->vclipzmin != zmin ||
414 fmesa->vclipzmax != zmax) {
415 fmesa->vclipmin = vcmin;
416 fmesa->vclipmax = vcmax;
417 fmesa->vclipzmin = zmin;
418 fmesa->vclipzmax = zmax;
419 FFB_MAKE_DIRTY(fmesa, FFB_STATE_CLIP, (4 + (4 * 2)));
420 }
421 }
422
423 void ffbCalcViewport(GLcontext *ctx)
424 {
425 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
426 const GLfloat *v = ctx->Viewport._WindowMap.m;
427 GLfloat *m = fmesa->hw_viewport;
428 __DRIdrawable *dPriv = fmesa->driDrawable;
429
430 m[MAT_SX] = v[MAT_SX];
431 m[MAT_TX] = v[MAT_TX] + dPriv->x + SUBPIXEL_X;
432 m[MAT_SY] = - v[MAT_SY];
433 m[MAT_TY] = - v[MAT_TY] + dPriv->h + dPriv->y + SUBPIXEL_Y;
434 m[MAT_SZ] = v[MAT_SZ] * ((GLdouble)1.0 / (GLdouble)0x0fffffff);
435 m[MAT_TZ] = v[MAT_TZ] * ((GLdouble)1.0 / (GLdouble)0x0fffffff);
436
437 fmesa->depth_scale = ((GLdouble)1.0 / (GLdouble)0x0fffffff);
438
439 ffbCalcViewportRegs(ctx);
440
441 fmesa->setupnewinputs |= VERT_BIT_POS;
442 }
443
444 static void ffbDDViewport(GLcontext *ctx, GLint x, GLint y,
445 GLsizei width, GLsizei height)
446 {
447 ffbCalcViewport(ctx);
448 }
449
450 static void ffbDDDepthRange(GLcontext *ctx, GLclampd nearval, GLclampd farval)
451 {
452 ffbCalcViewport(ctx);
453 }
454
455 static void ffbDDScissor(GLcontext *ctx, GLint cx, GLint cy,
456 GLsizei cw, GLsizei ch)
457 {
458 ffbCalcViewport(ctx);
459 }
460
461 static void ffbDDDrawBuffer(GLcontext *ctx, GLenum buffer)
462 {
463 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
464 unsigned int fbc = fmesa->fbc;
465
466 #ifdef STATE_TRACE
467 fprintf(stderr, "ffbDDDrawBuffer: mode(%s)\n",
468 _mesa_lookup_enum_by_nr(buffer));
469 #endif
470 fbc &= ~(FFB_FBC_WB_AB | FFB_FBC_RB_MASK);
471 switch (buffer) {
472 case GL_FRONT:
473 if (fmesa->back_buffer == 0)
474 fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B;
475 else
476 fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A;
477 break;
478
479 case GL_BACK:
480 if (fmesa->back_buffer == 0)
481 fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A;
482 else
483 fbc |= FFB_FBC_WB_B | FFB_FBC_RB_B;
484 break;
485
486 case GL_FRONT_AND_BACK:
487 fbc |= FFB_FBC_WB_AB;
488 break;
489
490 default:
491 return;
492 };
493
494 if (fbc != fmesa->fbc) {
495 fmesa->fbc = fbc;
496 FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1);
497 }
498 }
499
500
501 static void ffbDDReadBuffer(GLcontext *ctx, GLenum buffer)
502 {
503 /* no-op, unless you implement h/w glRead/CopyPixels */
504 }
505
506
507 /*
508 * Specifies buffer for sw fallbacks (spans)
509 */
510 #if 000
511 /* XXX
512 * This function is obsolete. It's not clear how this really effected
513 * span reading/writing above. The span functions should use the
514 * incoming driRenderbuffer (gl_renderbuffer) pointer to determine how
515 * to read from the specified bufer.
516 */
517 static void ffbDDSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
518 GLuint bufferBit)
519 {
520 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
521 unsigned int fbc = fmesa->fbc;
522
523 #ifdef STATE_TRACE
524 fprintf(stderr, "ffbDDSetReadBuffer: mode(%s)\n",
525 _mesa_lookup_enum_by_nr(buffer));
526 #endif
527 fbc &= ~(FFB_FBC_RB_MASK);
528 switch (bufferBit) {
529 case BUFFER_BIT_FRONT_LEFT:
530 if (fmesa->back_buffer == 0)
531 fbc |= FFB_FBC_RB_B;
532 else
533 fbc |= FFB_FBC_RB_A;
534 break;
535
536 case BUFFER_BIT_BACK_LEFT:
537 if (fmesa->back_buffer == 0)
538 fbc |= FFB_FBC_RB_A;
539 else
540 fbc |= FFB_FBC_RB_B;
541 break;
542
543 default:
544 _mesa_problem(ctx, "Unexpected buffer in ffbDDSetBuffer()");
545 return;
546 };
547
548 if (fbc != fmesa->fbc) {
549 fmesa->fbc = fbc;
550 FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1);
551 }
552 }
553 #endif
554
555
556 static void ffbDDClearColor(GLcontext *ctx, const GLfloat color[4])
557 {
558 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
559 GLubyte c[4];
560 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
561 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
562 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
563
564 fmesa->clear_pixel = ((c[0] << 0) |
565 (c[1] << 8) |
566 (c[2] << 16));
567 }
568
569 static void ffbDDClearDepth(GLcontext *ctx, GLclampd depth)
570 {
571 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
572
573 fmesa->clear_depth = Z_FROM_MESA(depth * 4294967295.0f);
574 }
575
576 static void ffbDDClearStencil(GLcontext *ctx, GLint stencil)
577 {
578 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
579
580 fmesa->clear_stencil = stencil & 0xf;
581 }
582
583 /* XXX Actually, should I be using FBC controls for this? -DaveM */
584 static void ffbDDColorMask(GLcontext *ctx,
585 GLboolean r, GLboolean g,
586 GLboolean b, GLboolean a)
587 {
588 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
589 unsigned int new_pmask = 0x0;
590
591 #ifdef STATE_TRACE
592 fprintf(stderr, "ffbDDColorMask: r(%d) g(%d) b(%d) a(%d)\n",
593 r, g, b, a);
594 #endif
595 if (r)
596 new_pmask |= 0x000000ff;
597 if (g)
598 new_pmask |= 0x0000ff00;
599 if (b)
600 new_pmask |= 0x00ff0000;
601 if (a)
602 new_pmask |= 0xff000000;
603
604 if (fmesa->pmask != new_pmask) {
605 fmesa->pmask = new_pmask;
606 FFB_MAKE_DIRTY(fmesa, FFB_STATE_PMASK, 1);
607 }
608 }
609
610 static void ffbDDLogicOp(GLcontext *ctx, GLenum op)
611 {
612 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
613 unsigned int rop;
614
615 #ifdef STATE_TRACE
616 fprintf(stderr, "ffbDDLogicOp: op(%s)\n",
617 _mesa_lookup_enum_by_nr(op));
618 #endif
619 switch (op) {
620 case GL_CLEAR: rop = FFB_ROP_ZERO; break;
621 case GL_SET: rop = FFB_ROP_ONES; break;
622 case GL_COPY: rop = FFB_ROP_NEW; break;
623 case GL_AND: rop = FFB_ROP_NEW_AND_OLD; break;
624 case GL_NAND: rop = FFB_ROP_NEW_AND_NOLD; break;
625 case GL_OR: rop = FFB_ROP_NEW_OR_OLD; break;
626 case GL_NOR: rop = FFB_ROP_NEW_OR_NOLD; break;
627 case GL_XOR: rop = FFB_ROP_NEW_XOR_OLD; break;
628 case GL_NOOP: rop = FFB_ROP_OLD; break;
629 case GL_COPY_INVERTED: rop = FFB_ROP_NNEW; break;
630 case GL_INVERT: rop = FFB_ROP_NOLD; break;
631 case GL_EQUIV: rop = FFB_ROP_NNEW_XOR_NOLD; break;
632 case GL_AND_REVERSE: rop = FFB_ROP_NEW_AND_NOLD; break;
633 case GL_AND_INVERTED: rop = FFB_ROP_NNEW_AND_OLD; break;
634 case GL_OR_REVERSE: rop = FFB_ROP_NEW_OR_NOLD; break;
635 case GL_OR_INVERTED: rop = FFB_ROP_NNEW_OR_OLD; break;
636
637 default:
638 return;
639 };
640
641 rop |= fmesa->rop & ~0xff;
642 if (rop != fmesa->rop) {
643 fmesa->rop = rop;
644 FFB_MAKE_DIRTY(fmesa, FFB_STATE_ROP, 1);
645
646 if (op == GL_COPY)
647 FALLBACK( ctx, FFB_BADATTR_BLENDROP, GL_FALSE );
648 }
649 }
650
651 #if 0
652 /* XXX Also need to track near/far just like 3dfx driver.
653 * XXX
654 * XXX Actually, that won't work, because the 3dfx chip works by
655 * XXX having 1/w coordinates fed to it for each primitive, and
656 * XXX it uses this to index it's 64 entry fog table.
657 */
658 static void ffb_fog_linear(GLcontext *ctx, ffbContextPtr fmesa)
659 {
660 GLfloat c = ctx->ProjectionMatrix.m[10];
661 GLfloat d = ctx->ProjectionMatrix.m[14];
662 GLfloat tz = ctx->Viewport.WindowMap.m[MAT_TZ];
663 GLfloat szInv = 1.0F / ctx->Viewport.WindowMap.m[MAT_SZ];
664 GLfloat fogEnd = ctx->Fog.End;
665 GLfloat fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
666 GLfloat ndcz;
667 GLfloat eyez;
668 GLfloat Zzero, Zone;
669 unsigned int zb, zf;
670
671 /* Compute the Z at which f reaches 0.0, this is the full
672 * saturation point.
673 *
674 * Thus compute Z (as seen by the chip during rendering),
675 * such that:
676 *
677 * 0.0 = (fogEnd - eyez) * fogScale
678 *
679 * fogScale is usually not zero, thus we are looking for:
680 *
681 * fogEnd = eyez
682 *
683 * fogEnd = -d / (c + ((Z - tz) * szInv))
684 * fogEnd * (c + ((Z - tz) * szInv)) = -d
685 * (c + ((Z - tz) * szInv)) = -d / fogEnd
686 * (Z - tz) * szInv = (-d / fogEnd) - c
687 * (Z - tz) = ((-d / fogEnd) - c) / szInv
688 * Z = (((-d / fogEnd) - c) / szInv) + tz
689 */
690 Zzero = (((-d / fogEnd) - c) / szInv) + tz;
691
692 /* Compute the Z at which f reaches 1.0, this is where
693 * the incoming frag's full intensity is shown. This
694 * equation is:
695 *
696 * 1.0 = (fogEnd - eyez)
697 *
698 * We are looking for:
699 *
700 * 1.0 + eyez = fogEnd
701 *
702 * 1.0 + (-d / (c + ((Z - tz) * szInv))) = fogEnd
703 * -d / (c + ((Z - tz) * szInv)) = fogEnd - 1.0
704 * -d / (FogEnd - 1.0) = (c + ((Z - tz) * szInv))
705 * (-d / (fogEnd - 1.0)) - c = ((Z - tz) * szInv)
706 * ((-d / (fogEnd - 1.0)) - c) / szInv = (Z - tz)
707 * (((-d / (fogEnd - 1.0)) - c) / szInv) + tz = Z
708 */
709 Zone = (((-d / (fogEnd - 1.0)) - c) / szInv) + tz;
710
711 /* FFB's Zfront must be less than Zback, thus we may have
712 * to invert Sf/Sb to satisfy this constraint.
713 */
714 if (Zzero < Zone) {
715 sf = 0.0;
716 sb = 1.0;
717 zf = Z_FROM_MESA(Zzero);
718 zb = Z_FROM_MESA(Zone);
719 } else {
720 sf = 1.0;
721 sb = 0.0;
722 zf = Z_FROM_MESA(Zone);
723 zb = Z_FROM_MESA(Zzero);
724 }
725 }
726 #endif
727
728 static void ffbDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
729 {
730 #ifdef STATE_TRACE
731 fprintf(stderr, "ffbDDFogfv: pname(%s)\n", _mesa_lookup_enum_by_nr(pname));
732 #endif
733 }
734
735 static void ffbDDLineStipple(GLcontext *ctx, GLint factor, GLushort pattern)
736 {
737 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
738
739 #ifdef STATE_TRACE
740 fprintf(stderr, "ffbDDLineStipple: factor(%d) pattern(%04x)\n",
741 factor, pattern);
742 #endif
743 if (ctx->Line.StippleFlag) {
744 factor = ctx->Line.StippleFactor;
745 pattern = ctx->Line.StipplePattern;
746 if ((GLuint) factor > 15) {
747 fmesa->lpat = FFB_LPAT_BAD;
748 } else {
749 fmesa->lpat = ((factor << FFB_LPAT_SCALEVAL_SHIFT) |
750 (0 << FFB_LPAT_PATLEN_SHIFT) |
751 ((pattern & 0xffff) << FFB_LPAT_PATTERN_SHIFT));
752 }
753 } else {
754 fmesa->lpat = 0;
755 }
756 }
757
758 void ffbXformAreaPattern(ffbContextPtr fmesa, const GLubyte *mask)
759 {
760 __DRIdrawable *dPriv = fmesa->driDrawable;
761 int i, lines, xoff;
762
763 lines = 0;
764 i = (dPriv->y + dPriv->h) & (32 - 1);
765 xoff = dPriv->x & (32 - 1);
766 while (lines++ < 32) {
767 GLuint raw =
768 (((GLuint)mask[0] << 24) |
769 ((GLuint)mask[1] << 16) |
770 ((GLuint)mask[2] << 8) |
771 ((GLuint)mask[3] << 0));
772
773 fmesa->pattern[i] =
774 (raw << xoff) | (raw >> (32 - xoff));
775 i = (i - 1) & (32 - 1);
776 mask += 4;
777 }
778
779 FFB_MAKE_DIRTY(fmesa, FFB_STATE_APAT, 32);
780 }
781
782 static void ffbDDPolygonStipple(GLcontext *ctx, const GLubyte *mask)
783 {
784 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
785
786 #ifdef STATE_TRACE
787 fprintf(stderr, "ffbDDPolygonStipple: state(%d)\n",
788 ctx->Polygon.StippleFlag);
789 #endif
790 ffbXformAreaPattern(fmesa, mask);
791 }
792
793 static void ffbDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
794 {
795 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
796 unsigned int tmp;
797
798 #ifdef STATE_TRACE
799 fprintf(stderr, "ffbDDEnable: %s state(%d)\n",
800 _mesa_lookup_enum_by_nr(cap), state);
801 #endif
802 switch (cap) {
803 case GL_ALPHA_TEST:
804 if (state)
805 tmp = ffbComputeAlphaFunc(ctx);
806 else
807 tmp = FFB_XCLIP_TEST_ALWAYS;
808
809 if (tmp != fmesa->xclip) {
810 fmesa->xclip = tmp;
811 FFB_MAKE_DIRTY(fmesa, FFB_STATE_XCLIP, 1);
812 }
813 break;
814
815 case GL_BLEND:
816 tmp = (fmesa->ppc & ~FFB_PPC_ABE_MASK);
817 if (state) {
818 tmp |= FFB_PPC_ABE_ENABLE;
819 } else {
820 tmp |= FFB_PPC_ABE_DISABLE;
821 }
822 if (fmesa->ppc != tmp) {
823 fmesa->ppc = tmp;
824 FFB_MAKE_DIRTY(fmesa, FFB_STATE_PPC, 1);
825 ffbDDBlendFuncSeparate(ctx, 0, 0, 0, 0 );
826 }
827 break;
828
829 case GL_DEPTH_TEST:
830 if (state)
831 tmp = 0x0fffffff;
832 else
833 tmp = 0x00000000;
834 if (tmp != fmesa->magnc) {
835 unsigned int fbc = fmesa->fbc;
836 fbc &= ~FFB_FBC_ZE_MASK;
837 if (state)
838 fbc |= FFB_FBC_ZE_ON;
839 else
840 fbc |= FFB_FBC_ZE_OFF;
841 fmesa->fbc = fbc;
842 ffbDDDepthFunc(ctx, ctx->Depth.Func);
843 fmesa->magnc = tmp;
844 FFB_MAKE_DIRTY(fmesa, (FFB_STATE_MAGNC | FFB_STATE_FBC), 2);
845 }
846 break;
847
848 case GL_SCISSOR_TEST:
849 ffbDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
850 ctx->Scissor.Width, ctx->Scissor.Height);
851 break;
852
853 case GL_STENCIL_TEST:
854 if (!(fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS)) {
855 FALLBACK( ctx, FFB_BADATTR_STENCIL, state );
856 }
857
858 tmp = fmesa->fbc & ~FFB_FBC_YE_MASK;
859 if (state) {
860 ffbDDStencilFuncSeparate(ctx, GL_FRONT,
861 ctx->Stencil.Function[0],
862 ctx->Stencil.Ref[0],
863 ctx->Stencil.ValueMask[0]);
864 ffbDDStencilMaskSeparate(ctx, GL_FRONT,
865 ctx->Stencil.WriteMask[0]);
866 ffbDDStencilOpSeparate(ctx, GL_FRONT,
867 ctx->Stencil.FailFunc[0],
868 ctx->Stencil.ZFailFunc[0],
869 ctx->Stencil.ZPassFunc[0]);
870 tmp |= FFB_FBC_YE_MASK;
871 } else {
872 fmesa->stencil = 0xf0000000;
873 fmesa->stencilctl = 0x33300000;
874 FFB_MAKE_DIRTY(fmesa, FFB_STATE_STENCIL, 6);
875 tmp |= FFB_FBC_YE_OFF;
876 }
877 if (tmp != fmesa->fbc) {
878 fmesa->fbc = tmp;
879 FFB_MAKE_DIRTY(fmesa, FFB_STATE_FBC, 1);
880 }
881 break;
882
883 case GL_FOG:
884 /* Until I implement the fog support... */
885 FALLBACK( ctx, FFB_BADATTR_FOG, state );
886 break;
887
888 case GL_LINE_STIPPLE:
889 if (! state)
890 fmesa->lpat = 0;
891 else
892 ffbDDLineStipple(ctx,
893 ctx->Line.StippleFactor,
894 ctx->Line.StipplePattern);
895 break;
896
897 case GL_POLYGON_STIPPLE:
898 /* Do nothing, we interrogate the state during
899 * reduced primitive changes. Since our caller
900 * will set NEW_POLYGON in the ctx NewState this
901 * will cause the driver rasterization functions
902 * to be reevaluated, which will cause us to force
903 * a reduced primitive change next rendering pass
904 * and it all works out.
905 */
906 break;
907
908 default:
909 break;
910 };
911 }
912
913 void ffbSyncHardware(ffbContextPtr fmesa)
914 {
915 ffb_fbcPtr ffb = fmesa->regs;
916 unsigned int dirty;
917 int i;
918
919 FFBFifo(fmesa, fmesa->state_fifo_ents);
920
921 dirty = fmesa->state_dirty;
922 if (dirty & (FFB_STATE_FBC | FFB_STATE_PPC | FFB_STATE_DRAWOP |
923 FFB_STATE_ROP | FFB_STATE_LPAT | FFB_STATE_WID)) {
924 if (dirty & FFB_STATE_FBC)
925 ffb->fbc = fmesa->fbc;
926 if (dirty & FFB_STATE_PPC)
927 ffb->ppc = fmesa->ppc;
928 if (dirty & FFB_STATE_DRAWOP)
929 ffb->drawop = fmesa->drawop;
930 if (dirty & FFB_STATE_ROP)
931 ffb->rop = fmesa->rop;
932 if (dirty & FFB_STATE_LPAT)
933 ffb->rop = fmesa->lpat;
934 if (dirty & FFB_STATE_WID)
935 ffb->wid = fmesa->wid;
936 }
937 if (dirty & (FFB_STATE_PMASK | FFB_STATE_XPMASK | FFB_STATE_YPMASK |
938 FFB_STATE_ZPMASK | FFB_STATE_XCLIP | FFB_STATE_CMP |
939 FFB_STATE_MATCHAB | FFB_STATE_MAGNAB | FFB_STATE_MATCHC |
940 FFB_STATE_MAGNC)) {
941 if (dirty & FFB_STATE_PMASK)
942 ffb->pmask = fmesa->pmask;
943 if (dirty & FFB_STATE_XPMASK)
944 ffb->xpmask = fmesa->xpmask;
945 if (dirty & FFB_STATE_YPMASK)
946 ffb->ypmask = fmesa->ypmask;
947 if (dirty & FFB_STATE_ZPMASK)
948 ffb->zpmask = fmesa->zpmask;
949 if (dirty & FFB_STATE_XCLIP)
950 ffb->xclip = fmesa->xclip;
951 if (dirty & FFB_STATE_CMP)
952 ffb->cmp = fmesa->cmp;
953 if (dirty & FFB_STATE_MATCHAB)
954 ffb->matchab = fmesa->matchab;
955 if (dirty & FFB_STATE_MAGNAB)
956 ffb->magnab = fmesa->magnab;
957 if (dirty & FFB_STATE_MATCHC)
958 ffb->matchc = fmesa->matchc;
959 if (dirty & FFB_STATE_MAGNC)
960 ffb->magnc = fmesa->magnc;
961 }
962
963 if (dirty & FFB_STATE_DCUE) {
964 ffb->dcss = fmesa->dcss;
965 ffb->dcsf = fmesa->dcsf;
966 ffb->dcsb = fmesa->dcsb;
967 ffb->dczf = fmesa->dczf;
968 ffb->dczb = fmesa->dczb;
969 if (fmesa->ffb_sarea->flags & (FFB_DRI_FFB2 | FFB_DRI_FFB2PLUS)) {
970 ffb->dcss1 = fmesa->dcss1;
971 ffb->dcss2 = fmesa->dcss2;
972 ffb->dcss3 = fmesa->dcss3;
973 ffb->dcs2 = fmesa->dcs2;
974 ffb->dcs3 = fmesa->dcs3;
975 ffb->dcs4 = fmesa->dcs4;
976 ffb->dcd2 = fmesa->dcd2;
977 ffb->dcd3 = fmesa->dcd3;
978 ffb->dcd4 = fmesa->dcd4;
979 }
980 }
981
982 if (dirty & FFB_STATE_BLEND) {
983 ffb->blendc = fmesa->blendc;
984 ffb->blendc1 = fmesa->blendc1;
985 ffb->blendc2 = fmesa->blendc2;
986 }
987
988 if (dirty & FFB_STATE_CLIP) {
989 ffb->vclipmin = fmesa->vclipmin;
990 ffb->vclipmax = fmesa->vclipmax;
991 ffb->vclipzmin = fmesa->vclipzmin;
992 ffb->vclipzmax = fmesa->vclipzmax;
993 for (i = 0; i < 4; i++) {
994 ffb->auxclip[i].min = fmesa->aux_clips[i].min;
995 ffb->auxclip[i].max = fmesa->aux_clips[i].max;
996 }
997 }
998
999 if ((dirty & FFB_STATE_STENCIL) &&
1000 (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS)) {
1001 ffb->stencil = fmesa->stencil;
1002 ffb->stencilctl = fmesa->stencilctl;
1003 ffb->fbc = FFB_FBC_WB_C;
1004 ffb->rawstencilctl = (fmesa->stencilctl | (1 << 19));
1005 ffb->fbc = fmesa->fbc;
1006 ffb->consty = fmesa->consty;
1007 }
1008
1009 if (dirty & FFB_STATE_APAT) {
1010 for (i = 0; i < 32; i++)
1011 ffb->pattern[i] = fmesa->pattern[i];
1012 }
1013
1014 fmesa->state_dirty = 0;
1015 fmesa->state_fifo_ents = 0;
1016 fmesa->ffbScreen->rp_active = 1;
1017 }
1018
1019 static void ffbDDUpdateState(GLcontext *ctx, GLuint newstate)
1020 {
1021 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
1022
1023 /* When we are hw rendering, changing certain kinds of
1024 * state does not require flushing all of our context.
1025 */
1026 if (fmesa->bad_fragment_attrs == 0 &&
1027 (newstate & ~_NEW_COLOR) == 0)
1028 return;
1029
1030 _swrast_InvalidateState( ctx, newstate );
1031 _swsetup_InvalidateState( ctx, newstate );
1032 _vbo_InvalidateState( ctx, newstate );
1033 _tnl_InvalidateState( ctx, newstate );
1034
1035 if (newstate & _NEW_TEXTURE)
1036 FALLBACK( ctx, FFB_BADATTR_TEXTURE,
1037 (ctx->Texture._EnabledUnits != 0));
1038
1039 #ifdef STATE_TRACE
1040 fprintf(stderr, "ffbDDUpdateState: newstate(%08x)\n", newstate);
1041 #endif
1042
1043 fmesa->new_gl_state |= newstate;
1044
1045 /* Force a reduced primitive change next rendering
1046 * pass.
1047 */
1048 fmesa->raster_primitive = GL_POLYGON + 1;
1049
1050 #if 0
1051 /* When the modelview matrix changes, this changes what
1052 * the eye coordinates will be so we have to recompute
1053 * the depth cueing parameters.
1054 *
1055 * XXX DD_HAVE_HARDWARE_FOG.
1056 */
1057 if (ctx->Fog.Enabled && (newstate & _NEW_MODELVIEW))
1058 ffb_update_fog();
1059 #endif
1060 }
1061
1062
1063 void ffbDDInitStateFuncs(GLcontext *ctx)
1064 {
1065 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
1066
1067 ctx->Driver.UpdateState = ffbDDUpdateState;
1068
1069 ctx->Driver.Enable = ffbDDEnable;
1070 ctx->Driver.AlphaFunc = ffbDDAlphaFunc;
1071 ctx->Driver.BlendEquationSeparate = ffbDDBlendEquationSeparate;
1072 ctx->Driver.BlendFuncSeparate = ffbDDBlendFuncSeparate;
1073 ctx->Driver.DepthFunc = ffbDDDepthFunc;
1074 ctx->Driver.DepthMask = ffbDDDepthMask;
1075 ctx->Driver.Fogfv = ffbDDFogfv;
1076 ctx->Driver.LineStipple = ffbDDLineStipple;
1077 ctx->Driver.PolygonStipple = ffbDDPolygonStipple;
1078 ctx->Driver.Scissor = ffbDDScissor;
1079 ctx->Driver.ColorMask = ffbDDColorMask;
1080 ctx->Driver.LogicOpcode = ffbDDLogicOp;
1081 ctx->Driver.Viewport = ffbDDViewport;
1082 ctx->Driver.DepthRange = ffbDDDepthRange;
1083
1084 if (fmesa->ffb_sarea->flags & FFB_DRI_FFB2PLUS) {
1085 ctx->Driver.StencilFuncSeparate = ffbDDStencilFuncSeparate;
1086 ctx->Driver.StencilMaskSeparate = ffbDDStencilMaskSeparate;
1087 ctx->Driver.StencilOpSeparate = ffbDDStencilOpSeparate;
1088 }
1089
1090 ctx->Driver.DrawBuffer = ffbDDDrawBuffer;
1091 ctx->Driver.ReadBuffer = ffbDDReadBuffer;
1092 ctx->Driver.ClearColor = ffbDDClearColor;
1093 ctx->Driver.ClearDepth = ffbDDClearDepth;
1094 ctx->Driver.ClearStencil = ffbDDClearStencil;
1095
1096 /* We will support color index modes later... -DaveM */
1097 /*
1098 ctx->Driver.ClearIndex = 0;
1099 ctx->Driver.IndexMask = 0;
1100 */
1101 }
1102
1103 void ffbDDInitContextHwState(GLcontext *ctx)
1104 {
1105 ffbContextPtr fmesa = FFB_CONTEXT(ctx);
1106 int fifo_count = 0;
1107 int i;
1108
1109 fmesa->hw_locked = 0;
1110
1111 fmesa->bad_fragment_attrs = 0;
1112 fmesa->state_dirty = FFB_STATE_ALL;
1113 fmesa->new_gl_state = ~0;
1114
1115 fifo_count = 1;
1116 fmesa->fbc = (FFB_FBC_WE_FORCEON | FFB_FBC_WM_COMBINED |
1117 FFB_FBC_SB_BOTH | FFB_FBC_ZE_MASK |
1118 FFB_FBC_YE_OFF | FFB_FBC_XE_OFF |
1119 FFB_FBC_RGBE_MASK);
1120 if (ctx->Visual.doubleBufferMode) {
1121 /* Buffer B is the initial back buffer. */
1122 fmesa->back_buffer = 1;
1123 fmesa->fbc |= FFB_FBC_WB_BC | FFB_FBC_RB_B;
1124 } else {
1125 fmesa->back_buffer = 0;
1126 fmesa->fbc |= FFB_FBC_WB_A | FFB_FBC_RB_A;
1127 }
1128
1129 fifo_count += 1;
1130 fmesa->ppc = (FFB_PPC_ACE_DISABLE | FFB_PPC_DCE_DISABLE |
1131 FFB_PPC_ABE_DISABLE | FFB_PPC_VCE_3D |
1132 FFB_PPC_APE_DISABLE | FFB_PPC_TBE_OPAQUE |
1133 FFB_PPC_ZS_CONST | FFB_PPC_YS_CONST |
1134 FFB_PPC_XS_WID | FFB_PPC_CS_VAR);
1135
1136 fifo_count += 3;
1137 fmesa->drawop = FFB_DRAWOP_RECTANGLE;
1138
1139 /* GL_COPY is the default LogicOp. */
1140 fmesa->rop = (FFB_ROP_NEW << 16) | (FFB_ROP_NEW << 8) | FFB_ROP_NEW;
1141
1142 /* No line patterning enabled. */
1143 fmesa->lpat = 0x00000000;
1144
1145 /* We do not know the WID value until the first context switch. */
1146 fifo_count += 1;
1147 fmesa->wid = ~0;
1148
1149 fifo_count += 5;
1150
1151 /* ColorMask, all enabled. */
1152 fmesa->pmask = 0xffffffff;
1153
1154 fmesa->xpmask = 0x000000ff;
1155 fmesa->ypmask = 0x0000000f;
1156 fmesa->zpmask = 0x0fffffff;
1157
1158 /* AlphaFunc GL_ALWAYS, AlphaRef 0 */
1159 fmesa->xclip = FFB_XCLIP_TEST_ALWAYS | 0x00;
1160
1161 /* This sets us up to use WID clipping (so the DRI clipping
1162 * rectangle is unneeded by us). All other match and magnitude
1163 * tests are set to pass.
1164 */
1165 fifo_count += 5;
1166 fmesa->cmp = ((FFB_CMP_MATCH_ALWAYS << 24) | /* MATCH C */
1167 (FFB_CMP_MAGN_ALWAYS << 16) | /* MAGN C */
1168 (FFB_CMP_MATCH_EQ << 8) | /* MATCH AB */
1169 (FFB_CMP_MAGN_ALWAYS << 0)); /* MAGN AB */
1170 fmesa->matchab = 0xff000000;
1171 fmesa->magnab = 0x00000000;
1172 fmesa->matchc = 0x00000000;
1173 fmesa->magnc = 0x00000000;
1174
1175 /* Depth cue parameters, all zeros to start. */
1176 fifo_count += 14;
1177 fmesa->dcss = 0x00000000;
1178 fmesa->dcsf = 0x00000000;
1179 fmesa->dcsb = 0x00000000;
1180 fmesa->dczf = 0x00000000;
1181 fmesa->dczb = 0x00000000;
1182 fmesa->dcss1 = 0x00000000;
1183 fmesa->dcss2 = 0x00000000;
1184 fmesa->dcss3 = 0x00000000;
1185 fmesa->dcs2 = 0x00000000;
1186 fmesa->dcs3 = 0x00000000;
1187 fmesa->dcs4 = 0x00000000;
1188 fmesa->dcd2 = 0x00000000;
1189 fmesa->dcd3 = 0x00000000;
1190 fmesa->dcd4 = 0x00000000;
1191
1192 /* Alpha blending unit state. */
1193 fifo_count += 3;
1194 fmesa->blendc = (1 << 0) | (0 << 2); /* src(GL_ONE) | dst(GL_ZERO) */
1195 fmesa->blendc1 = 0x00000000;
1196 fmesa->blendc2 = 0x00000000;
1197
1198 /* ViewPort clip state. */
1199 fifo_count += 4 + (4 * 2);
1200 fmesa->vclipmin = 0x00000000;
1201 fmesa->vclipmax = 0xffffffff;
1202 fmesa->vclipzmin = 0x00000000;
1203 fmesa->vclipzmax = 0x0fffffff;
1204 for (i = 0; i < 4; i++) {
1205 fmesa->aux_clips[0].min = 0x00000000;
1206 fmesa->aux_clips[0].max = 0x00000000;
1207 }
1208
1209 /* Stenciling state. */
1210 fifo_count += 6;
1211 fmesa->stencil = 0xf0000000; /* Stencil MASK, Y plane */
1212 fmesa->stencilctl = 0x33300000; /* All stencil tests disabled */
1213 fmesa->consty = 0x0;
1214
1215 /* Area pattern, used for polygon stipples. */
1216 fifo_count += 32;
1217 for (i = 0; i < 32; i++)
1218 fmesa->pattern[i] = 0x00000000;
1219
1220 fmesa->state_fifo_ents = fifo_count;
1221 fmesa->state_all_fifo_ents = fifo_count;
1222 }