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