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