Migrate i830 driver to t_vertex.[ch] for building hw vertices.
[mesa.git] / src / mesa / drivers / dri / i830 / i830_state.c
1 /**************************************************************************
2
3 Copyright 2001 2d3d Inc., Delray Beach, FL
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.6 2003/01/28 22:47:06 dawes Exp $ */
29
30 /*
31 * Author:
32 * Jeff Hartmann <jhartmann@2d3d.com>
33 *
34 * Heavily based on the I810 driver, which was written by:
35 * Keith Whitwell <keith@tungstengraphics.com>
36 */
37
38 #include "glheader.h"
39 #include "context.h"
40 #include "macros.h"
41 #include "enums.h"
42 #include "dd.h"
43
44 #include "texmem.h"
45
46 #include "i830_screen.h"
47 #include "i830_dri.h"
48
49 #include "i830_context.h"
50 #include "i830_state.h"
51 #include "i830_tex.h"
52 #include "i830_tris.h"
53 #include "i830_ioctl.h"
54
55 #include "swrast/swrast.h"
56 #include "array_cache/acache.h"
57 #include "tnl/tnl.h"
58 #include "swrast_setup/swrast_setup.h"
59
60 #include "tnl/t_pipeline.h"
61
62 static __inline__ GLuint i830PackColor(GLuint format,
63 GLubyte r, GLubyte g,
64 GLubyte b, GLubyte a)
65 {
66
67 if (I830_DEBUG&DEBUG_DRI)
68 fprintf(stderr, "%s\n", __FUNCTION__);
69
70 switch (format) {
71 case DV_PF_555:
72 return I830PACKCOLOR1555(r,g,b,a);
73 case DV_PF_565:
74 return I830PACKCOLOR565(r,g,b);
75 case DV_PF_8888:
76 return I830PACKCOLOR8888(r,g,b,a);
77 default:
78 fprintf(stderr, "unknown format %d\n", (int)format);
79 return 0;
80 }
81 }
82
83 static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref,
84 GLuint mask)
85 {
86 i830ContextPtr imesa = I830_CONTEXT(ctx);
87 int test = 0;
88
89 mask = mask & 0xff;
90
91 if (I830_DEBUG&DEBUG_DRI)
92 fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
93 _mesa_lookup_enum_by_nr(func), ref, mask);
94
95 switch(func) {
96 case GL_NEVER:
97 test = COMPAREFUNC_NEVER;
98 break;
99 case GL_LESS:
100 test = COMPAREFUNC_LESS;
101 break;
102 case GL_LEQUAL:
103 test = COMPAREFUNC_LEQUAL;
104 break;
105 case GL_GREATER:
106 test = COMPAREFUNC_GREATER;
107 break;
108 case GL_GEQUAL:
109 test = COMPAREFUNC_GEQUAL;
110 break;
111 case GL_NOTEQUAL:
112 test = COMPAREFUNC_NOTEQUAL;
113 break;
114 case GL_EQUAL:
115 test = COMPAREFUNC_EQUAL;
116 break;
117 case GL_ALWAYS:
118 test = COMPAREFUNC_ALWAYS;
119 break;
120 default:
121 return;
122 }
123
124 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
125 imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
126 imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
127 STENCIL_TEST_MASK(mask));
128 imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
129 ENABLE_STENCIL_TEST_FUNC_MASK);
130 imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE |
131 ENABLE_STENCIL_TEST_FUNC |
132 STENCIL_REF_VALUE(ref) |
133 STENCIL_TEST_FUNC(test));
134 }
135
136 static void i830StencilMask(GLcontext *ctx, GLuint mask)
137 {
138 i830ContextPtr imesa = I830_CONTEXT(ctx);
139
140 if (I830_DEBUG&DEBUG_DRI)
141 fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
142
143 mask = mask & 0xff;
144
145 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
146 imesa->Setup[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
147 imesa->Setup[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
148 STENCIL_WRITE_MASK(mask));
149 }
150
151 static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
152 GLenum zpass)
153 {
154 i830ContextPtr imesa = I830_CONTEXT(ctx);
155 int fop, dfop, dpop;
156
157 if (I830_DEBUG&DEBUG_DRI)
158 fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
159 _mesa_lookup_enum_by_nr(fail),
160 _mesa_lookup_enum_by_nr(zfail),
161 _mesa_lookup_enum_by_nr(zpass));
162
163 fop = 0; dfop = 0; dpop = 0;
164
165 switch(fail) {
166 case GL_KEEP:
167 fop = STENCILOP_KEEP;
168 break;
169 case GL_ZERO:
170 fop = STENCILOP_ZERO;
171 break;
172 case GL_REPLACE:
173 fop = STENCILOP_REPLACE;
174 break;
175 case GL_INCR:
176 fop = STENCILOP_INCRSAT;
177 break;
178 case GL_DECR:
179 fop = STENCILOP_DECRSAT;
180 break;
181 case GL_INCR_WRAP:
182 fop = STENCILOP_INCR;
183 break;
184 case GL_DECR_WRAP:
185 fop = STENCILOP_DECR;
186 break;
187 case GL_INVERT:
188 fop = STENCILOP_INVERT;
189 break;
190 default:
191 break;
192 }
193 switch(zfail) {
194 case GL_KEEP:
195 dfop = STENCILOP_KEEP;
196 break;
197 case GL_ZERO:
198 dfop = STENCILOP_ZERO;
199 break;
200 case GL_REPLACE:
201 dfop = STENCILOP_REPLACE;
202 break;
203 case GL_INCR:
204 dfop = STENCILOP_INCRSAT;
205 break;
206 case GL_DECR:
207 dfop = STENCILOP_DECRSAT;
208 break;
209 case GL_INCR_WRAP:
210 dfop = STENCILOP_INCR;
211 break;
212 case GL_DECR_WRAP:
213 dfop = STENCILOP_DECR;
214 break;
215 case GL_INVERT:
216 dfop = STENCILOP_INVERT;
217 break;
218 default:
219 break;
220 }
221 switch(zpass) {
222 case GL_KEEP:
223 dpop = STENCILOP_KEEP;
224 break;
225 case GL_ZERO:
226 dpop = STENCILOP_ZERO;
227 break;
228 case GL_REPLACE:
229 dpop = STENCILOP_REPLACE;
230 break;
231 case GL_INCR:
232 dpop = STENCILOP_INCRSAT;
233 break;
234 case GL_DECR:
235 dpop = STENCILOP_DECRSAT;
236 break;
237 case GL_INCR_WRAP:
238 dpop = STENCILOP_INCR;
239 break;
240 case GL_DECR_WRAP:
241 dpop = STENCILOP_DECR;
242 break;
243 case GL_INVERT:
244 dpop = STENCILOP_INVERT;
245 break;
246 default:
247 break;
248 }
249
250
251 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
252 imesa->Setup[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
253 imesa->Setup[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS |
254 STENCIL_FAIL_OP(fop) |
255 STENCIL_PASS_DEPTH_FAIL_OP(dfop) |
256 STENCIL_PASS_DEPTH_PASS_OP(dpop));
257 }
258
259 static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
260 {
261 i830ContextPtr imesa = I830_CONTEXT(ctx);
262 int test = 0;
263 GLuint refByte = (GLint) (ref * 255.0);
264
265 switch(func) {
266 case GL_NEVER:
267 test = COMPAREFUNC_NEVER;
268 break;
269 case GL_LESS:
270 test = COMPAREFUNC_LESS;
271 break;
272 case GL_LEQUAL:
273 test = COMPAREFUNC_LEQUAL;
274 break;
275 case GL_GREATER:
276 test = COMPAREFUNC_GREATER;
277 break;
278 case GL_GEQUAL:
279 test = COMPAREFUNC_GEQUAL;
280 break;
281 case GL_NOTEQUAL:
282 test = COMPAREFUNC_NOTEQUAL;
283 break;
284 case GL_EQUAL:
285 test = COMPAREFUNC_EQUAL;
286 break;
287 case GL_ALWAYS:
288 test = COMPAREFUNC_ALWAYS;
289 break;
290 default:
291 return;
292 }
293
294 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
295 imesa->Setup[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK;
296 imesa->Setup[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC |
297 ENABLE_ALPHA_REF_VALUE |
298 ALPHA_TEST_FUNC(test) |
299 ALPHA_REF_VALUE(refByte));
300 }
301
302 /* This function makes sure that the proper enables are
303 * set for LogicOp, Independant Alpha Blend, and Blending.
304 * It needs to be called from numerous places where we
305 * could change the LogicOp or Independant Alpha Blend without subsequent
306 * calls to glEnable.
307 */
308 static void i830EvalLogicOpBlendState(GLcontext *ctx)
309 {
310 i830ContextPtr imesa = I830_CONTEXT(ctx);
311
312 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
313
314 if (ctx->Color.ColorLogicOpEnabled) {
315 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
316 ENABLE_LOGIC_OP_MASK);
317 imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
318 ENABLE_LOGIC_OP);
319 imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
320 imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
321 } else if (ctx->Color.BlendEnabled) {
322 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
323 ENABLE_LOGIC_OP_MASK);
324 imesa->Setup[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND |
325 DISABLE_LOGIC_OP);
326 imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
327 if (imesa->Setup[I830_CTXREG_IALPHAB] & SRC_DST_ABLEND_MASK) {
328 imesa->Setup[I830_CTXREG_IALPHAB] |= ENABLE_INDPT_ALPHA_BLEND;
329 } else {
330 imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
331 }
332 } else {
333 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
334 ENABLE_LOGIC_OP_MASK);
335 imesa->Setup[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
336 DISABLE_LOGIC_OP);
337 imesa->Setup[I830_CTXREG_IALPHAB] &= ~ENABLE_INDPT_ALPHA_BLEND;
338 imesa->Setup[I830_CTXREG_IALPHAB] |= DISABLE_INDPT_ALPHA_BLEND;
339 }
340 }
341
342 static void i830BlendColor(GLcontext *ctx, const GLfloat color[4])
343 {
344 i830ContextPtr imesa = I830_CONTEXT(ctx);
345 GLubyte r, g, b, a;
346
347 if (I830_DEBUG&DEBUG_DRI)
348 fprintf(stderr, "%s\n", __FUNCTION__);
349
350 FLOAT_COLOR_TO_UBYTE_COLOR(r, color[RCOMP]);
351 FLOAT_COLOR_TO_UBYTE_COLOR(g, color[GCOMP]);
352 FLOAT_COLOR_TO_UBYTE_COLOR(b, color[BCOMP]);
353 FLOAT_COLOR_TO_UBYTE_COLOR(a, color[ACOMP]);
354
355 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
356 imesa->Setup[I830_CTXREG_BLENDCOLR] = ((a << 24) |
357 (r << 16) |
358 (g << 8) |
359 b);
360 }
361
362 static void i830BlendEquation(GLcontext *ctx, GLenum mode)
363 {
364 i830ContextPtr imesa = I830_CONTEXT(ctx);
365 int func = ENABLE_ALPHA_BLENDFUNC;
366
367 if (I830_DEBUG&DEBUG_DRI)
368 fprintf(stderr, "%s %s\n", __FUNCTION__,
369 _mesa_lookup_enum_by_nr(mode));
370
371 /* This will catch a logicop blend equation */
372 i830EvalLogicOpBlendState(ctx);
373
374 switch(mode) {
375 case GL_FUNC_ADD_EXT:
376 func |= BLENDFUNC_ADD;
377 break;
378 case GL_MIN_EXT:
379 func |= BLENDFUNC_MIN;
380 break;
381 case GL_MAX_EXT:
382 func |= BLENDFUNC_MAX;
383 break;
384 case GL_FUNC_SUBTRACT_EXT:
385 func |= BLENDFUNC_SUB;
386 break;
387 case GL_FUNC_REVERSE_SUBTRACT_EXT:
388 func |= BLENDFUNC_RVRSE_SUB;
389 break;
390 default: return;
391 }
392
393 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
394 imesa->Setup[I830_CTXREG_STATE1] &= ~BLENDFUNC_MASK;
395 imesa->Setup[I830_CTXREG_STATE1] |= func;
396 if (0) fprintf(stderr, "%s : STATE1 : 0x%08x\n",
397 __FUNCTION__,
398 imesa->Setup[I830_CTXREG_STATE1]);
399 }
400
401 static void i830BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
402 {
403 i830ContextPtr imesa = I830_CONTEXT(ctx);
404 int func = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
405
406 if (I830_DEBUG&DEBUG_DRI)
407 fprintf(stderr, "%s %s %s\n", __FUNCTION__,
408 _mesa_lookup_enum_by_nr(sfactor),
409 _mesa_lookup_enum_by_nr(dfactor));
410
411 switch(sfactor) {
412 case GL_ZERO:
413 func |= SRC_BLND_FACT(BLENDFACT_ZERO);
414 break;
415 case GL_SRC_ALPHA:
416 func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA);
417 break;
418 case GL_ONE:
419 func |= SRC_BLND_FACT(BLENDFACT_ONE);
420 break;
421 case GL_DST_COLOR:
422 func |= SRC_BLND_FACT(BLENDFACT_DST_COLR);
423 break;
424 case GL_ONE_MINUS_DST_COLOR:
425 func |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR);
426 break;
427 case GL_ONE_MINUS_SRC_ALPHA:
428 func |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
429 break;
430 case GL_DST_ALPHA:
431 func |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA);
432 break;
433 case GL_ONE_MINUS_DST_ALPHA:
434 func |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
435 break;
436 case GL_SRC_ALPHA_SATURATE:
437 func |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
438 break;
439 case GL_CONSTANT_COLOR_EXT:
440 func |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR);
441 break;
442 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
443 func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
444 break;
445 case GL_CONSTANT_ALPHA_EXT:
446 func |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA);
447 break;
448 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
449 func |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
450 break;
451 default:
452 return;
453 }
454
455 switch(dfactor) {
456 case GL_SRC_ALPHA:
457 func |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA);
458 break;
459 case GL_ONE_MINUS_SRC_ALPHA:
460 func |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
461 break;
462 case GL_ZERO:
463 func |= DST_BLND_FACT(BLENDFACT_ZERO);
464 break;
465 case GL_ONE:
466 func |= DST_BLND_FACT(BLENDFACT_ONE);
467 break;
468 case GL_SRC_COLOR:
469 func |= DST_BLND_FACT(BLENDFACT_SRC_COLR);
470 break;
471 case GL_ONE_MINUS_SRC_COLOR:
472 func |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR);
473 break;
474 case GL_DST_ALPHA:
475 func |= DST_BLND_FACT(BLENDFACT_DST_ALPHA);
476 break;
477 case GL_ONE_MINUS_DST_ALPHA:
478 func |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
479 break;
480 case GL_CONSTANT_COLOR_EXT:
481 func |= DST_BLND_FACT(BLENDFACT_CONST_COLOR);
482 break;
483 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
484 func |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
485 break;
486 case GL_CONSTANT_ALPHA_EXT:
487 func |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA);
488 break;
489 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
490 func |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
491 break;
492 default:
493 return;
494 }
495
496 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
497 imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK;
498 imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK;
499 imesa->Setup[I830_CTXREG_STATE1] |= func;
500 /* Insure Independant Alpha Blend is really disabled. */
501 i830EvalLogicOpBlendState(ctx);
502 }
503
504 static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
505 GLenum dfactorRGB, GLenum sfactorA,
506 GLenum dfactorA )
507 {
508 i830ContextPtr imesa = I830_CONTEXT(ctx);
509 int funcA = (ENABLE_SRC_ABLEND_FACTOR|ENABLE_DST_ABLEND_FACTOR);
510 int funcRGB = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
511
512 if (I830_DEBUG&DEBUG_DRI)
513 fprintf(stderr, "%s\n", __FUNCTION__);
514
515 switch(sfactorA) {
516 case GL_ZERO:
517 funcA |= SRC_ABLEND_FACT(BLENDFACT_ZERO);
518 break;
519 case GL_SRC_ALPHA:
520 funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA);
521 break;
522 case GL_ONE:
523 funcA |= SRC_ABLEND_FACT(BLENDFACT_ONE);
524 break;
525 case GL_DST_COLOR:
526 funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_COLR);
527 break;
528 case GL_ONE_MINUS_DST_COLOR:
529 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_COLR);
530 break;
531 case GL_ONE_MINUS_SRC_ALPHA:
532 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA);
533 break;
534 case GL_DST_ALPHA:
535 funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_ALPHA);
536 break;
537 case GL_ONE_MINUS_DST_ALPHA:
538 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA);
539 break;
540 case GL_SRC_ALPHA_SATURATE:
541 funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
542 break;
543 case GL_CONSTANT_COLOR_EXT:
544 funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_COLOR);
545 break;
546 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
547 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR);
548 break;
549 case GL_CONSTANT_ALPHA_EXT:
550 funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_ALPHA);
551 break;
552 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
553 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA);
554 break;
555 default: return;
556 }
557
558 switch(dfactorA) {
559 case GL_SRC_ALPHA:
560 funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_ALPHA);
561 break;
562 case GL_ONE_MINUS_SRC_ALPHA:
563 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA);
564 break;
565 case GL_ZERO:
566 funcA |= DST_ABLEND_FACT(BLENDFACT_ZERO);
567 break;
568 case GL_ONE:
569 funcA |= DST_ABLEND_FACT(BLENDFACT_ONE);
570 break;
571 case GL_SRC_COLOR:
572 funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_COLR);
573 break;
574 case GL_ONE_MINUS_SRC_COLOR:
575 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_COLR);
576 break;
577 case GL_DST_ALPHA:
578 funcA |= DST_ABLEND_FACT(BLENDFACT_DST_ALPHA);
579 break;
580 case GL_ONE_MINUS_DST_ALPHA:
581 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA);
582 break;
583 case GL_CONSTANT_COLOR_EXT:
584 funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_COLOR);
585 break;
586 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
587 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR);
588 break;
589 case GL_CONSTANT_ALPHA_EXT:
590 funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_ALPHA);
591 break;
592 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
593 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA);
594 break;
595 default: return;
596 }
597
598 switch(sfactorRGB) {
599 case GL_ZERO:
600 funcRGB |= SRC_BLND_FACT(BLENDFACT_ZERO);
601 break;
602 case GL_SRC_ALPHA:
603 funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA);
604 break;
605 case GL_ONE:
606 funcRGB |= SRC_BLND_FACT(BLENDFACT_ONE);
607 break;
608 case GL_DST_COLOR:
609 funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_COLR);
610 break;
611 case GL_ONE_MINUS_DST_COLOR:
612 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR);
613 break;
614 case GL_ONE_MINUS_SRC_ALPHA:
615 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
616 break;
617 case GL_DST_ALPHA:
618 funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA);
619 break;
620 case GL_ONE_MINUS_DST_ALPHA:
621 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
622 break;
623 case GL_SRC_ALPHA_SATURATE:
624 funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
625 break;
626 case GL_CONSTANT_COLOR_EXT:
627 funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR);
628 break;
629 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
630 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
631 break;
632 case GL_CONSTANT_ALPHA_EXT:
633 funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA);
634 break;
635 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
636 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
637 break;
638 default: return;
639 }
640
641 switch(dfactorRGB) {
642 case GL_SRC_ALPHA:
643 funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA);
644 break;
645 case GL_ONE_MINUS_SRC_ALPHA:
646 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
647 break;
648 case GL_ZERO:
649 funcRGB |= DST_BLND_FACT(BLENDFACT_ZERO);
650 break;
651 case GL_ONE:
652 funcRGB |= DST_BLND_FACT(BLENDFACT_ONE);
653 break;
654 case GL_SRC_COLOR:
655 funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_COLR);
656 break;
657 case GL_ONE_MINUS_SRC_COLOR:
658 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR);
659 break;
660 case GL_DST_ALPHA:
661 funcRGB |= DST_BLND_FACT(BLENDFACT_DST_ALPHA);
662 break;
663 case GL_ONE_MINUS_DST_ALPHA:
664 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
665 break;
666 case GL_CONSTANT_COLOR_EXT:
667 funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_COLOR);
668 break;
669 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
670 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
671 break;
672 case GL_CONSTANT_ALPHA_EXT:
673 funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA);
674 break;
675 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
676 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
677 break;
678 default: return;
679 }
680
681 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
682 imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK;
683 imesa->Setup[I830_CTXREG_IALPHAB] |= funcA;
684 imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK;
685 imesa->Setup[I830_CTXREG_STATE1] |= funcRGB;
686
687 /* Insure Independant Alpha Blend is really enabled if
688 * Blending is already enabled.
689 */
690 i830EvalLogicOpBlendState(ctx);
691 }
692
693 static void i830DepthFunc(GLcontext *ctx, GLenum func)
694 {
695 i830ContextPtr imesa = I830_CONTEXT(ctx);
696 int test = 0;
697
698 if (I830_DEBUG&DEBUG_DRI)
699 fprintf(stderr, "%s\n", __FUNCTION__);
700
701 switch(func) {
702 case GL_NEVER:
703 test = COMPAREFUNC_NEVER;
704 break;
705 case GL_LESS:
706 test = COMPAREFUNC_LESS;
707 break;
708 case GL_LEQUAL:
709 test = COMPAREFUNC_LEQUAL;
710 break;
711 case GL_GREATER:
712 test = COMPAREFUNC_GREATER;
713 break;
714 case GL_GEQUAL:
715 test = COMPAREFUNC_GEQUAL;
716 break;
717 case GL_NOTEQUAL:
718 test = COMPAREFUNC_NOTEQUAL;
719 break;
720 case GL_EQUAL:
721 test = COMPAREFUNC_EQUAL;
722 break;
723 case GL_ALWAYS:
724 test = COMPAREFUNC_ALWAYS;
725 break;
726 default: return;
727 }
728
729 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
730 imesa->Setup[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
731 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
732 DEPTH_TEST_FUNC(test));
733 }
734
735 static void i830DepthMask(GLcontext *ctx, GLboolean flag)
736 {
737 i830ContextPtr imesa = I830_CONTEXT(ctx);
738
739 if (I830_DEBUG&DEBUG_DRI)
740 fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
741
742 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
743
744 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
745
746 if (flag && ctx->Depth.Test)
747 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
748 else
749 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
750 }
751
752 /* =============================================================
753 * Polygon stipple
754 *
755 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
756 * Fortunately stipple is usually a repeating pattern.
757 */
758 static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask )
759 {
760 i830ContextPtr imesa = I830_CONTEXT(ctx);
761 const GLubyte *m = mask;
762 GLubyte p[4];
763 int i,j,k;
764 int active = (ctx->Polygon.StippleFlag &&
765 imesa->reduced_primitive == GL_TRIANGLES);
766 GLuint newMask;
767
768 if (active) {
769 I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
770 imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE;
771 }
772
773 p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
774 p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
775 p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
776 p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
777
778 for (k = 0 ; k < 8 ; k++)
779 for (j = 3 ; j >= 0; j--)
780 for (i = 0 ; i < 4 ; i++, m++)
781 if (*m != p[j]) {
782 imesa->hw_stipple = 0;
783 return;
784 }
785
786 newMask = (((p[0] & 0xf) << 0) |
787 ((p[1] & 0xf) << 4) |
788 ((p[2] & 0xf) << 8) |
789 ((p[3] & 0xf) << 12));
790
791
792 if (newMask == 0xffff || newMask == 0x0) {
793 /* this is needed to make conform pass */
794 imesa->hw_stipple = 0;
795 return;
796 }
797
798 imesa->StippleSetup[I830_STPREG_ST1] &= ~0xffff;
799 imesa->StippleSetup[I830_STPREG_ST1] |= newMask;
800 imesa->hw_stipple = 1;
801
802 if (active)
803 imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
804 }
805
806 static void i830PolygonStippleFallback( GLcontext *ctx, const GLubyte *mask )
807 {
808 i830ContextPtr imesa = I830_CONTEXT(ctx);
809 imesa->hw_stipple = 0;
810 (void) i830PolygonStipple;
811 }
812
813 /* =============================================================
814 * Hardware clipping
815 */
816 static void i830Scissor(GLcontext *ctx, GLint x, GLint y,
817 GLsizei w, GLsizei h)
818 {
819 i830ContextPtr imesa = I830_CONTEXT(ctx);
820 int x1 = x;
821 int y1 = imesa->driDrawable->h - (y + h);
822 int x2 = x + w - 1;
823 int y2 = y1 + h - 1;
824
825 if (I830_DEBUG&DEBUG_DRI)
826 fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__,
827 x, y, w, h);
828
829 if (x1 < 0) x1 = 0;
830 if (y1 < 0) y1 = 0;
831 if (x2 < 0) x2 = 0;
832 if (y2 < 0) y2 = 0;
833
834 if (x2 >= imesa->i830Screen->width) x2 = imesa->i830Screen->width-1;
835 if (y2 >= imesa->i830Screen->height) y2 = imesa->i830Screen->height-1;
836 if (x1 >= imesa->i830Screen->width) x1 = imesa->i830Screen->width-1;
837 if (y1 >= imesa->i830Screen->height) y1 = imesa->i830Screen->height-1;
838
839
840 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
841 imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
842 imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
843 }
844
845 static void i830LogicOp(GLcontext *ctx, GLenum opcode)
846 {
847 i830ContextPtr imesa = I830_CONTEXT(ctx);
848 int tmp = 0;
849
850 if (I830_DEBUG&DEBUG_DRI)
851 fprintf(stderr, "%s\n", __FUNCTION__);
852
853 /* FIXME: This should be a look-up table, like the r200 driver. */
854 switch(opcode) {
855 case GL_CLEAR:
856 tmp = LOGICOP_CLEAR;
857 break;
858 case GL_AND:
859 tmp = LOGICOP_AND;
860 break;
861 case GL_AND_REVERSE:
862 tmp = LOGICOP_AND_RVRSE;
863 break;
864 case GL_COPY:
865 tmp = LOGICOP_COPY;
866 break;
867 case GL_COPY_INVERTED:
868 tmp = LOGICOP_COPY_INV;
869 break;
870 case GL_AND_INVERTED:
871 tmp = LOGICOP_AND_INV;
872 break;
873 case GL_NOOP:
874 tmp = LOGICOP_NOOP;
875 break;
876 case GL_XOR:
877 tmp = LOGICOP_XOR;
878 break;
879 case GL_OR:
880 tmp = LOGICOP_OR;
881 break;
882 case GL_OR_INVERTED:
883 tmp = LOGICOP_OR_INV;
884 break;
885 case GL_NOR:
886 tmp = LOGICOP_NOR;
887 break;
888 case GL_EQUIV:
889 tmp = LOGICOP_EQUIV;
890 break;
891 case GL_INVERT:
892 tmp = LOGICOP_INV;
893 break;
894 case GL_OR_REVERSE:
895 tmp = LOGICOP_OR_RVRSE;
896 break;
897 case GL_NAND:
898 tmp = LOGICOP_NAND;
899 break;
900 case GL_SET:
901 tmp = LOGICOP_SET;
902 break;
903 default:
904 return;
905 }
906
907 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
908 imesa->Setup[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
909 imesa->Setup[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
910
911 /* Make sure all the enables are correct */
912 i830EvalLogicOpBlendState(ctx);
913 }
914
915 /* Fallback to swrast for select and feedback.
916 */
917 static void i830RenderMode( GLcontext *ctx, GLenum mode )
918 {
919 i830ContextPtr imesa = I830_CONTEXT(ctx);
920 FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
921 }
922
923 static void i830DrawBuffer(GLcontext *ctx, GLenum mode )
924 {
925 i830ContextPtr imesa = I830_CONTEXT(ctx);
926
927 /*
928 * _DrawDestMask is easier to cope with than <mode>.
929 */
930 switch ( ctx->Color._DrawDestMask ) {
931 case FRONT_LEFT_BIT:
932 I830_FIREVERTICES(imesa);
933 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
934 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset;
935 i830XMesaSetFrontClipRects( imesa );
936 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
937 break;
938 case BACK_LEFT_BIT:
939 I830_FIREVERTICES(imesa);
940 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
941 imesa->BufferSetup[I830_DESTREG_CBUFADDR] =
942 imesa->i830Screen->backOffset;
943 i830XMesaSetBackClipRects( imesa );
944 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
945 break;
946 default:
947 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
948 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE );
949 return;
950 }
951
952 /* We want to update the s/w rast state too so that i830SetBuffer()
953 * gets called.
954 */
955 _swrast_DrawBuffer(ctx, mode);
956 }
957
958 static void i830ReadBuffer(GLcontext *ctx, GLenum mode )
959 {
960 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
961 }
962
963 static void i830ClearColor(GLcontext *ctx, const GLfloat color[4])
964 {
965 i830ContextPtr imesa = I830_CONTEXT(ctx);
966
967 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_red, color[0]);
968 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_green, color[1]);
969 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_blue, color[2]);
970 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_alpha, color[3]);
971
972 imesa->ClearColor = i830PackColor(imesa->i830Screen->fbFormat,
973 imesa->clear_red,
974 imesa->clear_green,
975 imesa->clear_blue,
976 imesa->clear_alpha);
977 }
978
979 static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused)
980 {
981 i830ContextPtr imesa = I830_CONTEXT(ctx);
982 GLuint mode = CULLMODE_BOTH;
983
984 if (I830_DEBUG&DEBUG_DRI)
985 fprintf(stderr, "%s\n", __FUNCTION__);
986
987 if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
988 mode = CULLMODE_CW;
989
990 if (ctx->Polygon.CullFaceMode == GL_FRONT)
991 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
992 if (ctx->Polygon.FrontFace != GL_CCW)
993 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
994 }
995
996 imesa->LcsCullMode = mode;
997
998 if (ctx->Polygon.CullFlag) {
999 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1000 imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
1001 imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode;
1002 }
1003 }
1004
1005 static void i830LineWidth( GLcontext *ctx, GLfloat widthf )
1006 {
1007 i830ContextPtr imesa = I830_CONTEXT( ctx );
1008 int width;
1009
1010 if (I830_DEBUG&DEBUG_DRI)
1011 fprintf(stderr, "%s\n", __FUNCTION__);
1012
1013 width = FloatToInt(widthf * 2);
1014 CLAMP_SELF(width, 1, 15);
1015
1016 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1017 imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_LINE_WIDTH_MASK;
1018 imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_LINE_WIDTH |
1019 FIXED_LINE_WIDTH(width));
1020 }
1021
1022 static void i830PointSize(GLcontext *ctx, GLfloat size)
1023 {
1024 i830ContextPtr imesa = I830_CONTEXT(ctx);
1025 GLint point_size = FloatToInt(size);
1026
1027 if (I830_DEBUG&DEBUG_DRI)
1028 fprintf(stderr, "%s\n", __FUNCTION__);
1029
1030 CLAMP_SELF(point_size, 1, 256);
1031 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1032 imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
1033 imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
1034 FIXED_POINT_WIDTH(point_size));
1035 }
1036
1037
1038 /* =============================================================
1039 * Color masks
1040 */
1041
1042 static void i830ColorMask(GLcontext *ctx,
1043 GLboolean r, GLboolean g,
1044 GLboolean b, GLboolean a)
1045 {
1046 i830ContextPtr imesa = I830_CONTEXT( ctx );
1047 GLuint tmp = 0;
1048
1049 if (I830_DEBUG&DEBUG_DRI)
1050 fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
1051
1052 imesa->mask_red = !r;
1053 imesa->mask_green = !g;
1054 imesa->mask_blue = !b;
1055 imesa->mask_alpha = !a;
1056
1057 tmp = (imesa->Setup[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) |
1058 ENABLE_COLOR_MASK |
1059 ENABLE_COLOR_WRITE |
1060 ((!r) << WRITEMASK_RED_SHIFT) |
1061 ((!g) << WRITEMASK_GREEN_SHIFT) |
1062 ((!b) << WRITEMASK_BLUE_SHIFT) |
1063 ((!a) << WRITEMASK_ALPHA_SHIFT);
1064
1065 if (tmp != imesa->Setup[I830_CTXREG_ENABLES_2]) {
1066 I830_FIREVERTICES(imesa);
1067 imesa->dirty |= I830_UPLOAD_CTX;
1068 imesa->Setup[I830_CTXREG_ENABLES_2] = tmp;
1069 }
1070 }
1071
1072 static void update_specular( GLcontext *ctx )
1073 {
1074 i830ContextPtr imesa = I830_CONTEXT( ctx );
1075
1076 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1077 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK;
1078
1079 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
1080 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD;
1081 else
1082 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD;
1083 }
1084
1085 static void i830LightModelfv(GLcontext *ctx, GLenum pname,
1086 const GLfloat *param)
1087 {
1088 if (I830_DEBUG&DEBUG_DRI)
1089 fprintf(stderr, "%s\n", __FUNCTION__);
1090
1091 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
1092 update_specular( ctx );
1093 }
1094 }
1095
1096 /* In Mesa 3.5 we can reliably do native flatshading.
1097 */
1098 static void i830ShadeModel(GLcontext *ctx, GLenum mode)
1099 {
1100 i830ContextPtr imesa = I830_CONTEXT(ctx);
1101 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1102
1103
1104 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
1105
1106 imesa->Setup[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK;
1107
1108 if (mode == GL_FLAT) {
1109 imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) |
1110 FOG_SHADE_MODE(SHADE_MODE_FLAT) |
1111 SPEC_SHADE_MODE(SHADE_MODE_FLAT) |
1112 COLOR_SHADE_MODE(SHADE_MODE_FLAT));
1113 } else {
1114 imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1115 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1116 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1117 COLOR_SHADE_MODE(SHADE_MODE_LINEAR));
1118 }
1119 }
1120
1121 /* =============================================================
1122 * Fog
1123 */
1124 static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
1125 {
1126 i830ContextPtr imesa = I830_CONTEXT(ctx);
1127
1128 if (I830_DEBUG&DEBUG_DRI)
1129 fprintf(stderr, "%s\n", __FUNCTION__);
1130
1131 if (pname == GL_FOG_COLOR) {
1132 GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
1133 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
1134 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
1135
1136 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1137 imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | color);
1138 }
1139 }
1140
1141 /* =============================================================
1142 */
1143
1144 static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state)
1145 {
1146 i830ContextPtr imesa = I830_CONTEXT(ctx);
1147
1148 switch(cap) {
1149 case GL_LIGHTING:
1150 case GL_COLOR_SUM_EXT:
1151 update_specular( ctx );
1152 break;
1153
1154 case GL_ALPHA_TEST:
1155 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1156 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK;
1157 if (state)
1158 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST;
1159 else
1160 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST;
1161
1162 break;
1163
1164 case GL_BLEND:
1165 case GL_COLOR_LOGIC_OP:
1166 case GL_INDEX_LOGIC_OP:
1167 i830EvalLogicOpBlendState(ctx);
1168 break;
1169
1170 case GL_DITHER:
1171 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1172 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER;
1173
1174 if (state)
1175 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER;
1176 else
1177 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER;
1178 break;
1179
1180 case GL_DEPTH_TEST:
1181 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1182 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
1183
1184 if (state)
1185 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
1186 else
1187 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
1188
1189 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1190 */
1191 i830DepthMask( ctx, state );
1192 break;
1193
1194 case GL_SCISSOR_TEST:
1195 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
1196
1197 if (state)
1198 imesa->BufferSetup[I830_DESTREG_SENABLE] =
1199 (STATE3D_SCISSOR_ENABLE_CMD |
1200 ENABLE_SCISSOR_RECT);
1201 else
1202 imesa->BufferSetup[I830_DESTREG_SENABLE] =
1203 (STATE3D_SCISSOR_ENABLE_CMD |
1204 DISABLE_SCISSOR_RECT);
1205
1206 imesa->upload_cliprects = GL_TRUE;
1207 break;
1208
1209 case GL_LINE_SMOOTH:
1210 if (imesa->reduced_primitive == GL_LINES) {
1211 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1212
1213 imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE;
1214 if (state)
1215 imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE;
1216 else
1217 imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE;
1218 }
1219 break;
1220
1221 case GL_FOG:
1222 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1223 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK;
1224 if (state)
1225 imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG;
1226 else
1227 imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG;
1228 break;
1229
1230 case GL_CULL_FACE:
1231 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1232 imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
1233 if (state)
1234 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
1235 imesa->LcsCullMode);
1236 else
1237 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
1238 CULLMODE_NONE);
1239 break;
1240
1241 case GL_TEXTURE_2D:
1242 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1243 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1244 break;
1245
1246 case GL_STENCIL_TEST:
1247 if (imesa->hw_stencil) {
1248 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1249 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
1250 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE;
1251
1252 if (state) {
1253 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
1254 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
1255 } else {
1256 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
1257 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE;
1258 }
1259 } else {
1260 FALLBACK( imesa, I830_FALLBACK_STENCIL, state );
1261 }
1262 break;
1263
1264 case GL_POLYGON_STIPPLE:
1265 #if 0
1266 /* The stipple command worked on my 855GM box, but not my 845G.
1267 * I'll do more testing later to find out exactly which hardware
1268 * supports it. Disabled for now.
1269 */
1270 if (imesa->hw_stipple && imesa->reduced_primitive == GL_TRIANGLES)
1271 {
1272 I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
1273 imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE;
1274 if (state)
1275 imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
1276 }
1277 #endif
1278 break;
1279
1280 default:
1281 ;
1282 }
1283 }
1284
1285
1286 void i830EmitDrawingRectangle( i830ContextPtr imesa )
1287 {
1288 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
1289 i830ScreenPrivate *i830Screen = imesa->i830Screen;
1290 int x0 = imesa->drawX;
1291 int y0 = imesa->drawY;
1292 int x1 = x0 + dPriv->w;
1293 int y1 = y0 + dPriv->h;
1294
1295 /* Don't set drawing rectangle */
1296 if (I830_DEBUG & DEBUG_IOCTL)
1297 fprintf(stderr, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__,
1298 x0, x1, y0, y1);
1299
1300 /* Coordinate origin of the window - may be offscreen.
1301 */
1302 imesa->BufferSetup[I830_DESTREG_DR4] = ((y0<<16) |
1303 (((unsigned)x0)&0xFFFF));
1304
1305 /* Clip to screen.
1306 */
1307 if (x0 < 0) x0 = 0;
1308 if (y0 < 0) y0 = 0;
1309 if (x1 > i830Screen->width-1) x1 = i830Screen->width-1;
1310 if (y1 > i830Screen->height-1) y1 = i830Screen->height-1;
1311
1312
1313 /* Onscreen drawing rectangle.
1314 */
1315 imesa->BufferSetup[I830_DESTREG_DR2] = ((y0<<16) | x0);
1316 imesa->BufferSetup[I830_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
1317
1318
1319 /* Just add in our dirty flag, since we might be called when locked */
1320 /* Might want to modify how this is done. */
1321 imesa->dirty |= I830_UPLOAD_BUFFERS;
1322
1323 if (0)
1324 fprintf(stderr, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1325 __FUNCTION__,
1326 imesa->BufferSetup[I830_DESTREG_DR2],
1327 imesa->BufferSetup[I830_DESTREG_DR3],
1328 imesa->BufferSetup[I830_DESTREG_DR4]);
1329 }
1330
1331 /* This could be done in hardware, will do once I have the driver
1332 * up and running.
1333 */
1334 static void i830CalcViewport( GLcontext *ctx )
1335 {
1336 i830ContextPtr imesa = I830_CONTEXT(ctx);
1337 const GLfloat *v = ctx->Viewport._WindowMap.m;
1338 GLfloat *m = imesa->ViewportMatrix.m;
1339
1340 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1341 * via state vars, too.
1342 */
1343 m[MAT_SX] = v[MAT_SX];
1344 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
1345 m[MAT_SY] = - v[MAT_SY];
1346 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y;
1347 m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale;
1348 m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale;
1349 }
1350
1351 static void i830Viewport( GLcontext *ctx,
1352 GLint x, GLint y,
1353 GLsizei width, GLsizei height )
1354 {
1355 i830CalcViewport( ctx );
1356 }
1357
1358 static void i830DepthRange( GLcontext *ctx,
1359 GLclampd nearval, GLclampd farval )
1360 {
1361 i830CalcViewport( ctx );
1362 }
1363
1364 void i830PrintDirty( const char *msg, GLuint state )
1365 {
1366 fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
1367 msg,
1368 (unsigned int) state,
1369 (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "",
1370 (state & I830_UPLOAD_TEX1) ? "upload-tex1, " : "",
1371 (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "",
1372 (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
1373 (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "",
1374 (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "",
1375 (state & I830_UPLOAD_STIPPLE) ? "stipple, " : ""
1376 );
1377 }
1378
1379 /* Push the state into the sarea and/or texture memory.
1380 */
1381 void i830EmitHwStateLocked( i830ContextPtr imesa )
1382 {
1383 int i;
1384
1385 if (I830_DEBUG & DEBUG_STATE)
1386 i830PrintDirty( __FUNCTION__, imesa->dirty );
1387
1388 if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0])
1389 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]);
1390 if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1])
1391 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]);
1392 if (imesa->dirty & I830_UPLOAD_CTX) {
1393 memcpy( imesa->sarea->ContextState,
1394 imesa->Setup, sizeof(imesa->Setup) );
1395 }
1396
1397 for (i = 0; i < I830_TEXTURE_COUNT; i++) {
1398 if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) {
1399 imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i);
1400 memcpy(imesa->sarea->TexState[i],
1401 imesa->CurrentTexObj[i]->Setup,
1402 sizeof(imesa->sarea->TexState[i]));
1403
1404 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
1405 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] |= imesa->LodBias[i];
1406
1407 /* Update the LRU usage */
1408 if (imesa->CurrentTexObj[i]->base.memBlock)
1409 driUpdateTextureLRU( (driTextureObject *)
1410 imesa->CurrentTexObj[i] );
1411 }
1412 }
1413 /* Need to figure out if texturing state, or enable changed. */
1414
1415 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1416 if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) {
1417 imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i);
1418 memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i],
1419 imesa->TexBlendWordsUsed[i] * 4);
1420 imesa->sarea->TexBlendStateWordsUsed[i] =
1421 imesa->TexBlendWordsUsed[i];
1422 }
1423 }
1424
1425 if (imesa->dirty & I830_UPLOAD_BUFFERS) {
1426 memcpy( imesa->sarea->BufferState,imesa->BufferSetup,
1427 sizeof(imesa->BufferSetup) );
1428 }
1429
1430 if (imesa->dirty & I830_UPLOAD_STIPPLE) {
1431 memcpy( imesa->sarea->StippleState,imesa->StippleSetup,
1432 sizeof(imesa->StippleSetup) );
1433 }
1434
1435 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
1436 memcpy( imesa->sarea->Palette[0],imesa->palette,
1437 sizeof(imesa->sarea->Palette[0]));
1438 } else {
1439 i830TextureObjectPtr p;
1440 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
1441 p = imesa->CurrentTexObj[0];
1442 memcpy( imesa->sarea->Palette[0],p->palette,
1443 sizeof(imesa->sarea->Palette[0]));
1444 }
1445 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
1446 p = imesa->CurrentTexObj[1];
1447 memcpy( imesa->sarea->Palette[1],
1448 p->palette,
1449 sizeof(imesa->sarea->Palette[1]));
1450 }
1451 }
1452
1453 imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK |
1454 I830_UPLOAD_TEXBLEND_MASK));
1455
1456 imesa->upload_cliprects = GL_TRUE;
1457 imesa->dirty = 0;
1458 }
1459
1460
1461 void i830DDInitState( GLcontext *ctx )
1462 {
1463 i830ContextPtr imesa = I830_CONTEXT(ctx);
1464 i830ScreenPrivate *i830Screen = imesa->i830Screen;
1465 int i, j;
1466
1467 imesa->clear_red = 0;
1468 imesa->clear_green = 0;
1469 imesa->clear_blue = 0;
1470 imesa->clear_alpha = 0;
1471
1472 imesa->mask_red = GL_FALSE;
1473 imesa->mask_green = GL_FALSE;
1474 imesa->mask_blue = GL_FALSE;
1475 imesa->mask_alpha = GL_FALSE;
1476
1477 /* Zero all texture state */
1478 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1479 for (j = 0; j < I830_TEXBLEND_SIZE; j++) {
1480 imesa->TexBlend[i][j] = 0;
1481 imesa->Init_TexBlend[i][j] = 0;
1482 }
1483 imesa->TexBlendWordsUsed[i] = 0;
1484 imesa->Init_TexBlendWordsUsed[i] = 0;
1485 imesa->TexBlendColorPipeNum[i] = 0;
1486 imesa->Init_TexBlendColorPipeNum[i] = 0;
1487 }
1488
1489 /* Set default blend state */
1490 imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1491 TEXPIPE_COLOR |
1492 ENABLE_TEXOUTPUT_WRT_SEL |
1493 TEXOP_OUTPUT_CURRENT |
1494 DISABLE_TEX_CNTRL_STAGE |
1495 TEXOP_SCALE_1X |
1496 TEXOP_MODIFY_PARMS |
1497 TEXOP_LAST_STAGE |
1498 TEXBLENDOP_ARG1);
1499 imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1500 TEXPIPE_ALPHA |
1501 ENABLE_TEXOUTPUT_WRT_SEL |
1502 TEXOP_OUTPUT_CURRENT |
1503 TEXOP_SCALE_1X |
1504 TEXOP_MODIFY_PARMS |
1505 TEXBLENDOP_ARG1);
1506 imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1507 TEXPIPE_COLOR |
1508 TEXBLEND_ARG1 |
1509 TEXBLENDARG_MODIFY_PARMS |
1510 TEXBLENDARG_DIFFUSE);
1511 imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1512 TEXPIPE_ALPHA |
1513 TEXBLEND_ARG1 |
1514 TEXBLENDARG_MODIFY_PARMS |
1515 TEXBLENDARG_DIFFUSE);
1516
1517 imesa->TexBlendWordsUsed[0] = 4;
1518 imesa->TexBlendColorPipeNum[0] = 0;
1519
1520 imesa->Init_TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1521 TEXPIPE_COLOR |
1522 ENABLE_TEXOUTPUT_WRT_SEL |
1523 TEXOP_OUTPUT_CURRENT |
1524 DISABLE_TEX_CNTRL_STAGE |
1525 TEXOP_SCALE_1X |
1526 TEXOP_MODIFY_PARMS |
1527 TEXOP_LAST_STAGE |
1528 TEXBLENDOP_ARG1);
1529 imesa->Init_TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1530 TEXPIPE_ALPHA |
1531 ENABLE_TEXOUTPUT_WRT_SEL |
1532 TEXOP_OUTPUT_CURRENT |
1533 TEXOP_SCALE_1X |
1534 TEXOP_MODIFY_PARMS |
1535 TEXBLENDOP_ARG1);
1536 imesa->Init_TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1537 TEXPIPE_COLOR |
1538 TEXBLEND_ARG1 |
1539 TEXBLENDARG_MODIFY_PARMS |
1540 TEXBLENDARG_CURRENT);
1541 imesa->Init_TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1542 TEXPIPE_ALPHA |
1543 TEXBLEND_ARG1 |
1544 TEXBLENDARG_MODIFY_PARMS |
1545 TEXBLENDARG_CURRENT);
1546 imesa->Init_TexBlendWordsUsed[0] = 4;
1547 imesa->Init_TexBlendColorPipeNum[0] = 0;
1548
1549 memset(imesa->Setup, 0, sizeof(imesa->Setup));
1550
1551 imesa->Setup[I830_CTXREG_VF] = 0;
1552 imesa->Setup[I830_CTXREG_VF2] = 0;
1553
1554 imesa->Setup[I830_CTXREG_AA] = (STATE3D_AA_CMD |
1555 AA_LINE_ECAAR_WIDTH_ENABLE |
1556 AA_LINE_ECAAR_WIDTH_1_0 |
1557 AA_LINE_REGION_WIDTH_ENABLE |
1558 AA_LINE_REGION_WIDTH_1_0 |
1559 AA_LINE_DISABLE);
1560
1561 imesa->Setup[I830_CTXREG_ENABLES_1] = (STATE3D_ENABLES_1_CMD |
1562 DISABLE_LOGIC_OP |
1563 DISABLE_STENCIL_TEST |
1564 DISABLE_DEPTH_BIAS |
1565 DISABLE_SPEC_ADD |
1566 I830_DISABLE_FOG |
1567 DISABLE_ALPHA_TEST |
1568 DISABLE_COLOR_BLEND |
1569 DISABLE_DEPTH_TEST);
1570
1571 if (imesa->hw_stencil) {
1572 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1573 ENABLE_STENCIL_WRITE |
1574 ENABLE_TEX_CACHE |
1575 ENABLE_DITHER |
1576 ENABLE_COLOR_MASK |
1577 /* set no color comps disabled */
1578 ENABLE_COLOR_WRITE |
1579 ENABLE_DEPTH_WRITE);
1580 } else {
1581 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1582 DISABLE_STENCIL_WRITE |
1583 ENABLE_TEX_CACHE |
1584 ENABLE_DITHER |
1585 ENABLE_COLOR_MASK |
1586 /* set no color comps disabled */
1587 ENABLE_COLOR_WRITE |
1588 ENABLE_DEPTH_WRITE);
1589 }
1590
1591 imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD |
1592 ENABLE_COLR_BLND_FUNC |
1593 BLENDFUNC_ADD |
1594 ENABLE_SRC_BLND_FACTOR |
1595 SRC_BLND_FACT(BLENDFACT_ONE) |
1596 ENABLE_DST_BLND_FACTOR |
1597 DST_BLND_FACT(BLENDFACT_ZERO) );
1598
1599 imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD |
1600 ENABLE_GLOBAL_DEPTH_BIAS |
1601 GLOBAL_DEPTH_BIAS(0) |
1602 ENABLE_ALPHA_TEST_FUNC |
1603 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1604 ALPHA_REF_VALUE(0) );
1605
1606 imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD |
1607 ENABLE_DEPTH_TEST_FUNC |
1608 DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
1609 ENABLE_ALPHA_SHADE_MODE |
1610 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1611 ENABLE_FOG_SHADE_MODE |
1612 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1613 ENABLE_SPEC_SHADE_MODE |
1614 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1615 ENABLE_COLOR_SHADE_MODE |
1616 COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
1617 ENABLE_CULL_MODE |
1618 CULLMODE_NONE);
1619
1620 imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD |
1621 ENABLE_LOGIC_OP_FUNC |
1622 LOGIC_OP_FUNC(LOGICOP_COPY) |
1623 ENABLE_STENCIL_TEST_MASK |
1624 STENCIL_TEST_MASK(0xff) |
1625 ENABLE_STENCIL_WRITE_MASK |
1626 STENCIL_WRITE_MASK(0xff));
1627
1628 imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD |
1629 ENABLE_STENCIL_PARMS |
1630 STENCIL_FAIL_OP(STENCILOP_KEEP) |
1631 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
1632 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
1633 ENABLE_STENCIL_TEST_FUNC |
1634 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1635 ENABLE_STENCIL_REF_VALUE |
1636 STENCIL_REF_VALUE(0) );
1637
1638 imesa->Setup[I830_CTXREG_STATE5] = (STATE3D_MODES_5_CMD |
1639 FLUSH_TEXTURE_CACHE |
1640 ENABLE_SPRITE_POINT_TEX |
1641 SPRITE_POINT_TEX_OFF |
1642 ENABLE_FIXED_LINE_WIDTH |
1643 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1644 ENABLE_FIXED_POINT_WIDTH |
1645 FIXED_POINT_WIDTH(1) );
1646
1647 imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD |
1648 DISABLE_INDPT_ALPHA_BLEND |
1649 ENABLE_ALPHA_BLENDFUNC |
1650 ABLENDFUNC_ADD);
1651
1652 imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD |
1653 FOG_COLOR_RED(0) |
1654 FOG_COLOR_GREEN(0) |
1655 FOG_COLOR_BLUE(0));
1656
1657 imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD);
1658
1659 imesa->Setup[I830_CTXREG_BLENDCOLR] = 0;
1660
1661 imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD;
1662 imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
1663 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
1664 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
1665 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
1666
1667 imesa->LcsCullMode = CULLMODE_CW; /* GL default */
1668
1669 memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
1670 memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup));
1671
1672
1673 if (imesa->glCtx->Visual.doubleBufferMode &&
1674 imesa->sarea->pf_current_page == 0) {
1675 imesa->drawMap = i830Screen->back.map;
1676 imesa->readMap = i830Screen->back.map;
1677 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
1678 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1679 } else {
1680 /* use front buffer by default */
1681 imesa->drawMap = (char *)imesa->driScreen->pFB;
1682 imesa->readMap = (char *)imesa->driScreen->pFB;
1683 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
1684 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1685 }
1686
1687 imesa->BufferSetup[I830_DESTREG_DV0] = STATE3D_DST_BUF_VARS_CMD;
1688
1689 switch (i830Screen->fbFormat) {
1690 case DV_PF_555:
1691 case DV_PF_565:
1692 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1693 DSTORG_VERT_BIAS(0x8) | /* .5 */
1694 i830Screen->fbFormat |
1695 DEPTH_IS_Z |
1696 DEPTH_FRMT_16_FIXED);
1697 break;
1698 case DV_PF_8888:
1699 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1700 DSTORG_VERT_BIAS(0x8) | /* .5 */
1701 i830Screen->fbFormat |
1702 DEPTH_IS_Z |
1703 DEPTH_FRMT_24_FIXED_8_OTHER);
1704 break;
1705 }
1706 imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD |
1707 DISABLE_SCISSOR_RECT);
1708 imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD;
1709 imesa->BufferSetup[I830_DESTREG_SR1] = 0;
1710 imesa->BufferSetup[I830_DESTREG_SR2] = 0;
1711
1712 imesa->BufferSetup[I830_DESTREG_DR0] = STATE3D_DRAW_RECT_CMD;
1713 imesa->BufferSetup[I830_DESTREG_DR1] = 0;
1714 imesa->BufferSetup[I830_DESTREG_DR2] = 0;
1715 imesa->BufferSetup[I830_DESTREG_DR3] = (((i830Screen->height)<<16) |
1716 (i830Screen->width));
1717 imesa->BufferSetup[I830_DESTREG_DR4] = 0;
1718
1719 memcpy( imesa->Init_Setup,
1720 imesa->Setup,
1721 sizeof(imesa->Setup) );
1722 memcpy( imesa->Init_BufferSetup,
1723 imesa->BufferSetup,
1724 sizeof(imesa->BufferSetup) );
1725
1726 }
1727
1728 static void i830InvalidateState( GLcontext *ctx, GLuint new_state )
1729 {
1730 _swrast_InvalidateState( ctx, new_state );
1731 _swsetup_InvalidateState( ctx, new_state );
1732 _ac_InvalidateState( ctx, new_state );
1733 _tnl_InvalidateState( ctx, new_state );
1734 I830_CONTEXT(ctx)->NewGLState |= new_state;
1735 }
1736
1737 void i830DDInitStateFuncs(GLcontext *ctx)
1738 {
1739 /* Callbacks for internal Mesa events.
1740 */
1741 ctx->Driver.UpdateState = i830InvalidateState;
1742
1743 /* API callbacks
1744 */
1745 ctx->Driver.AlphaFunc = i830AlphaFunc;
1746 ctx->Driver.BlendEquation = i830BlendEquation;
1747 ctx->Driver.BlendFunc = i830BlendFunc;
1748 ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate;
1749 ctx->Driver.BlendColor = i830BlendColor;
1750 ctx->Driver.ClearColor = i830ClearColor;
1751 ctx->Driver.ColorMask = i830ColorMask;
1752 ctx->Driver.CullFace = i830CullFaceFrontFace;
1753 ctx->Driver.DepthFunc = i830DepthFunc;
1754 ctx->Driver.DepthMask = i830DepthMask;
1755 ctx->Driver.Enable = i830Enable;
1756 ctx->Driver.Fogfv = i830Fogfv;
1757 ctx->Driver.FrontFace = i830CullFaceFrontFace;
1758 ctx->Driver.LineWidth = i830LineWidth;
1759 ctx->Driver.PointSize = i830PointSize;
1760 ctx->Driver.LogicOpcode = i830LogicOp;
1761 ctx->Driver.PolygonStipple = i830PolygonStippleFallback;
1762 ctx->Driver.RenderMode = i830RenderMode;
1763 ctx->Driver.Scissor = i830Scissor;
1764 ctx->Driver.DrawBuffer = i830DrawBuffer;
1765 ctx->Driver.ReadBuffer = i830ReadBuffer;
1766 ctx->Driver.ShadeModel = i830ShadeModel;
1767 ctx->Driver.DepthRange = i830DepthRange;
1768 ctx->Driver.Viewport = i830Viewport;
1769 ctx->Driver.LightModelfv = i830LightModelfv;
1770
1771 ctx->Driver.StencilFunc = i830StencilFunc;
1772 ctx->Driver.StencilMask = i830StencilMask;
1773 ctx->Driver.StencilOp = i830StencilOp;
1774
1775 /* Pixel path fallbacks.
1776 */
1777 ctx->Driver.Accum = _swrast_Accum;
1778 ctx->Driver.Bitmap = _swrast_Bitmap;
1779 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1780 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1781 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1782
1783 /* Swrast hooks for imaging extensions:
1784 */
1785 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1786 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1787 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1788 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1789 }