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