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