Reorganized hardware state data structures and state emission. Don't track
[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 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 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\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_CTX) ? "upload-ctx, " : "",
1275 (state & I830_UPLOAD_BUFFERS) ? "upload-bufs, " : "",
1276 (state & I830_UPLOAD_TEXBLEND0) ? "upload-blend0, " : "",
1277 (state & I830_UPLOAD_TEXBLEND1) ? "upload-blend1, " : "",
1278 (state & I830_UPLOAD_STIPPLE) ? "stipple, " : ""
1279 );
1280 }
1281
1282 /* Push the state into the sarea and/or texture memory.
1283 */
1284 void i830EmitHwStateLocked( i830ContextPtr imesa )
1285 {
1286 int i;
1287
1288 if (I830_DEBUG & DEBUG_STATE)
1289 i830PrintDirty( __FUNCTION__, imesa->dirty );
1290
1291 if ((imesa->dirty & I830_UPLOAD_TEX0_IMAGE) && imesa->CurrentTexObj[0])
1292 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[0]);
1293 if ((imesa->dirty & I830_UPLOAD_TEX1_IMAGE) && imesa->CurrentTexObj[1])
1294 i830UploadTexImagesLocked(imesa, imesa->CurrentTexObj[1]);
1295 if (imesa->dirty & I830_UPLOAD_CTX) {
1296 memcpy( imesa->sarea->ContextState,
1297 imesa->Setup, sizeof(imesa->Setup) );
1298 }
1299
1300 for (i = 0; i < I830_TEXTURE_COUNT; i++) {
1301 if ((imesa->dirty & I830_UPLOAD_TEX_N(i)) && imesa->CurrentTexObj[i]) {
1302 imesa->sarea->dirty |= I830_UPLOAD_TEX_N(i);
1303 memcpy(imesa->sarea->TexState[i],
1304 imesa->CurrentTexObj[i]->Setup,
1305 sizeof(imesa->sarea->TexState[i]));
1306
1307 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
1308 imesa->sarea->TexState[i][I830_TEXREG_TM0S3] |= imesa->LodBias[i];
1309
1310 /* Update the LRU usage */
1311 if (imesa->CurrentTexObj[i]->base.memBlock)
1312 driUpdateTextureLRU( (driTextureObject *)
1313 imesa->CurrentTexObj[i] );
1314 }
1315 }
1316 /* Need to figure out if texturing state, or enable changed. */
1317
1318 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1319 if (imesa->dirty & I830_UPLOAD_TEXBLEND_N(i)) {
1320 imesa->sarea->dirty |= I830_UPLOAD_TEXBLEND_N(i);
1321 memcpy(imesa->sarea->TexBlendState[i],imesa->TexBlend[i],
1322 imesa->TexBlendWordsUsed[i] * 4);
1323 imesa->sarea->TexBlendStateWordsUsed[i] =
1324 imesa->TexBlendWordsUsed[i];
1325 }
1326 }
1327
1328 if (imesa->dirty & I830_UPLOAD_BUFFERS) {
1329 memcpy( imesa->sarea->BufferState,imesa->BufferSetup,
1330 sizeof(imesa->BufferSetup) );
1331 }
1332
1333 if (imesa->dirty & I830_UPLOAD_STIPPLE) {
1334 memcpy( imesa->sarea->StippleState,imesa->StippleSetup,
1335 sizeof(imesa->StippleSetup) );
1336 }
1337
1338 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
1339 memcpy( imesa->sarea->Palette[0],imesa->palette,
1340 sizeof(imesa->sarea->Palette[0]));
1341 } else {
1342 i830TextureObjectPtr p;
1343 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
1344 p = imesa->CurrentTexObj[0];
1345 memcpy( imesa->sarea->Palette[0],p->palette,
1346 sizeof(imesa->sarea->Palette[0]));
1347 }
1348 if (imesa->dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
1349 p = imesa->CurrentTexObj[1];
1350 memcpy( imesa->sarea->Palette[1],
1351 p->palette,
1352 sizeof(imesa->sarea->Palette[1]));
1353 }
1354 }
1355
1356 imesa->sarea->dirty |= (imesa->dirty & ~(I830_UPLOAD_TEX_MASK |
1357 I830_UPLOAD_TEXBLEND_MASK));
1358
1359 imesa->upload_cliprects = GL_TRUE;
1360 imesa->dirty = 0;
1361 }
1362
1363
1364 void i830DDInitState( GLcontext *ctx )
1365 {
1366 i830ContextPtr imesa = I830_CONTEXT(ctx);
1367 i830ScreenPrivate *i830Screen = imesa->i830Screen;
1368 int i, j;
1369
1370 imesa->clear_red = 0;
1371 imesa->clear_green = 0;
1372 imesa->clear_blue = 0;
1373 imesa->clear_alpha = 0;
1374
1375 imesa->mask_red = GL_FALSE;
1376 imesa->mask_green = GL_FALSE;
1377 imesa->mask_blue = GL_FALSE;
1378 imesa->mask_alpha = GL_FALSE;
1379
1380 /* Zero all texture state */
1381 for (i = 0; i < I830_TEXBLEND_COUNT; i++) {
1382 for (j = 0; j < I830_TEXBLEND_SIZE; j++) {
1383 imesa->TexBlend[i][j] = 0;
1384 imesa->Init_TexBlend[i][j] = 0;
1385 }
1386 imesa->TexBlendWordsUsed[i] = 0;
1387 imesa->Init_TexBlendWordsUsed[i] = 0;
1388 imesa->TexBlendColorPipeNum[i] = 0;
1389 imesa->Init_TexBlendColorPipeNum[i] = 0;
1390 }
1391
1392 /* Set default blend state */
1393 imesa->TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1394 TEXPIPE_COLOR |
1395 ENABLE_TEXOUTPUT_WRT_SEL |
1396 TEXOP_OUTPUT_CURRENT |
1397 DISABLE_TEX_CNTRL_STAGE |
1398 TEXOP_SCALE_1X |
1399 TEXOP_MODIFY_PARMS |
1400 TEXOP_LAST_STAGE |
1401 TEXBLENDOP_ARG1);
1402 imesa->TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1403 TEXPIPE_ALPHA |
1404 ENABLE_TEXOUTPUT_WRT_SEL |
1405 TEXOP_OUTPUT_CURRENT |
1406 TEXOP_SCALE_1X |
1407 TEXOP_MODIFY_PARMS |
1408 TEXBLENDOP_ARG1);
1409 imesa->TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1410 TEXPIPE_COLOR |
1411 TEXBLEND_ARG1 |
1412 TEXBLENDARG_MODIFY_PARMS |
1413 TEXBLENDARG_DIFFUSE);
1414 imesa->TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1415 TEXPIPE_ALPHA |
1416 TEXBLEND_ARG1 |
1417 TEXBLENDARG_MODIFY_PARMS |
1418 TEXBLENDARG_DIFFUSE);
1419
1420 imesa->TexBlendWordsUsed[0] = 4;
1421 imesa->TexBlendColorPipeNum[0] = 0;
1422
1423 imesa->Init_TexBlend[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1424 TEXPIPE_COLOR |
1425 ENABLE_TEXOUTPUT_WRT_SEL |
1426 TEXOP_OUTPUT_CURRENT |
1427 DISABLE_TEX_CNTRL_STAGE |
1428 TEXOP_SCALE_1X |
1429 TEXOP_MODIFY_PARMS |
1430 TEXOP_LAST_STAGE |
1431 TEXBLENDOP_ARG1);
1432 imesa->Init_TexBlend[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1433 TEXPIPE_ALPHA |
1434 ENABLE_TEXOUTPUT_WRT_SEL |
1435 TEXOP_OUTPUT_CURRENT |
1436 TEXOP_SCALE_1X |
1437 TEXOP_MODIFY_PARMS |
1438 TEXBLENDOP_ARG1);
1439 imesa->Init_TexBlend[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1440 TEXPIPE_COLOR |
1441 TEXBLEND_ARG1 |
1442 TEXBLENDARG_MODIFY_PARMS |
1443 TEXBLENDARG_CURRENT);
1444 imesa->Init_TexBlend[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1445 TEXPIPE_ALPHA |
1446 TEXBLEND_ARG1 |
1447 TEXBLENDARG_MODIFY_PARMS |
1448 TEXBLENDARG_CURRENT);
1449 imesa->Init_TexBlendWordsUsed[0] = 4;
1450 imesa->Init_TexBlendColorPipeNum[0] = 0;
1451
1452 memset(imesa->Setup, 0, sizeof(imesa->Setup));
1453
1454 imesa->Setup[I830_CTXREG_VF] = 0;
1455 imesa->Setup[I830_CTXREG_VF2] = 0;
1456
1457 imesa->Setup[I830_CTXREG_AA] = (STATE3D_AA_CMD |
1458 AA_LINE_ECAAR_WIDTH_ENABLE |
1459 AA_LINE_ECAAR_WIDTH_1_0 |
1460 AA_LINE_REGION_WIDTH_ENABLE |
1461 AA_LINE_REGION_WIDTH_1_0 |
1462 AA_LINE_DISABLE);
1463
1464 imesa->Setup[I830_CTXREG_ENABLES_1] = (STATE3D_ENABLES_1_CMD |
1465 DISABLE_LOGIC_OP |
1466 DISABLE_STENCIL_TEST |
1467 DISABLE_DEPTH_BIAS |
1468 DISABLE_SPEC_ADD |
1469 I830_DISABLE_FOG |
1470 DISABLE_ALPHA_TEST |
1471 DISABLE_COLOR_BLEND |
1472 DISABLE_DEPTH_TEST);
1473
1474 if (imesa->hw_stencil) {
1475 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1476 ENABLE_STENCIL_WRITE |
1477 ENABLE_TEX_CACHE |
1478 ENABLE_DITHER |
1479 ENABLE_COLOR_MASK |
1480 /* set no color comps disabled */
1481 ENABLE_COLOR_WRITE |
1482 ENABLE_DEPTH_WRITE);
1483 } else {
1484 imesa->Setup[I830_CTXREG_ENABLES_2] = (STATE3D_ENABLES_2_CMD |
1485 DISABLE_STENCIL_WRITE |
1486 ENABLE_TEX_CACHE |
1487 ENABLE_DITHER |
1488 ENABLE_COLOR_MASK |
1489 /* set no color comps disabled */
1490 ENABLE_COLOR_WRITE |
1491 ENABLE_DEPTH_WRITE);
1492 }
1493
1494 imesa->Setup[I830_CTXREG_STATE1] = (STATE3D_MODES_1_CMD |
1495 ENABLE_COLR_BLND_FUNC |
1496 BLENDFUNC_ADD |
1497 ENABLE_SRC_BLND_FACTOR |
1498 SRC_BLND_FACT(BLENDFACT_ONE) |
1499 ENABLE_DST_BLND_FACTOR |
1500 DST_BLND_FACT(BLENDFACT_ZERO) );
1501
1502 imesa->Setup[I830_CTXREG_STATE2] = (STATE3D_MODES_2_CMD |
1503 ENABLE_GLOBAL_DEPTH_BIAS |
1504 GLOBAL_DEPTH_BIAS(0) |
1505 ENABLE_ALPHA_TEST_FUNC |
1506 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1507 ALPHA_REF_VALUE(0) );
1508
1509 imesa->Setup[I830_CTXREG_STATE3] = (STATE3D_MODES_3_CMD |
1510 ENABLE_DEPTH_TEST_FUNC |
1511 DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
1512 ENABLE_ALPHA_SHADE_MODE |
1513 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1514 ENABLE_FOG_SHADE_MODE |
1515 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1516 ENABLE_SPEC_SHADE_MODE |
1517 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1518 ENABLE_COLOR_SHADE_MODE |
1519 COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
1520 ENABLE_CULL_MODE |
1521 CULLMODE_NONE);
1522
1523 imesa->Setup[I830_CTXREG_STATE4] = (STATE3D_MODES_4_CMD |
1524 ENABLE_LOGIC_OP_FUNC |
1525 LOGIC_OP_FUNC(LOGICOP_COPY) |
1526 ENABLE_STENCIL_TEST_MASK |
1527 STENCIL_TEST_MASK(0xff) |
1528 ENABLE_STENCIL_WRITE_MASK |
1529 STENCIL_WRITE_MASK(0xff));
1530
1531 imesa->Setup[I830_CTXREG_STENCILTST] = (STATE3D_STENCIL_TEST_CMD |
1532 ENABLE_STENCIL_PARMS |
1533 STENCIL_FAIL_OP(STENCILOP_KEEP) |
1534 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
1535 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
1536 ENABLE_STENCIL_TEST_FUNC |
1537 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1538 ENABLE_STENCIL_REF_VALUE |
1539 STENCIL_REF_VALUE(0) );
1540
1541 imesa->Setup[I830_CTXREG_STATE5] = (STATE3D_MODES_5_CMD |
1542 FLUSH_TEXTURE_CACHE |
1543 ENABLE_SPRITE_POINT_TEX |
1544 SPRITE_POINT_TEX_OFF |
1545 ENABLE_FIXED_LINE_WIDTH |
1546 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1547 ENABLE_FIXED_POINT_WIDTH |
1548 FIXED_POINT_WIDTH(1) );
1549
1550 imesa->Setup[I830_CTXREG_IALPHAB] = (STATE3D_INDPT_ALPHA_BLEND_CMD |
1551 DISABLE_INDPT_ALPHA_BLEND |
1552 ENABLE_ALPHA_BLENDFUNC |
1553 ABLENDFUNC_ADD);
1554
1555 imesa->Setup[I830_CTXREG_FOGCOLOR] = (STATE3D_FOG_COLOR_CMD |
1556 FOG_COLOR_RED(0) |
1557 FOG_COLOR_GREEN(0) |
1558 FOG_COLOR_BLUE(0));
1559
1560 imesa->Setup[I830_CTXREG_BLENDCOLR0] = (STATE3D_CONST_BLEND_COLOR_CMD);
1561
1562 imesa->Setup[I830_CTXREG_BLENDCOLR] = 0;
1563
1564 imesa->Setup[I830_CTXREG_MCSB0] = STATE3D_MAP_COORD_SETBIND_CMD;
1565 imesa->Setup[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
1566 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
1567 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
1568 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
1569
1570 imesa->LcsCullMode = CULLMODE_CW; /* GL default */
1571
1572 memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
1573 memset(imesa->StippleSetup, 0, sizeof(imesa->StippleSetup));
1574
1575
1576 if (imesa->glCtx->Visual.doubleBufferMode &&
1577 imesa->sarea->pf_current_page == 0) {
1578 imesa->drawMap = i830Screen->back.map;
1579 imesa->readMap = i830Screen->back.map;
1580 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->backOffset;
1581 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1582 } else {
1583 /* use front buffer by default */
1584 imesa->drawMap = (char *)imesa->driScreen->pFB;
1585 imesa->readMap = (char *)imesa->driScreen->pFB;
1586 imesa->BufferSetup[I830_DESTREG_CBUFADDR] = i830Screen->fbOffset;
1587 imesa->BufferSetup[I830_DESTREG_DBUFADDR] = 0;
1588 }
1589
1590 imesa->BufferSetup[I830_DESTREG_DV0] = STATE3D_DST_BUF_VARS_CMD;
1591
1592 switch (i830Screen->fbFormat) {
1593 case DV_PF_555:
1594 case DV_PF_565:
1595 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1596 DSTORG_VERT_BIAS(0x8) | /* .5 */
1597 i830Screen->fbFormat |
1598 DEPTH_IS_Z |
1599 DEPTH_FRMT_16_FIXED);
1600 break;
1601 case DV_PF_8888:
1602 imesa->BufferSetup[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1603 DSTORG_VERT_BIAS(0x8) | /* .5 */
1604 i830Screen->fbFormat |
1605 DEPTH_IS_Z |
1606 DEPTH_FRMT_24_FIXED_8_OTHER);
1607 break;
1608 }
1609 imesa->BufferSetup[I830_DESTREG_SENABLE] = (STATE3D_SCISSOR_ENABLE_CMD |
1610 DISABLE_SCISSOR_RECT);
1611 imesa->BufferSetup[I830_DESTREG_SR0] = STATE3D_SCISSOR_RECT_0_CMD;
1612 imesa->BufferSetup[I830_DESTREG_SR1] = 0;
1613 imesa->BufferSetup[I830_DESTREG_SR2] = 0;
1614
1615 imesa->BufferSetup[I830_DESTREG_DR0] = STATE3D_DRAW_RECT_CMD;
1616 imesa->BufferSetup[I830_DESTREG_DR1] = 0;
1617 imesa->BufferSetup[I830_DESTREG_DR2] = 0;
1618 imesa->BufferSetup[I830_DESTREG_DR3] = (((i830Screen->height)<<16) |
1619 (i830Screen->width));
1620 imesa->BufferSetup[I830_DESTREG_DR4] = 0;
1621
1622 memcpy( imesa->Init_Setup,
1623 imesa->Setup,
1624 sizeof(imesa->Setup) );
1625 memcpy( imesa->Init_BufferSetup,
1626 imesa->BufferSetup,
1627 sizeof(imesa->BufferSetup) );
1628
1629 }
1630
1631 static void i830InvalidateState( GLcontext *ctx, GLuint new_state )
1632 {
1633 _swrast_InvalidateState( ctx, new_state );
1634 _swsetup_InvalidateState( ctx, new_state );
1635 _ac_InvalidateState( ctx, new_state );
1636 _tnl_InvalidateState( ctx, new_state );
1637 I830_CONTEXT(ctx)->NewGLState |= new_state;
1638 }
1639
1640 void i830DDInitStateFuncs(GLcontext *ctx)
1641 {
1642 /* Callbacks for internal Mesa events.
1643 */
1644 ctx->Driver.UpdateState = i830InvalidateState;
1645
1646 /* API callbacks
1647 */
1648 ctx->Driver.AlphaFunc = i830AlphaFunc;
1649 ctx->Driver.BlendEquationSeparate = i830BlendEquationSeparate;
1650 ctx->Driver.BlendFuncSeparate = i830BlendFuncSeparate;
1651 ctx->Driver.BlendColor = i830BlendColor;
1652 ctx->Driver.ClearColor = i830ClearColor;
1653 ctx->Driver.ColorMask = i830ColorMask;
1654 ctx->Driver.CullFace = i830CullFaceFrontFace;
1655 ctx->Driver.DepthFunc = i830DepthFunc;
1656 ctx->Driver.DepthMask = i830DepthMask;
1657 ctx->Driver.Enable = i830Enable;
1658 ctx->Driver.Fogfv = i830Fogfv;
1659 ctx->Driver.FrontFace = i830CullFaceFrontFace;
1660 ctx->Driver.LineWidth = i830LineWidth;
1661 ctx->Driver.PointSize = i830PointSize;
1662 ctx->Driver.LogicOpcode = i830LogicOp;
1663 ctx->Driver.PolygonStipple = i830PolygonStippleFallback;
1664 ctx->Driver.RenderMode = i830RenderMode;
1665 ctx->Driver.Scissor = i830Scissor;
1666 ctx->Driver.DrawBuffer = i830DrawBuffer;
1667 ctx->Driver.ReadBuffer = i830ReadBuffer;
1668 ctx->Driver.ShadeModel = i830ShadeModel;
1669 ctx->Driver.DepthRange = i830DepthRange;
1670 ctx->Driver.Viewport = i830Viewport;
1671 ctx->Driver.LightModelfv = i830LightModelfv;
1672
1673 ctx->Driver.StencilFunc = i830StencilFunc;
1674 ctx->Driver.StencilMask = i830StencilMask;
1675 ctx->Driver.StencilOp = i830StencilOp;
1676
1677 /* Pixel path fallbacks.
1678 */
1679 ctx->Driver.Accum = _swrast_Accum;
1680 ctx->Driver.Bitmap = _swrast_Bitmap;
1681 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1682 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1683 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1684
1685 /* Swrast hooks for imaging extensions:
1686 */
1687 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1688 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1689 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1690 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1691 }