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