Remove dd_function_table::BlendFunc. All drivers now use
[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 i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
402 GLenum dfactorRGB, GLenum sfactorA,
403 GLenum dfactorA )
404 {
405 i830ContextPtr imesa = I830_CONTEXT(ctx);
406 int funcA = (ENABLE_SRC_ABLEND_FACTOR|ENABLE_DST_ABLEND_FACTOR);
407 int funcRGB = (ENABLE_SRC_BLND_FACTOR|ENABLE_DST_BLND_FACTOR);
408
409 if (I830_DEBUG&DEBUG_DRI)
410 fprintf(stderr, "%s\n", __FUNCTION__);
411
412 switch(sfactorA) {
413 case GL_ZERO:
414 funcA |= SRC_ABLEND_FACT(BLENDFACT_ZERO);
415 break;
416 case GL_SRC_ALPHA:
417 funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA);
418 break;
419 case GL_ONE:
420 funcA |= SRC_ABLEND_FACT(BLENDFACT_ONE);
421 break;
422 case GL_DST_COLOR:
423 funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_COLR);
424 break;
425 case GL_ONE_MINUS_DST_COLOR:
426 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_COLR);
427 break;
428 case GL_ONE_MINUS_SRC_ALPHA:
429 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA);
430 break;
431 case GL_DST_ALPHA:
432 funcA |= SRC_ABLEND_FACT(BLENDFACT_DST_ALPHA);
433 break;
434 case GL_ONE_MINUS_DST_ALPHA:
435 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA);
436 break;
437 case GL_SRC_ALPHA_SATURATE:
438 funcA |= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
439 break;
440 case GL_CONSTANT_COLOR_EXT:
441 funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_COLOR);
442 break;
443 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
444 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR);
445 break;
446 case GL_CONSTANT_ALPHA_EXT:
447 funcA |= SRC_ABLEND_FACT(BLENDFACT_CONST_ALPHA);
448 break;
449 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
450 funcA |= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA);
451 break;
452 default: return;
453 }
454
455 switch(dfactorA) {
456 case GL_SRC_ALPHA:
457 funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_ALPHA);
458 break;
459 case GL_ONE_MINUS_SRC_ALPHA:
460 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA);
461 break;
462 case GL_ZERO:
463 funcA |= DST_ABLEND_FACT(BLENDFACT_ZERO);
464 break;
465 case GL_ONE:
466 funcA |= DST_ABLEND_FACT(BLENDFACT_ONE);
467 break;
468 case GL_SRC_COLOR:
469 funcA |= DST_ABLEND_FACT(BLENDFACT_SRC_COLR);
470 break;
471 case GL_ONE_MINUS_SRC_COLOR:
472 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_SRC_COLR);
473 break;
474 case GL_DST_ALPHA:
475 funcA |= DST_ABLEND_FACT(BLENDFACT_DST_ALPHA);
476 break;
477 case GL_ONE_MINUS_DST_ALPHA:
478 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA);
479 break;
480 case GL_CONSTANT_COLOR_EXT:
481 funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_COLOR);
482 break;
483 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
484 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR);
485 break;
486 case GL_CONSTANT_ALPHA_EXT:
487 funcA |= DST_ABLEND_FACT(BLENDFACT_CONST_ALPHA);
488 break;
489 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
490 funcA |= DST_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA);
491 break;
492 default: return;
493 }
494
495 switch(sfactorRGB) {
496 case GL_ZERO:
497 funcRGB |= SRC_BLND_FACT(BLENDFACT_ZERO);
498 break;
499 case GL_SRC_ALPHA:
500 funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA);
501 break;
502 case GL_ONE:
503 funcRGB |= SRC_BLND_FACT(BLENDFACT_ONE);
504 break;
505 case GL_DST_COLOR:
506 funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_COLR);
507 break;
508 case GL_ONE_MINUS_DST_COLOR:
509 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR);
510 break;
511 case GL_ONE_MINUS_SRC_ALPHA:
512 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
513 break;
514 case GL_DST_ALPHA:
515 funcRGB |= SRC_BLND_FACT(BLENDFACT_DST_ALPHA);
516 break;
517 case GL_ONE_MINUS_DST_ALPHA:
518 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
519 break;
520 case GL_SRC_ALPHA_SATURATE:
521 funcRGB |= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE);
522 break;
523 case GL_CONSTANT_COLOR_EXT:
524 funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_COLOR);
525 break;
526 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
527 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
528 break;
529 case GL_CONSTANT_ALPHA_EXT:
530 funcRGB |= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA);
531 break;
532 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
533 funcRGB |= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
534 break;
535 default: return;
536 }
537
538 switch(dfactorRGB) {
539 case GL_SRC_ALPHA:
540 funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_ALPHA);
541 break;
542 case GL_ONE_MINUS_SRC_ALPHA:
543 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA);
544 break;
545 case GL_ZERO:
546 funcRGB |= DST_BLND_FACT(BLENDFACT_ZERO);
547 break;
548 case GL_ONE:
549 funcRGB |= DST_BLND_FACT(BLENDFACT_ONE);
550 break;
551 case GL_SRC_COLOR:
552 funcRGB |= DST_BLND_FACT(BLENDFACT_SRC_COLR);
553 break;
554 case GL_ONE_MINUS_SRC_COLOR:
555 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR);
556 break;
557 case GL_DST_ALPHA:
558 funcRGB |= DST_BLND_FACT(BLENDFACT_DST_ALPHA);
559 break;
560 case GL_ONE_MINUS_DST_ALPHA:
561 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA);
562 break;
563 case GL_CONSTANT_COLOR_EXT:
564 funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_COLOR);
565 break;
566 case GL_ONE_MINUS_CONSTANT_COLOR_EXT:
567 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR);
568 break;
569 case GL_CONSTANT_ALPHA_EXT:
570 funcRGB |= DST_BLND_FACT(BLENDFACT_CONST_ALPHA);
571 break;
572 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT:
573 funcRGB |= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA);
574 break;
575 default: return;
576 }
577
578 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
579 imesa->Setup[I830_CTXREG_IALPHAB] &= ~SRC_DST_ABLEND_MASK;
580 imesa->Setup[I830_CTXREG_STATE1] &= ~SRC_DST_BLND_MASK;
581 imesa->Setup[I830_CTXREG_STATE1] |= funcRGB;
582
583 if ( (dfactorRGB != dfactorA) || (sfactorRGB != sfactorA) ) {
584 imesa->Setup[I830_CTXREG_IALPHAB] |= funcA;
585 }
586
587 /* Ensure Independant Alpha Blend is really in the correct state (either
588 * enabled or disabled) if blending is already enabled.
589 */
590 i830EvalLogicOpBlendState(ctx);
591 }
592
593 static void i830DepthFunc(GLcontext *ctx, GLenum func)
594 {
595 i830ContextPtr imesa = I830_CONTEXT(ctx);
596 int test = 0;
597
598 if (I830_DEBUG&DEBUG_DRI)
599 fprintf(stderr, "%s\n", __FUNCTION__);
600
601 switch(func) {
602 case GL_NEVER:
603 test = COMPAREFUNC_NEVER;
604 break;
605 case GL_LESS:
606 test = COMPAREFUNC_LESS;
607 break;
608 case GL_LEQUAL:
609 test = COMPAREFUNC_LEQUAL;
610 break;
611 case GL_GREATER:
612 test = COMPAREFUNC_GREATER;
613 break;
614 case GL_GEQUAL:
615 test = COMPAREFUNC_GEQUAL;
616 break;
617 case GL_NOTEQUAL:
618 test = COMPAREFUNC_NOTEQUAL;
619 break;
620 case GL_EQUAL:
621 test = COMPAREFUNC_EQUAL;
622 break;
623 case GL_ALWAYS:
624 test = COMPAREFUNC_ALWAYS;
625 break;
626 default: return;
627 }
628
629 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
630 imesa->Setup[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
631 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
632 DEPTH_TEST_FUNC(test));
633 }
634
635 static void i830DepthMask(GLcontext *ctx, GLboolean flag)
636 {
637 i830ContextPtr imesa = I830_CONTEXT(ctx);
638
639 if (I830_DEBUG&DEBUG_DRI)
640 fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
641
642 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
643
644 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
645
646 if (flag && ctx->Depth.Test)
647 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
648 else
649 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
650 }
651
652 /* =============================================================
653 * Polygon stipple
654 *
655 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
656 * Fortunately stipple is usually a repeating pattern.
657 */
658 static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask )
659 {
660 i830ContextPtr imesa = I830_CONTEXT(ctx);
661 const GLubyte *m = mask;
662 GLubyte p[4];
663 int i,j,k;
664 int active = (ctx->Polygon.StippleFlag &&
665 imesa->reduced_primitive == GL_TRIANGLES);
666 GLuint newMask;
667
668 if (active) {
669 I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
670 imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE;
671 }
672
673 p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
674 p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
675 p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
676 p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
677
678 for (k = 0 ; k < 8 ; k++)
679 for (j = 3 ; j >= 0; j--)
680 for (i = 0 ; i < 4 ; i++, m++)
681 if (*m != p[j]) {
682 imesa->hw_stipple = 0;
683 return;
684 }
685
686 newMask = (((p[0] & 0xf) << 0) |
687 ((p[1] & 0xf) << 4) |
688 ((p[2] & 0xf) << 8) |
689 ((p[3] & 0xf) << 12));
690
691
692 if (newMask == 0xffff || newMask == 0x0) {
693 /* this is needed to make conform pass */
694 imesa->hw_stipple = 0;
695 return;
696 }
697
698 imesa->StippleSetup[I830_STPREG_ST1] &= ~0xffff;
699 imesa->StippleSetup[I830_STPREG_ST1] |= newMask;
700 imesa->hw_stipple = 1;
701
702 if (active)
703 imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
704 }
705
706 static void i830PolygonStippleFallback( GLcontext *ctx, const GLubyte *mask )
707 {
708 i830ContextPtr imesa = I830_CONTEXT(ctx);
709 imesa->hw_stipple = 0;
710 (void) i830PolygonStipple;
711 }
712
713 /* =============================================================
714 * Hardware clipping
715 */
716 static void i830Scissor(GLcontext *ctx, GLint x, GLint y,
717 GLsizei w, GLsizei h)
718 {
719 i830ContextPtr imesa = I830_CONTEXT(ctx);
720 int x1 = x;
721 int y1 = imesa->driDrawable->h - (y + h);
722 int x2 = x + w - 1;
723 int y2 = y1 + h - 1;
724
725 if (I830_DEBUG&DEBUG_DRI)
726 fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__,
727 x, y, w, h);
728
729 if (x1 < 0) x1 = 0;
730 if (y1 < 0) y1 = 0;
731 if (x2 < 0) x2 = 0;
732 if (y2 < 0) y2 = 0;
733
734 if (x2 >= imesa->i830Screen->width) x2 = imesa->i830Screen->width-1;
735 if (y2 >= imesa->i830Screen->height) y2 = imesa->i830Screen->height-1;
736 if (x1 >= imesa->i830Screen->width) x1 = imesa->i830Screen->width-1;
737 if (y1 >= imesa->i830Screen->height) y1 = imesa->i830Screen->height-1;
738
739
740 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
741 imesa->BufferSetup[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
742 imesa->BufferSetup[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
743 }
744
745 static void i830LogicOp(GLcontext *ctx, GLenum opcode)
746 {
747 i830ContextPtr imesa = I830_CONTEXT(ctx);
748 int tmp = 0;
749
750 if (I830_DEBUG&DEBUG_DRI)
751 fprintf(stderr, "%s\n", __FUNCTION__);
752
753 /* FIXME: This should be a look-up table, like the r200 driver. */
754 switch(opcode) {
755 case GL_CLEAR:
756 tmp = LOGICOP_CLEAR;
757 break;
758 case GL_AND:
759 tmp = LOGICOP_AND;
760 break;
761 case GL_AND_REVERSE:
762 tmp = LOGICOP_AND_RVRSE;
763 break;
764 case GL_COPY:
765 tmp = LOGICOP_COPY;
766 break;
767 case GL_COPY_INVERTED:
768 tmp = LOGICOP_COPY_INV;
769 break;
770 case GL_AND_INVERTED:
771 tmp = LOGICOP_AND_INV;
772 break;
773 case GL_NOOP:
774 tmp = LOGICOP_NOOP;
775 break;
776 case GL_XOR:
777 tmp = LOGICOP_XOR;
778 break;
779 case GL_OR:
780 tmp = LOGICOP_OR;
781 break;
782 case GL_OR_INVERTED:
783 tmp = LOGICOP_OR_INV;
784 break;
785 case GL_NOR:
786 tmp = LOGICOP_NOR;
787 break;
788 case GL_EQUIV:
789 tmp = LOGICOP_EQUIV;
790 break;
791 case GL_INVERT:
792 tmp = LOGICOP_INV;
793 break;
794 case GL_OR_REVERSE:
795 tmp = LOGICOP_OR_RVRSE;
796 break;
797 case GL_NAND:
798 tmp = LOGICOP_NAND;
799 break;
800 case GL_SET:
801 tmp = LOGICOP_SET;
802 break;
803 default:
804 return;
805 }
806
807 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
808 imesa->Setup[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
809 imesa->Setup[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
810
811 /* Make sure all the enables are correct */
812 i830EvalLogicOpBlendState(ctx);
813 }
814
815 /* Fallback to swrast for select and feedback.
816 */
817 static void i830RenderMode( GLcontext *ctx, GLenum mode )
818 {
819 i830ContextPtr imesa = I830_CONTEXT(ctx);
820 FALLBACK( imesa, I830_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
821 }
822
823 static void i830DrawBuffer(GLcontext *ctx, GLenum mode )
824 {
825 i830ContextPtr imesa = I830_CONTEXT(ctx);
826
827 /*
828 * _DrawDestMask is easier to cope with than <mode>.
829 */
830 switch ( ctx->Color._DrawDestMask ) {
831 case FRONT_LEFT_BIT:
832 I830_FIREVERTICES(imesa);
833 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
834 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = imesa->i830Screen->fbOffset;
835 i830XMesaSetFrontClipRects( imesa );
836 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
837 break;
838 case BACK_LEFT_BIT:
839 I830_FIREVERTICES(imesa);
840 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
841 imesa->BufferSetup[I830_DESTREG_CBUFADDR] =
842 imesa->i830Screen->backOffset;
843 i830XMesaSetBackClipRects( imesa );
844 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_FALSE );
845 break;
846 default:
847 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
848 FALLBACK( imesa, I830_FALLBACK_DRAW_BUFFER, GL_TRUE );
849 return;
850 }
851
852 /* We want to update the s/w rast state too so that i830SetBuffer()
853 * gets called.
854 */
855 _swrast_DrawBuffer(ctx, mode);
856 }
857
858 static void i830ReadBuffer(GLcontext *ctx, GLenum mode )
859 {
860 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
861 }
862
863 static void i830ClearColor(GLcontext *ctx, const GLfloat color[4])
864 {
865 i830ContextPtr imesa = I830_CONTEXT(ctx);
866
867 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_red, color[0]);
868 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_green, color[1]);
869 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_blue, color[2]);
870 CLAMPED_FLOAT_TO_UBYTE(imesa->clear_alpha, color[3]);
871
872 imesa->ClearColor = i830PackColor(imesa->i830Screen->fbFormat,
873 imesa->clear_red,
874 imesa->clear_green,
875 imesa->clear_blue,
876 imesa->clear_alpha);
877 }
878
879 static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused)
880 {
881 i830ContextPtr imesa = I830_CONTEXT(ctx);
882 GLuint mode = CULLMODE_BOTH;
883
884 if (I830_DEBUG&DEBUG_DRI)
885 fprintf(stderr, "%s\n", __FUNCTION__);
886
887 if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
888 mode = CULLMODE_CW;
889
890 if (ctx->Polygon.CullFaceMode == GL_FRONT)
891 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
892 if (ctx->Polygon.FrontFace != GL_CCW)
893 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
894 }
895
896 imesa->LcsCullMode = mode;
897
898 if (ctx->Polygon.CullFlag) {
899 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
900 imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
901 imesa->Setup[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode;
902 }
903 }
904
905 static void i830LineWidth( GLcontext *ctx, GLfloat widthf )
906 {
907 i830ContextPtr imesa = I830_CONTEXT( ctx );
908 int width;
909
910 if (I830_DEBUG&DEBUG_DRI)
911 fprintf(stderr, "%s\n", __FUNCTION__);
912
913 width = FloatToInt(widthf * 2);
914 CLAMP_SELF(width, 1, 15);
915
916 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
917 imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_LINE_WIDTH_MASK;
918 imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_LINE_WIDTH |
919 FIXED_LINE_WIDTH(width));
920 }
921
922 static void i830PointSize(GLcontext *ctx, GLfloat size)
923 {
924 i830ContextPtr imesa = I830_CONTEXT(ctx);
925 GLint point_size = FloatToInt(size);
926
927 if (I830_DEBUG&DEBUG_DRI)
928 fprintf(stderr, "%s\n", __FUNCTION__);
929
930 CLAMP_SELF(point_size, 1, 256);
931 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
932 imesa->Setup[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
933 imesa->Setup[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
934 FIXED_POINT_WIDTH(point_size));
935 }
936
937
938 /* =============================================================
939 * Color masks
940 */
941
942 static void i830ColorMask(GLcontext *ctx,
943 GLboolean r, GLboolean g,
944 GLboolean b, GLboolean a)
945 {
946 i830ContextPtr imesa = I830_CONTEXT( ctx );
947 GLuint tmp = 0;
948
949 if (I830_DEBUG&DEBUG_DRI)
950 fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
951
952 imesa->mask_red = !r;
953 imesa->mask_green = !g;
954 imesa->mask_blue = !b;
955 imesa->mask_alpha = !a;
956
957 tmp = (imesa->Setup[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) |
958 ENABLE_COLOR_MASK |
959 ENABLE_COLOR_WRITE |
960 ((!r) << WRITEMASK_RED_SHIFT) |
961 ((!g) << WRITEMASK_GREEN_SHIFT) |
962 ((!b) << WRITEMASK_BLUE_SHIFT) |
963 ((!a) << WRITEMASK_ALPHA_SHIFT);
964
965 if (tmp != imesa->Setup[I830_CTXREG_ENABLES_2]) {
966 I830_FIREVERTICES(imesa);
967 imesa->dirty |= I830_UPLOAD_CTX;
968 imesa->Setup[I830_CTXREG_ENABLES_2] = tmp;
969 }
970 }
971
972 static void update_specular( GLcontext *ctx )
973 {
974 i830ContextPtr imesa = I830_CONTEXT( ctx );
975
976 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
977 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK;
978
979 if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
980 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD;
981 else
982 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD;
983 }
984
985 static void i830LightModelfv(GLcontext *ctx, GLenum pname,
986 const GLfloat *param)
987 {
988 if (I830_DEBUG&DEBUG_DRI)
989 fprintf(stderr, "%s\n", __FUNCTION__);
990
991 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
992 update_specular( ctx );
993 }
994 }
995
996 /* In Mesa 3.5 we can reliably do native flatshading.
997 */
998 static void i830ShadeModel(GLcontext *ctx, GLenum mode)
999 {
1000 i830ContextPtr imesa = I830_CONTEXT(ctx);
1001 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1002
1003
1004 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
1005
1006 imesa->Setup[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK;
1007
1008 if (mode == GL_FLAT) {
1009 imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) |
1010 FOG_SHADE_MODE(SHADE_MODE_FLAT) |
1011 SPEC_SHADE_MODE(SHADE_MODE_FLAT) |
1012 COLOR_SHADE_MODE(SHADE_MODE_FLAT));
1013 } else {
1014 imesa->Setup[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1015 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1016 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1017 COLOR_SHADE_MODE(SHADE_MODE_LINEAR));
1018 }
1019 }
1020
1021 /* =============================================================
1022 * Fog
1023 */
1024 static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
1025 {
1026 i830ContextPtr imesa = I830_CONTEXT(ctx);
1027
1028 if (I830_DEBUG&DEBUG_DRI)
1029 fprintf(stderr, "%s\n", __FUNCTION__);
1030
1031 if (pname == GL_FOG_COLOR) {
1032 GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
1033 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
1034 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
1035
1036 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1037 imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD | color);
1038 }
1039 }
1040
1041 /* =============================================================
1042 */
1043
1044 static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state)
1045 {
1046 i830ContextPtr imesa = I830_CONTEXT(ctx);
1047
1048 switch(cap) {
1049 case GL_LIGHTING:
1050 case GL_COLOR_SUM_EXT:
1051 update_specular( ctx );
1052 break;
1053
1054 case GL_ALPHA_TEST:
1055 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1056 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK;
1057 if (state)
1058 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST;
1059 else
1060 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST;
1061
1062 break;
1063
1064 case GL_BLEND:
1065 case GL_COLOR_LOGIC_OP:
1066 case GL_INDEX_LOGIC_OP:
1067 i830EvalLogicOpBlendState(ctx);
1068 break;
1069
1070 case GL_DITHER:
1071 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1072 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER;
1073
1074 if (state)
1075 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER;
1076 else
1077 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER;
1078 break;
1079
1080 case GL_DEPTH_TEST:
1081 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1082 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
1083
1084 if (state)
1085 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
1086 else
1087 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
1088
1089 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1090 */
1091 i830DepthMask( ctx, state );
1092 break;
1093
1094 case GL_SCISSOR_TEST:
1095 I830_STATECHANGE(imesa, I830_UPLOAD_BUFFERS);
1096
1097 if (state)
1098 imesa->BufferSetup[I830_DESTREG_SENABLE] =
1099 (STATE3D_SCISSOR_ENABLE_CMD |
1100 ENABLE_SCISSOR_RECT);
1101 else
1102 imesa->BufferSetup[I830_DESTREG_SENABLE] =
1103 (STATE3D_SCISSOR_ENABLE_CMD |
1104 DISABLE_SCISSOR_RECT);
1105
1106 imesa->upload_cliprects = GL_TRUE;
1107 break;
1108
1109 case GL_LINE_SMOOTH:
1110 if (imesa->reduced_primitive == GL_LINES) {
1111 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1112
1113 imesa->Setup[I830_CTXREG_AA] &= ~AA_LINE_ENABLE;
1114 if (state)
1115 imesa->Setup[I830_CTXREG_AA] |= AA_LINE_ENABLE;
1116 else
1117 imesa->Setup[I830_CTXREG_AA] |= AA_LINE_DISABLE;
1118 }
1119 break;
1120
1121 case GL_FOG:
1122 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1123 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK;
1124 if (state)
1125 imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_ENABLE_FOG;
1126 else
1127 imesa->Setup[I830_CTXREG_ENABLES_1] |= I830_DISABLE_FOG;
1128 break;
1129
1130 case GL_CULL_FACE:
1131 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1132 imesa->Setup[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
1133 if (state)
1134 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
1135 imesa->LcsCullMode);
1136 else
1137 imesa->Setup[I830_CTXREG_STATE3] |= (ENABLE_CULL_MODE |
1138 CULLMODE_NONE);
1139 break;
1140
1141 case GL_TEXTURE_2D:
1142 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1143 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1144 break;
1145
1146 case GL_STENCIL_TEST:
1147 if (imesa->hw_stencil) {
1148 I830_STATECHANGE(imesa, I830_UPLOAD_CTX);
1149 imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
1150 imesa->Setup[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE;
1151
1152 if (state) {
1153 imesa->Setup[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
1154 imesa->Setup[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
1155 } else {
1156 imesa->Setup[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
1157 imesa->Setup[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE;
1158 }
1159 } else {
1160 FALLBACK( imesa, I830_FALLBACK_STENCIL, state );
1161 }
1162 break;
1163
1164 case GL_POLYGON_STIPPLE:
1165 #if 0
1166 /* The stipple command worked on my 855GM box, but not my 845G.
1167 * I'll do more testing later to find out exactly which hardware
1168 * supports it. Disabled for now.
1169 */
1170 if (imesa->hw_stipple && imesa->reduced_primitive == GL_TRIANGLES)
1171 {
1172 I830_STATECHANGE(imesa, I830_UPLOAD_STIPPLE);
1173 imesa->StippleSetup[I830_STPREG_ST1] &= ~ST1_ENABLE;
1174 if (state)
1175 imesa->StippleSetup[I830_STPREG_ST1] |= ST1_ENABLE;
1176 }
1177 #endif
1178 break;
1179
1180 default:
1181 ;
1182 }
1183 }
1184
1185
1186 void i830EmitDrawingRectangle( i830ContextPtr imesa )
1187 {
1188 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
1189 i830ScreenPrivate *i830Screen = imesa->i830Screen;
1190 int x0 = imesa->drawX;
1191 int y0 = imesa->drawY;
1192 int x1 = x0 + dPriv->w;
1193 int y1 = y0 + dPriv->h;
1194
1195 /* Don't set drawing rectangle */
1196 if (I830_DEBUG & DEBUG_IOCTL)
1197 fprintf(stderr, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__,
1198 x0, x1, y0, y1);
1199
1200 /* Coordinate origin of the window - may be offscreen.
1201 */
1202 imesa->BufferSetup[I830_DESTREG_DR4] = ((y0<<16) |
1203 (((unsigned)x0)&0xFFFF));
1204
1205 /* Clip to screen.
1206 */
1207 if (x0 < 0) x0 = 0;
1208 if (y0 < 0) y0 = 0;
1209 if (x1 > i830Screen->width-1) x1 = i830Screen->width-1;
1210 if (y1 > i830Screen->height-1) y1 = i830Screen->height-1;
1211
1212
1213 /* Onscreen drawing rectangle.
1214 */
1215 imesa->BufferSetup[I830_DESTREG_DR2] = ((y0<<16) | x0);
1216 imesa->BufferSetup[I830_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
1217
1218
1219 /* Just add in our dirty flag, since we might be called when locked */
1220 /* Might want to modify how this is done. */
1221 imesa->dirty |= I830_UPLOAD_BUFFERS;
1222
1223 if (0)
1224 fprintf(stderr, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1225 __FUNCTION__,
1226 imesa->BufferSetup[I830_DESTREG_DR2],
1227 imesa->BufferSetup[I830_DESTREG_DR3],
1228 imesa->BufferSetup[I830_DESTREG_DR4]);
1229 }
1230
1231 /* This could be done in hardware, will do once I have the driver
1232 * up and running.
1233 */
1234 static void i830CalcViewport( GLcontext *ctx )
1235 {
1236 i830ContextPtr imesa = I830_CONTEXT(ctx);
1237 const GLfloat *v = ctx->Viewport._WindowMap.m;
1238 GLfloat *m = imesa->ViewportMatrix.m;
1239
1240 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1241 * via state vars, too.
1242 */
1243 m[MAT_SX] = v[MAT_SX];
1244 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
1245 m[MAT_SY] = - v[MAT_SY];
1246 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y;
1247 m[MAT_SZ] = v[MAT_SZ] * imesa->depth_scale;
1248 m[MAT_TZ] = v[MAT_TZ] * imesa->depth_scale;
1249 }
1250
1251 static void i830Viewport( GLcontext *ctx,
1252 GLint x, GLint y,
1253 GLsizei width, GLsizei height )
1254 {
1255 i830CalcViewport( ctx );
1256 }
1257
1258 static void i830DepthRange( GLcontext *ctx,
1259 GLclampd nearval, GLclampd farval )
1260 {
1261 i830CalcViewport( ctx );
1262 }
1263
1264 void i830PrintDirty( const char *msg, GLuint state )
1265 {
1266 fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
1267 msg,
1268 (unsigned int) state,
1269 (state & I830_UPLOAD_TEX0) ? "upload-tex0, " : "",
1270 (state & I830_UPLOAD_TEX1) ? "upload-tex1, " : "",
1271 (state & I830_UPLOAD_CTX) ? "upload-ctx, " : "",
1272 (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
1273 (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "",
1274 (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "",
1275 (state & I830_UPLOAD_STIPPLE) ? "stipple, " : ""
1276 );
1277 }
1278
1279 /* Push the state into the sarea and/or texture memory.
1280 */
1281 void i830EmitHwStateLocked( i830ContextPtr imesa )
1282 {
1283 int i;
1284
1285 if (I830_DEBUG & DEBUG_STATE)
1286 i830PrintDirty( __FUNCTION__, imesa->dirty );
1287
1288 if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0])
1289 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]);
1290 if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1])
1291 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]);
1292 if (imesa->dirty & I830_UPLOAD_CTX) {
1293 memcpy( imesa->sarea->ContextState,
1294 imesa->Setup, sizeof(imesa->Setup) );
1295 }
1296
1297 for (i = 0; i < I830_TEXTURE_COUNT; i++) {
1298 if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) {
1299 imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i);
1300 memcpy(imesa->sarea->TexState[i],
1301 imesa->CurrentTexObj[i]->Setup,
1302 sizeof(imesa->sarea->TexState[i]));
1303
1304 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
1305 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] |= imesa->LodBias[i];
1306
1307 /* Update the LRU usage */
1308 if (imesa->CurrentTexObj[i]->base.memBlock)
1309 driUpdateTextureLRU( (driTextureObject *)
1310 imesa->CurrentTexObj[i] );
1311 }
1312 }
1313 /* Need to figure out if texturing state, or enable changed. */
1314
1315 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1316 if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) {
1317 imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i);
1318 memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i],
1319 imesa->TexBlendWordsUsed[i] * 4);
1320 imesa->sarea->TexBlendStateWordsUsed[i] =
1321 imesa->TexBlendWordsUsed[i];
1322 }
1323 }
1324
1325 if (imesa->dirty & I830_UPLOAD_BUFFERS) {
1326 memcpy( imesa->sarea->BufferState,imesa->BufferSetup,
1327 sizeof(imesa->BufferSetup) );
1328 }
1329
1330 if (imesa->dirty & I830_UPLOAD_STIPPLE) {
1331 memcpy( imesa->sarea->StippleState,imesa->StippleSetup,
1332 sizeof(imesa->StippleSetup) );
1333 }
1334
1335 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
1336 memcpy( imesa->sarea->Palette[0],imesa->palette,
1337 sizeof(imesa->sarea->Palette[0]));
1338 } else {
1339 i830TextureObjectPtr p;
1340 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
1341 p = imesa->CurrentTexObj[0];
1342 memcpy( imesa->sarea->Palette[0],p->palette,
1343 sizeof(imesa->sarea->Palette[0]));
1344 }
1345 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
1346 p = imesa->CurrentTexObj[1];
1347 memcpy( imesa->sarea->Palette[1],
1348 p->palette,
1349 sizeof(imesa->sarea->Palette[1]));
1350 }
1351 }
1352
1353 imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK |
1354 I830_UPLOAD_TEXBLEND_MASK));
1355
1356 imesa->upload_cliprects = GL_TRUE;
1357 imesa->dirty = 0;
1358 }
1359
1360
1361 void i830DDInitState( GLcontext *ctx )
1362 {
1363 i830ContextPtr imesa = I830_CONTEXT(ctx);
1364 i830ScreenPrivate *i830Screen = imesa->i830Screen;
1365 int i, j;
1366
1367 imesa->clear_red = 0;
1368 imesa->clear_green = 0;
1369 imesa->clear_blue = 0;
1370 imesa->clear_alpha = 0;
1371
1372 imesa->mask_red = GL_FALSE;
1373 imesa->mask_green = GL_FALSE;
1374 imesa->mask_blue = GL_FALSE;
1375 imesa->mask_alpha = GL_FALSE;
1376
1377 /* Zero all texture state */
1378 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1379 for (j = 0; j < I830_TEXBLEND_SIZE; j++) {
1380 imesa->TexBlend[i][j] = 0;
1381 imesa->Init_TexBlend[i][j] = 0;
1382 }
1383 imesa->TexBlendWordsUsed[i] = 0;
1384 imesa->Init_TexBlendWordsUsed[i] = 0;
1385 imesa->TexBlendColorPipeNum[i] = 0;
1386 imesa->Init_TexBlendColorPipeNum[i] = 0;
1387 }
1388
1389 /* Set default blend state */
1390 imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1391 TEXPIPE_COLOR |
1392 ENABLE_TEXOUTPUT_WRT_SEL |
1393 TEXOP_OUTPUT_CURRENT |
1394 DISABLE_TEX_CNTRL_STAGE |
1395 TEXOP_SCALE_1X |
1396 TEXOP_MODIFY_PARMS |
1397 TEXOP_LAST_STAGE |
1398 TEXBLENDOP_ARG1);
1399 imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1400 TEXPIPE_ALPHA |
1401 ENABLE_TEXOUTPUT_WRT_SEL |
1402 TEXOP_OUTPUT_CURRENT |
1403 TEXOP_SCALE_1X |
1404 TEXOP_MODIFY_PARMS |
1405 TEXBLENDOP_ARG1);
1406 imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1407 TEXPIPE_COLOR |
1408 TEXBLEND_ARG1 |
1409 TEXBLENDARG_MODIFY_PARMS |
1410 TEXBLENDARG_DIFFUSE);
1411 imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1412 TEXPIPE_ALPHA |
1413 TEXBLEND_ARG1 |
1414 TEXBLENDARG_MODIFY_PARMS |
1415 TEXBLENDARG_DIFFUSE);
1416
1417 imesa->TexBlendWordsUsed[0] = 4;
1418 imesa->TexBlendColorPipeNum[0] = 0;
1419
1420 imesa->Init_TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1421 TEXPIPE_COLOR |
1422 ENABLE_TEXOUTPUT_WRT_SEL |
1423 TEXOP_OUTPUT_CURRENT |
1424 DISABLE_TEX_CNTRL_STAGE |
1425 TEXOP_SCALE_1X |
1426 TEXOP_MODIFY_PARMS |
1427 TEXOP_LAST_STAGE |
1428 TEXBLENDOP_ARG1);
1429 imesa->Init_TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1430 TEXPIPE_ALPHA |
1431 ENABLE_TEXOUTPUT_WRT_SEL |
1432 TEXOP_OUTPUT_CURRENT |
1433 TEXOP_SCALE_1X |
1434 TEXOP_MODIFY_PARMS |
1435 TEXBLENDOP_ARG1);
1436 imesa->Init_TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1437 TEXPIPE_COLOR |
1438 TEXBLEND_ARG1 |
1439 TEXBLENDARG_MODIFY_PARMS |
1440 TEXBLENDARG_CURRENT);
1441 imesa->Init_TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1442 TEXPIPE_ALPHA |
1443 TEXBLEND_ARG1 |
1444 TEXBLENDARG_MODIFY_PARMS |
1445 TEXBLENDARG_CURRENT);
1446 imesa->Init_TexBlendWordsUsed[0] = 4;
1447 imesa->Init_TexBlendColorPipeNum[0] = 0;
1448
1449 memset(imesa->Setup, 0, sizeof(imesa->Setup));
1450
1451 imesa->Setup[I830_CTXREG_VF] = 0;
1452 imesa->Setup[I830_CTXREG_VF2] = 0;
1453
1454 imesa->Setup[I830_CTXREG_AA] = (STATE3D_AA_CMD |
1455 AA_LINE_ECAAR_WIDTH_ENABLE |
1456 AA_LINE_ECAAR_WIDTH_1_0 |
1457 AA_LINE_REGION_WIDTH_ENABLE |
1458 AA_LINE_REGION_WIDTH_1_0 |
1459 AA_LINE_DISABLE);
1460
1461 imesa->Setup[I830_CTXREG_ENABLES_1] = (STATE3D_ENABLES_1_CMD |
1462 DISABLE_LOGIC_OP |
1463 DISABLE_STENCIL_TEST |
1464 DISABLE_DEPTH_BIAS |
1465 DISABLE_SPEC_ADD |
1466 I830_DISABLE_FOG |
1467 DISABLE_ALPHA_TEST |
1468 DISABLE_COLOR_BLEND |
1469 DISABLE_DEPTH_TEST);
1470
1471 if (imesa->hw_stencil) {
1472 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1473 ENABLE_STENCIL_WRITE |
1474 ENABLE_TEX_CACHE |
1475 ENABLE_DITHER |
1476 ENABLE_COLOR_MASK |
1477 /* set no color comps disabled */
1478 ENABLE_COLOR_WRITE |
1479 ENABLE_DEPTH_WRITE);
1480 } else {
1481 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1482 DISABLE_STENCIL_WRITE |
1483 ENABLE_TEX_CACHE |
1484 ENABLE_DITHER |
1485 ENABLE_COLOR_MASK |
1486 /* set no color comps disabled */
1487 ENABLE_COLOR_WRITE |
1488 ENABLE_DEPTH_WRITE);
1489 }
1490
1491 imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD |
1492 ENABLE_COLR_BLND_FUNC |
1493 BLENDFUNC_ADD |
1494 ENABLE_SRC_BLND_FACTOR |
1495 SRC_BLND_FACT(BLENDFACT_ONE) |
1496 ENABLE_DST_BLND_FACTOR |
1497 DST_BLND_FACT(BLENDFACT_ZERO) );
1498
1499 imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD |
1500 ENABLE_GLOBAL_DEPTH_BIAS |
1501 GLOBAL_DEPTH_BIAS(0) |
1502 ENABLE_ALPHA_TEST_FUNC |
1503 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1504 ALPHA_REF_VALUE(0) );
1505
1506 imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD |
1507 ENABLE_DEPTH_TEST_FUNC |
1508 DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
1509 ENABLE_ALPHA_SHADE_MODE |
1510 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1511 ENABLE_FOG_SHADE_MODE |
1512 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1513 ENABLE_SPEC_SHADE_MODE |
1514 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1515 ENABLE_COLOR_SHADE_MODE |
1516 COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
1517 ENABLE_CULL_MODE |
1518 CULLMODE_NONE);
1519
1520 imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD |
1521 ENABLE_LOGIC_OP_FUNC |
1522 LOGIC_OP_FUNC(LOGICOP_COPY) |
1523 ENABLE_STENCIL_TEST_MASK |
1524 STENCIL_TEST_MASK(0xff) |
1525 ENABLE_STENCIL_WRITE_MASK |
1526 STENCIL_WRITE_MASK(0xff));
1527
1528 imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD |
1529 ENABLE_STENCIL_PARMS |
1530 STENCIL_FAIL_OP(STENCILOP_KEEP) |
1531 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
1532 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
1533 ENABLE_STENCIL_TEST_FUNC |
1534 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1535 ENABLE_STENCIL_REF_VALUE |
1536 STENCIL_REF_VALUE(0) );
1537
1538 imesa->Setup[I830_CTXREG_STATE5] = (STATE3D_MODES_5_CMD |
1539 FLUSH_TEXTURE_CACHE |
1540 ENABLE_SPRITE_POINT_TEX |
1541 SPRITE_POINT_TEX_OFF |
1542 ENABLE_FIXED_LINE_WIDTH |
1543 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1544 ENABLE_FIXED_POINT_WIDTH |
1545 FIXED_POINT_WIDTH(1) );
1546
1547 imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD |
1548 DISABLE_INDPT_ALPHA_BLEND |
1549 ENABLE_ALPHA_BLENDFUNC |
1550 ABLENDFUNC_ADD);
1551
1552 imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD |
1553 FOG_COLOR_RED(0) |
1554 FOG_COLOR_GREEN(0) |
1555 FOG_COLOR_BLUE(0));
1556
1557 imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD);
1558
1559 imesa->Setup[I830_CTXREG_BLENDCOLR] = 0;
1560
1561 imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD;
1562 imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
1563 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
1564 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
1565 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
1566
1567 imesa->LcsCullMode = CULLMODE_CW; /* GL default */
1568
1569 memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
1570 memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup));
1571
1572
1573 if (imesa->glCtx->Visual.doubleBufferMode &&
1574 imesa->sarea->pf_current_page == 0) {
1575 imesa->drawMap = i830Screen->back.map;
1576 imesa->readMap = i830Screen->back.map;
1577 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
1578 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1579 } else {
1580 /* use front buffer by default */
1581 imesa->drawMap = (char *)imesa->driScreen->pFB;
1582 imesa->readMap = (char *)imesa->driScreen->pFB;
1583 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
1584 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1585 }
1586
1587 imesa->BufferSetup[I830_DESTREG_DV0] = STATE3D_DST_BUF_VARS_CMD;
1588
1589 switch (i830Screen->fbFormat) {
1590 case DV_PF_555:
1591 case DV_PF_565:
1592 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1593 DSTORG_VERT_BIAS(0x8) | /* .5 */
1594 i830Screen->fbFormat |
1595 DEPTH_IS_Z |
1596 DEPTH_FRMT_16_FIXED);
1597 break;
1598 case DV_PF_8888:
1599 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1600 DSTORG_VERT_BIAS(0x8) | /* .5 */
1601 i830Screen->fbFormat |
1602 DEPTH_IS_Z |
1603 DEPTH_FRMT_24_FIXED_8_OTHER);
1604 break;
1605 }
1606 imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD |
1607 DISABLE_SCISSOR_RECT);
1608 imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD;
1609 imesa->BufferSetup[I830_DESTREG_SR1] = 0;
1610 imesa->BufferSetup[I830_DESTREG_SR2] = 0;
1611
1612 imesa->BufferSetup[I830_DESTREG_DR0] = STATE3D_DRAW_RECT_CMD;
1613 imesa->BufferSetup[I830_DESTREG_DR1] = 0;
1614 imesa->BufferSetup[I830_DESTREG_DR2] = 0;
1615 imesa->BufferSetup[I830_DESTREG_DR3] = (((i830Screen->height)<<16) |
1616 (i830Screen->width));
1617 imesa->BufferSetup[I830_DESTREG_DR4] = 0;
1618
1619 memcpy( imesa->Init_Setup,
1620 imesa->Setup,
1621 sizeof(imesa->Setup) );
1622 memcpy( imesa->Init_BufferSetup,
1623 imesa->BufferSetup,
1624 sizeof(imesa->BufferSetup) );
1625
1626 }
1627
1628 static void i830InvalidateState( GLcontext *ctx, GLuint new_state )
1629 {
1630 _swrast_InvalidateState( ctx, new_state );
1631 _swsetup_InvalidateState( ctx, new_state );
1632 _ac_InvalidateState( ctx, new_state );
1633 _tnl_InvalidateState( ctx, new_state );
1634 I830_CONTEXT(ctx)->NewGLState |= new_state;
1635 }
1636
1637 void i830DDInitStateFuncs(GLcontext *ctx)
1638 {
1639 /* Callbacks for internal Mesa events.
1640 */
1641 ctx->Driver.UpdateState = i830InvalidateState;
1642
1643 /* API callbacks
1644 */
1645 ctx->Driver.AlphaFunc = i830AlphaFunc;
1646 ctx->Driver.BlendEquation = i830BlendEquation;
1647 ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate;
1648 ctx->Driver.BlendColor = i830BlendColor;
1649 ctx->Driver.ClearColor = i830ClearColor;
1650 ctx->Driver.ColorMask = i830ColorMask;
1651 ctx->Driver.CullFace = i830CullFaceFrontFace;
1652 ctx->Driver.DepthFunc = i830DepthFunc;
1653 ctx->Driver.DepthMask = i830DepthMask;
1654 ctx->Driver.Enable = i830Enable;
1655 ctx->Driver.Fogfv = i830Fogfv;
1656 ctx->Driver.FrontFace = i830CullFaceFrontFace;
1657 ctx->Driver.LineWidth = i830LineWidth;
1658 ctx->Driver.PointSize = i830PointSize;
1659 ctx->Driver.LogicOpcode = i830LogicOp;
1660 ctx->Driver.PolygonStipple = i830PolygonStippleFallback;
1661 ctx->Driver.RenderMode = i830RenderMode;
1662 ctx->Driver.Scissor = i830Scissor;
1663 ctx->Driver.DrawBuffer = i830DrawBuffer;
1664 ctx->Driver.ReadBuffer = i830ReadBuffer;
1665 ctx->Driver.ShadeModel = i830ShadeModel;
1666 ctx->Driver.DepthRange = i830DepthRange;
1667 ctx->Driver.Viewport = i830Viewport;
1668 ctx->Driver.LightModelfv = i830LightModelfv;
1669
1670 ctx->Driver.StencilFunc = i830StencilFunc;
1671 ctx->Driver.StencilMask = i830StencilMask;
1672 ctx->Driver.StencilOp = i830StencilOp;
1673
1674 /* Pixel path fallbacks.
1675 */
1676 ctx->Driver.Accum = _swrast_Accum;
1677 ctx->Driver.Bitmap = _swrast_Bitmap;
1678 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1679 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1680 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1681
1682 /* Swrast hooks for imaging extensions:
1683 */
1684 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1685 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1686 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1687 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1688 }