1 /**************************************************************************
3 Copyright 2001 2d3d Inc., Delray Beach, FL
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:
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
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.
26 **************************************************************************/
28 /* $XFree86: xc/lib/GL/mesa/src/drv/i830/i830_state.c,v 1.6 2003/01/28 22:47:06 dawes Exp $ */
32 * Jeff Hartmann <jhartmann@2d3d.com>
34 * Heavily based on the I810 driver, which was written by:
35 * Keith Whitwell <keith@tungstengraphics.com>
46 #include "i830_screen.h"
49 #include "i830_context.h"
50 #include "i830_state.h"
52 #include "i830_tris.h"
53 #include "i830_ioctl.h"
55 #include "swrast/swrast.h"
56 #include "array_cache/acache.h"
58 #include "swrast_setup/swrast_setup.h"
60 #include "tnl/t_pipeline.h"
62 static __inline__ GLuint
i830PackColor(GLuint format
,
67 if (I830_DEBUG
&DEBUG_DRI
)
68 fprintf(stderr
, "%s\n", __FUNCTION__
);
72 return I830PACKCOLOR1555(r
,g
,b
,a
);
74 return I830PACKCOLOR565(r
,g
,b
);
76 return I830PACKCOLOR8888(r
,g
,b
,a
);
78 fprintf(stderr
, "unknown format %d\n", (int)format
);
83 static void i830StencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
86 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
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
);
97 test
= COMPAREFUNC_NEVER
;
100 test
= COMPAREFUNC_LESS
;
103 test
= COMPAREFUNC_LEQUAL
;
106 test
= COMPAREFUNC_GREATER
;
109 test
= COMPAREFUNC_GEQUAL
;
112 test
= COMPAREFUNC_NOTEQUAL
;
115 test
= COMPAREFUNC_EQUAL
;
118 test
= COMPAREFUNC_ALWAYS
;
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
));
136 static void i830StencilMask(GLcontext
*ctx
, GLuint mask
)
138 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
140 if (I830_DEBUG
&DEBUG_DRI
)
141 fprintf(stderr
, "%s : mask 0x%x\n", __FUNCTION__
, mask
);
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
));
151 static void i830StencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
154 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
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
));
163 fop
= 0; dfop
= 0; dpop
= 0;
167 fop
= STENCILOP_KEEP
;
170 fop
= STENCILOP_ZERO
;
173 fop
= STENCILOP_REPLACE
;
176 fop
= STENCILOP_INCRSAT
;
179 fop
= STENCILOP_DECRSAT
;
182 fop
= STENCILOP_INCR
;
185 fop
= STENCILOP_DECR
;
188 fop
= STENCILOP_INVERT
;
195 dfop
= STENCILOP_KEEP
;
198 dfop
= STENCILOP_ZERO
;
201 dfop
= STENCILOP_REPLACE
;
204 dfop
= STENCILOP_INCRSAT
;
207 dfop
= STENCILOP_DECRSAT
;
210 dfop
= STENCILOP_INCR
;
213 dfop
= STENCILOP_DECR
;
216 dfop
= STENCILOP_INVERT
;
223 dpop
= STENCILOP_KEEP
;
226 dpop
= STENCILOP_ZERO
;
229 dpop
= STENCILOP_REPLACE
;
232 dpop
= STENCILOP_INCRSAT
;
235 dpop
= STENCILOP_DECRSAT
;
238 dpop
= STENCILOP_INCR
;
241 dpop
= STENCILOP_DECR
;
244 dpop
= STENCILOP_INVERT
;
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
));
259 static void i830AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
261 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
263 GLuint refByte
= (GLint
) (ref
* 255.0);
267 test
= COMPAREFUNC_NEVER
;
270 test
= COMPAREFUNC_LESS
;
273 test
= COMPAREFUNC_LEQUAL
;
276 test
= COMPAREFUNC_GREATER
;
279 test
= COMPAREFUNC_GEQUAL
;
282 test
= COMPAREFUNC_NOTEQUAL
;
285 test
= COMPAREFUNC_EQUAL
;
288 test
= COMPAREFUNC_ALWAYS
;
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
));
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
308 static void i830EvalLogicOpBlendState(GLcontext
*ctx
)
310 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
312 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
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
|
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
|
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
;
330 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
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
|
337 imesa
->Setup
[I830_CTXREG_IALPHAB
] &= ~ENABLE_INDPT_ALPHA_BLEND
;
338 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
342 static void i830BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
344 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
347 if (I830_DEBUG
&DEBUG_DRI
)
348 fprintf(stderr
, "%s\n", __FUNCTION__
);
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
]);
355 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
356 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = ((a
<< 24) |
362 static void i830BlendEquation(GLcontext
*ctx
, GLenum mode
)
364 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
365 int func
= ENABLE_ALPHA_BLENDFUNC
;
367 if (I830_DEBUG
&DEBUG_DRI
)
368 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
369 _mesa_lookup_enum_by_nr(mode
));
371 /* This will catch a logicop blend equation */
372 i830EvalLogicOpBlendState(ctx
);
375 case GL_FUNC_ADD_EXT
:
376 func
|= BLENDFUNC_ADD
;
379 func
|= BLENDFUNC_MIN
;
382 func
|= BLENDFUNC_MAX
;
384 case GL_FUNC_SUBTRACT_EXT
:
385 func
|= BLENDFUNC_SUB
;
387 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
388 func
|= BLENDFUNC_RVRSE_SUB
;
393 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
394 imesa
->Setup
[I830_CTXREG_STATE1
] &= ~BLENDFUNC_MASK
;
395 imesa
->Setup
[I830_CTXREG_STATE1
] |= func
;
396 if (0) fprintf(stderr
, "%s : STATE1 : 0x%08x\n",
398 imesa
->Setup
[I830_CTXREG_STATE1
]);
401 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
402 GLenum dfactorRGB
, GLenum sfactorA
,
405 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
406 int funcA
= (ENABLE_SRC_ABLEND_FACTOR
|ENABLE_DST_ABLEND_FACTOR
);
407 int funcRGB
= (ENABLE_SRC_BLND_FACTOR
|ENABLE_DST_BLND_FACTOR
);
409 if (I830_DEBUG
&DEBUG_DRI
)
410 fprintf(stderr
, "%s\n", __FUNCTION__
);
414 funcA
|= SRC_ABLEND_FACT(BLENDFACT_ZERO
);
417 funcA
|= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA
);
420 funcA
|= SRC_ABLEND_FACT(BLENDFACT_ONE
);
423 funcA
|= SRC_ABLEND_FACT(BLENDFACT_DST_COLR
);
425 case GL_ONE_MINUS_DST_COLOR
:
426 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_DST_COLR
);
428 case GL_ONE_MINUS_SRC_ALPHA
:
429 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA
);
432 funcA
|= SRC_ABLEND_FACT(BLENDFACT_DST_ALPHA
);
434 case GL_ONE_MINUS_DST_ALPHA
:
435 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA
);
437 case GL_SRC_ALPHA_SATURATE
:
438 funcA
|= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA_SATURATE
);
440 case GL_CONSTANT_COLOR_EXT
:
441 funcA
|= SRC_ABLEND_FACT(BLENDFACT_CONST_COLOR
);
443 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
444 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR
);
446 case GL_CONSTANT_ALPHA_EXT
:
447 funcA
|= SRC_ABLEND_FACT(BLENDFACT_CONST_ALPHA
);
449 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
450 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA
);
457 funcA
|= DST_ABLEND_FACT(BLENDFACT_SRC_ALPHA
);
459 case GL_ONE_MINUS_SRC_ALPHA
:
460 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA
);
463 funcA
|= DST_ABLEND_FACT(BLENDFACT_ZERO
);
466 funcA
|= DST_ABLEND_FACT(BLENDFACT_ONE
);
469 funcA
|= DST_ABLEND_FACT(BLENDFACT_SRC_COLR
);
471 case GL_ONE_MINUS_SRC_COLOR
:
472 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_SRC_COLR
);
475 funcA
|= DST_ABLEND_FACT(BLENDFACT_DST_ALPHA
);
477 case GL_ONE_MINUS_DST_ALPHA
:
478 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA
);
480 case GL_CONSTANT_COLOR_EXT
:
481 funcA
|= DST_ABLEND_FACT(BLENDFACT_CONST_COLOR
);
483 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
484 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR
);
486 case GL_CONSTANT_ALPHA_EXT
:
487 funcA
|= DST_ABLEND_FACT(BLENDFACT_CONST_ALPHA
);
489 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
490 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA
);
497 funcRGB
|= SRC_BLND_FACT(BLENDFACT_ZERO
);
500 funcRGB
|= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA
);
503 funcRGB
|= SRC_BLND_FACT(BLENDFACT_ONE
);
506 funcRGB
|= SRC_BLND_FACT(BLENDFACT_DST_COLR
);
508 case GL_ONE_MINUS_DST_COLOR
:
509 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR
);
511 case GL_ONE_MINUS_SRC_ALPHA
:
512 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA
);
515 funcRGB
|= SRC_BLND_FACT(BLENDFACT_DST_ALPHA
);
517 case GL_ONE_MINUS_DST_ALPHA
:
518 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA
);
520 case GL_SRC_ALPHA_SATURATE
:
521 funcRGB
|= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE
);
523 case GL_CONSTANT_COLOR_EXT
:
524 funcRGB
|= SRC_BLND_FACT(BLENDFACT_CONST_COLOR
);
526 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
527 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR
);
529 case GL_CONSTANT_ALPHA_EXT
:
530 funcRGB
|= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA
);
532 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
533 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA
);
540 funcRGB
|= DST_BLND_FACT(BLENDFACT_SRC_ALPHA
);
542 case GL_ONE_MINUS_SRC_ALPHA
:
543 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA
);
546 funcRGB
|= DST_BLND_FACT(BLENDFACT_ZERO
);
549 funcRGB
|= DST_BLND_FACT(BLENDFACT_ONE
);
552 funcRGB
|= DST_BLND_FACT(BLENDFACT_SRC_COLR
);
554 case GL_ONE_MINUS_SRC_COLOR
:
555 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR
);
558 funcRGB
|= DST_BLND_FACT(BLENDFACT_DST_ALPHA
);
560 case GL_ONE_MINUS_DST_ALPHA
:
561 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA
);
563 case GL_CONSTANT_COLOR_EXT
:
564 funcRGB
|= DST_BLND_FACT(BLENDFACT_CONST_COLOR
);
566 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
567 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR
);
569 case GL_CONSTANT_ALPHA_EXT
:
570 funcRGB
|= DST_BLND_FACT(BLENDFACT_CONST_ALPHA
);
572 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
573 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA
);
578 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
579 imesa
->Setup
[I830_CTXREG_IALPHAB
] &= ~SRC_DST_ABLEND_MASK
;
580 imesa
->Setup
[I830_CTXREG_STATE1
] &= ~SRC_DST_BLND_MASK
;
581 imesa
->Setup
[I830_CTXREG_STATE1
] |= funcRGB
;
583 if ( (dfactorRGB
!= dfactorA
) || (sfactorRGB
!= sfactorA
) ) {
584 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= funcA
;
587 /* Ensure Independant Alpha Blend is really in the correct state (either
588 * enabled or disabled) if blending is already enabled.
590 i830EvalLogicOpBlendState(ctx
);
593 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
595 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
598 if (I830_DEBUG
&DEBUG_DRI
)
599 fprintf(stderr
, "%s\n", __FUNCTION__
);
603 test
= COMPAREFUNC_NEVER
;
606 test
= COMPAREFUNC_LESS
;
609 test
= COMPAREFUNC_LEQUAL
;
612 test
= COMPAREFUNC_GREATER
;
615 test
= COMPAREFUNC_GEQUAL
;
618 test
= COMPAREFUNC_NOTEQUAL
;
621 test
= COMPAREFUNC_EQUAL
;
624 test
= COMPAREFUNC_ALWAYS
;
629 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
630 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
631 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
632 DEPTH_TEST_FUNC(test
));
635 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
637 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
639 if (I830_DEBUG
&DEBUG_DRI
)
640 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
642 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
644 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
646 if (flag
&& ctx
->Depth
.Test
)
647 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
649 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
652 /* =============================================================
655 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
656 * Fortunately stipple is usually a repeating pattern.
658 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
660 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
661 const GLubyte
*m
= mask
;
664 int active
= (ctx
->Polygon
.StippleFlag
&&
665 imesa
->reduced_primitive
== GL_TRIANGLES
);
669 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
670 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
673 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
674 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
675 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
676 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
678 for (k
= 0 ; k
< 8 ; k
++)
679 for (j
= 3 ; j
>= 0; j
--)
680 for (i
= 0 ; i
< 4 ; i
++, m
++)
682 imesa
->hw_stipple
= 0;
686 newMask
= (((p
[0] & 0xf) << 0) |
687 ((p
[1] & 0xf) << 4) |
688 ((p
[2] & 0xf) << 8) |
689 ((p
[3] & 0xf) << 12));
692 if (newMask
== 0xffff || newMask
== 0x0) {
693 /* this is needed to make conform pass */
694 imesa
->hw_stipple
= 0;
698 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~0xffff;
699 imesa
->StippleSetup
[I830_STPREG_ST1
] |= newMask
;
700 imesa
->hw_stipple
= 1;
703 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
706 static void i830PolygonStippleFallback( GLcontext
*ctx
, const GLubyte
*mask
)
708 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
709 imesa
->hw_stipple
= 0;
710 (void) i830PolygonStipple
;
713 /* =============================================================
716 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
717 GLsizei w
, GLsizei h
)
719 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
721 int y1
= imesa
->driDrawable
->h
- (y
+ h
);
725 if (I830_DEBUG
&DEBUG_DRI
)
726 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
734 if (x2
>= imesa
->i830Screen
->width
) x2
= imesa
->i830Screen
->width
-1;
735 if (y2
>= imesa
->i830Screen
->height
) y2
= imesa
->i830Screen
->height
-1;
736 if (x1
>= imesa
->i830Screen
->width
) x1
= imesa
->i830Screen
->width
-1;
737 if (y1
>= imesa
->i830Screen
->height
) y1
= imesa
->i830Screen
->height
-1;
740 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
741 imesa
->BufferSetup
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
742 imesa
->BufferSetup
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
745 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
747 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
750 if (I830_DEBUG
&DEBUG_DRI
)
751 fprintf(stderr
, "%s\n", __FUNCTION__
);
753 /* FIXME: This should be a look-up table, like the r200 driver. */
762 tmp
= LOGICOP_AND_RVRSE
;
767 case GL_COPY_INVERTED
:
768 tmp
= LOGICOP_COPY_INV
;
770 case GL_AND_INVERTED
:
771 tmp
= LOGICOP_AND_INV
;
783 tmp
= LOGICOP_OR_INV
;
795 tmp
= LOGICOP_OR_RVRSE
;
807 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
808 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
809 imesa
->Setup
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
811 /* Make sure all the enables are correct */
812 i830EvalLogicOpBlendState(ctx
);
815 /* Fallback to swrast for select and feedback.
817 static void i830RenderMode( GLcontext
*ctx
, GLenum mode
)
819 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
820 FALLBACK( imesa
, I830_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
823 static void i830DrawBuffer(GLcontext
*ctx
, GLenum mode
)
825 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
828 * _DrawDestMask is easier to cope with than <mode>.
830 switch ( ctx
->Color
._DrawDestMask
) {
832 I830_FIREVERTICES(imesa
);
833 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
834 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = imesa
->i830Screen
->fbOffset
;
835 i830XMesaSetFrontClipRects( imesa
);
836 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
839 I830_FIREVERTICES(imesa
);
840 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
841 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] =
842 imesa
->i830Screen
->backOffset
;
843 i830XMesaSetBackClipRects( imesa
);
844 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
847 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
848 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
852 /* We want to update the s/w rast state too so that i830SetBuffer()
855 _swrast_DrawBuffer(ctx
, mode
);
858 static void i830ReadBuffer(GLcontext
*ctx
, GLenum mode
)
860 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
863 static void i830ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
865 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
867 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_red
, color
[0]);
868 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_green
, color
[1]);
869 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_blue
, color
[2]);
870 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_alpha
, color
[3]);
872 imesa
->ClearColor
= i830PackColor(imesa
->i830Screen
->fbFormat
,
879 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
881 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
882 GLuint mode
= CULLMODE_BOTH
;
884 if (I830_DEBUG
&DEBUG_DRI
)
885 fprintf(stderr
, "%s\n", __FUNCTION__
);
887 if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
890 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
891 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
892 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
893 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
896 imesa
->LcsCullMode
= mode
;
898 if (ctx
->Polygon
.CullFlag
) {
899 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
900 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
901 imesa
->Setup
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
905 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
907 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
910 if (I830_DEBUG
&DEBUG_DRI
)
911 fprintf(stderr
, "%s\n", __FUNCTION__
);
913 width
= FloatToInt(widthf
* 2);
914 CLAMP_SELF(width
, 1, 15);
916 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
917 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_LINE_WIDTH_MASK
;
918 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_LINE_WIDTH
|
919 FIXED_LINE_WIDTH(width
));
922 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
924 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
925 GLint point_size
= FloatToInt(size
);
927 if (I830_DEBUG
&DEBUG_DRI
)
928 fprintf(stderr
, "%s\n", __FUNCTION__
);
930 CLAMP_SELF(point_size
, 1, 256);
931 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
932 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
933 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
934 FIXED_POINT_WIDTH(point_size
));
938 /* =============================================================
942 static void i830ColorMask(GLcontext
*ctx
,
943 GLboolean r
, GLboolean g
,
944 GLboolean b
, GLboolean a
)
946 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
949 if (I830_DEBUG
&DEBUG_DRI
)
950 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
952 imesa
->mask_red
= !r
;
953 imesa
->mask_green
= !g
;
954 imesa
->mask_blue
= !b
;
955 imesa
->mask_alpha
= !a
;
957 tmp
= (imesa
->Setup
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
960 ((!r
) << WRITEMASK_RED_SHIFT
) |
961 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
962 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
963 ((!a
) << WRITEMASK_ALPHA_SHIFT
);
965 if (tmp
!= imesa
->Setup
[I830_CTXREG_ENABLES_2
]) {
966 I830_FIREVERTICES(imesa
);
967 imesa
->dirty
|= I830_UPLOAD_CTX
;
968 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = tmp
;
972 static void update_specular( GLcontext
*ctx
)
974 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
976 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
977 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
979 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
980 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
982 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
985 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
986 const GLfloat
*param
)
988 if (I830_DEBUG
&DEBUG_DRI
)
989 fprintf(stderr
, "%s\n", __FUNCTION__
);
991 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
992 update_specular( ctx
);
996 /* In Mesa 3.5 we can reliably do native flatshading.
998 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
1000 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1001 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1004 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
1006 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
1008 if (mode
== GL_FLAT
) {
1009 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
1010 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
1011 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
1012 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
1014 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1015 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1016 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1017 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
1021 /* =============================================================
1024 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
1026 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1028 if (I830_DEBUG
&DEBUG_DRI
)
1029 fprintf(stderr
, "%s\n", __FUNCTION__
);
1031 if (pname
== GL_FOG_COLOR
) {
1032 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
1033 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
1034 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
1036 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1037 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
| color
);
1041 /* =============================================================
1044 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1046 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1050 case GL_COLOR_SUM_EXT
:
1051 update_specular( ctx
);
1055 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1056 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
1058 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
1060 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
1065 case GL_COLOR_LOGIC_OP
:
1066 case GL_INDEX_LOGIC_OP
:
1067 i830EvalLogicOpBlendState(ctx
);
1071 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1072 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
1075 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
1077 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
1081 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1082 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
1085 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
1087 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
1089 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1091 i830DepthMask( ctx
, state
);
1094 case GL_SCISSOR_TEST
:
1095 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
1098 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1099 (STATE3D_SCISSOR_ENABLE_CMD
|
1100 ENABLE_SCISSOR_RECT
);
1102 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1103 (STATE3D_SCISSOR_ENABLE_CMD
|
1104 DISABLE_SCISSOR_RECT
);
1106 imesa
->upload_cliprects
= GL_TRUE
;
1109 case GL_LINE_SMOOTH
:
1110 if (imesa
->reduced_primitive
== GL_LINES
) {
1111 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1113 imesa
->Setup
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
1115 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
1117 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
1122 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1123 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
1125 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_ENABLE_FOG
;
1127 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_DISABLE_FOG
;
1131 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1132 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
1134 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1135 imesa
->LcsCullMode
);
1137 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1142 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1143 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1146 case GL_STENCIL_TEST
:
1147 if (imesa
->hw_stencil
) {
1148 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1149 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
1150 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
1153 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
1154 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
1156 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
1157 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
1160 FALLBACK( imesa
, I830_FALLBACK_STENCIL
, state
);
1164 case GL_POLYGON_STIPPLE
:
1166 /* The stipple command worked on my 855GM box, but not my 845G.
1167 * I'll do more testing later to find out exactly which hardware
1168 * supports it. Disabled for now.
1170 if (imesa
->hw_stipple
&& imesa
->reduced_primitive
== GL_TRIANGLES
)
1172 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
1173 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
1175 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
1186 void i830EmitDrawingRectangle( i830ContextPtr imesa
)
1188 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1189 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1190 int x0
= imesa
->drawX
;
1191 int y0
= imesa
->drawY
;
1192 int x1
= x0
+ dPriv
->w
;
1193 int y1
= y0
+ dPriv
->h
;
1195 /* Don't set drawing rectangle */
1196 if (I830_DEBUG
& DEBUG_IOCTL
)
1197 fprintf(stderr
, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__
,
1200 /* Coordinate origin of the window - may be offscreen.
1202 imesa
->BufferSetup
[I830_DESTREG_DR4
] = ((y0
<<16) |
1203 (((unsigned)x0
)&0xFFFF));
1209 if (x1
> i830Screen
->width
-1) x1
= i830Screen
->width
-1;
1210 if (y1
> i830Screen
->height
-1) y1
= i830Screen
->height
-1;
1213 /* Onscreen drawing rectangle.
1215 imesa
->BufferSetup
[I830_DESTREG_DR2
] = ((y0
<<16) | x0
);
1216 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((y1
+1)<<16) | (x1
+1));
1219 /* Just add in our dirty flag, since we might be called when locked */
1220 /* Might want to modify how this is done. */
1221 imesa
->dirty
|= I830_UPLOAD_BUFFERS
;
1224 fprintf(stderr
, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1226 imesa
->BufferSetup
[I830_DESTREG_DR2
],
1227 imesa
->BufferSetup
[I830_DESTREG_DR3
],
1228 imesa
->BufferSetup
[I830_DESTREG_DR4
]);
1231 /* This could be done in hardware, will do once I have the driver
1234 static void i830CalcViewport( GLcontext
*ctx
)
1236 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1237 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1238 GLfloat
*m
= imesa
->ViewportMatrix
.m
;
1240 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1241 * via state vars, too.
1243 m
[MAT_SX
] = v
[MAT_SX
];
1244 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
1245 m
[MAT_SY
] = - v
[MAT_SY
];
1246 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ SUBPIXEL_Y
;
1247 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
1248 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
1251 static void i830Viewport( GLcontext
*ctx
,
1253 GLsizei width
, GLsizei height
)
1255 i830CalcViewport( ctx
);
1258 static void i830DepthRange( GLcontext
*ctx
,
1259 GLclampd nearval
, GLclampd farval
)
1261 i830CalcViewport( ctx
);
1264 void i830PrintDirty( const char *msg
, GLuint state
)
1266 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s%s\n",
1268 (unsigned int) state
,
1269 (state
& I830_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1270 (state
& I830_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1271 (state
& I830_UPLOAD_CTX
) ? "upload-ctx, " : "",
1272 (state
& I830_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1273 (state
& I830_UPLOAD_TEXBLEND0
) ? "upload-blend0, " : "",
1274 (state
& I830_UPLOAD_TEXBLEND1
) ? "upload-blend1, " : "",
1275 (state
& I830_UPLOAD_STIPPLE
) ? "stipple, " : ""
1279 /* Push the state into the sarea and/or texture memory.
1281 void i830EmitHwStateLocked( i830ContextPtr imesa
)
1285 if (I830_DEBUG
& DEBUG_STATE
)
1286 i830PrintDirty( __FUNCTION__
, imesa
->dirty
);
1288 if ((imesa
->dirty
& I830_UPLOAD_TEX0_IMAGE
) && imesa
->CurrentTexObj
[0])
1289 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[0]);
1290 if ((imesa
->dirty
& I830_UPLOAD_TEX1_IMAGE
) && imesa
->CurrentTexObj
[1])
1291 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[1]);
1292 if (imesa
->dirty
& I830_UPLOAD_CTX
) {
1293 memcpy( imesa
->sarea
->ContextState
,
1294 imesa
->Setup
, sizeof(imesa
->Setup
) );
1297 for (i
= 0; i
< I830_TEXTURE_COUNT
; i
++) {
1298 if ((imesa
->dirty
& I830_UPLOAD_TEX_N(i
)) && imesa
->CurrentTexObj
[i
]) {
1299 imesa
->sarea
->dirty
|= I830_UPLOAD_TEX_N(i
);
1300 memcpy(imesa
->sarea
->TexState
[i
],
1301 imesa
->CurrentTexObj
[i
]->Setup
,
1302 sizeof(imesa
->sarea
->TexState
[i
]));
1304 imesa
->sarea
->TexState
[i
][I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
1305 imesa
->sarea
->TexState
[i
][I830_TEXREG_TM0S3
] |= imesa
->LodBias
[i
];
1307 /* Update the LRU usage */
1308 if (imesa
->CurrentTexObj
[i
]->base
.memBlock
)
1309 driUpdateTextureLRU( (driTextureObject
*)
1310 imesa
->CurrentTexObj
[i
] );
1313 /* Need to figure out if texturing state, or enable changed. */
1315 for (i
= 0; i
< I830_TEXBLEND_COUNT
; i
++) {
1316 if (imesa
->dirty
& I830_UPLOAD_TEXBLEND_N(i
)) {
1317 imesa
->sarea
->dirty
|= I830_UPLOAD_TEXBLEND_N(i
);
1318 memcpy(imesa
->sarea
->TexBlendState
[i
],imesa
->TexBlend
[i
],
1319 imesa
->TexBlendWordsUsed
[i
] * 4);
1320 imesa
->sarea
->TexBlendStateWordsUsed
[i
] =
1321 imesa
->TexBlendWordsUsed
[i
];
1325 if (imesa
->dirty
& I830_UPLOAD_BUFFERS
) {
1326 memcpy( imesa
->sarea
->BufferState
,imesa
->BufferSetup
,
1327 sizeof(imesa
->BufferSetup
) );
1330 if (imesa
->dirty
& I830_UPLOAD_STIPPLE
) {
1331 memcpy( imesa
->sarea
->StippleState
,imesa
->StippleSetup
,
1332 sizeof(imesa
->StippleSetup
) );
1335 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_SHARED
) {
1336 memcpy( imesa
->sarea
->Palette
[0],imesa
->palette
,
1337 sizeof(imesa
->sarea
->Palette
[0]));
1339 i830TextureObjectPtr p
;
1340 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(0)) {
1341 p
= imesa
->CurrentTexObj
[0];
1342 memcpy( imesa
->sarea
->Palette
[0],p
->palette
,
1343 sizeof(imesa
->sarea
->Palette
[0]));
1345 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(1)) {
1346 p
= imesa
->CurrentTexObj
[1];
1347 memcpy( imesa
->sarea
->Palette
[1],
1349 sizeof(imesa
->sarea
->Palette
[1]));
1353 imesa
->sarea
->dirty
|= (imesa
->dirty
& ~(I830_UPLOAD_TEX_MASK
|
1354 I830_UPLOAD_TEXBLEND_MASK
));
1356 imesa
->upload_cliprects
= GL_TRUE
;
1361 void i830DDInitState( GLcontext
*ctx
)
1363 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1364 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1367 imesa
->clear_red
= 0;
1368 imesa
->clear_green
= 0;
1369 imesa
->clear_blue
= 0;
1370 imesa
->clear_alpha
= 0;
1372 imesa
->mask_red
= GL_FALSE
;
1373 imesa
->mask_green
= GL_FALSE
;
1374 imesa
->mask_blue
= GL_FALSE
;
1375 imesa
->mask_alpha
= GL_FALSE
;
1377 /* Zero all texture state */
1378 for (i
= 0; i
< I830_TEXBLEND_COUNT
; i
++) {
1379 for (j
= 0; j
< I830_TEXBLEND_SIZE
; j
++) {
1380 imesa
->TexBlend
[i
][j
] = 0;
1381 imesa
->Init_TexBlend
[i
][j
] = 0;
1383 imesa
->TexBlendWordsUsed
[i
] = 0;
1384 imesa
->Init_TexBlendWordsUsed
[i
] = 0;
1385 imesa
->TexBlendColorPipeNum
[i
] = 0;
1386 imesa
->Init_TexBlendColorPipeNum
[i
] = 0;
1389 /* Set default blend state */
1390 imesa
->TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1392 ENABLE_TEXOUTPUT_WRT_SEL
|
1393 TEXOP_OUTPUT_CURRENT
|
1394 DISABLE_TEX_CNTRL_STAGE
|
1396 TEXOP_MODIFY_PARMS
|
1399 imesa
->TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1401 ENABLE_TEXOUTPUT_WRT_SEL
|
1402 TEXOP_OUTPUT_CURRENT
|
1404 TEXOP_MODIFY_PARMS
|
1406 imesa
->TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1409 TEXBLENDARG_MODIFY_PARMS
|
1410 TEXBLENDARG_DIFFUSE
);
1411 imesa
->TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1414 TEXBLENDARG_MODIFY_PARMS
|
1415 TEXBLENDARG_DIFFUSE
);
1417 imesa
->TexBlendWordsUsed
[0] = 4;
1418 imesa
->TexBlendColorPipeNum
[0] = 0;
1420 imesa
->Init_TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1422 ENABLE_TEXOUTPUT_WRT_SEL
|
1423 TEXOP_OUTPUT_CURRENT
|
1424 DISABLE_TEX_CNTRL_STAGE
|
1426 TEXOP_MODIFY_PARMS
|
1429 imesa
->Init_TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1431 ENABLE_TEXOUTPUT_WRT_SEL
|
1432 TEXOP_OUTPUT_CURRENT
|
1434 TEXOP_MODIFY_PARMS
|
1436 imesa
->Init_TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1439 TEXBLENDARG_MODIFY_PARMS
|
1440 TEXBLENDARG_CURRENT
);
1441 imesa
->Init_TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1444 TEXBLENDARG_MODIFY_PARMS
|
1445 TEXBLENDARG_CURRENT
);
1446 imesa
->Init_TexBlendWordsUsed
[0] = 4;
1447 imesa
->Init_TexBlendColorPipeNum
[0] = 0;
1449 memset(imesa
->Setup
, 0, sizeof(imesa
->Setup
));
1451 imesa
->Setup
[I830_CTXREG_VF
] = 0;
1452 imesa
->Setup
[I830_CTXREG_VF2
] = 0;
1454 imesa
->Setup
[I830_CTXREG_AA
] = (STATE3D_AA_CMD
|
1455 AA_LINE_ECAAR_WIDTH_ENABLE
|
1456 AA_LINE_ECAAR_WIDTH_1_0
|
1457 AA_LINE_REGION_WIDTH_ENABLE
|
1458 AA_LINE_REGION_WIDTH_1_0
|
1461 imesa
->Setup
[I830_CTXREG_ENABLES_1
] = (STATE3D_ENABLES_1_CMD
|
1463 DISABLE_STENCIL_TEST
|
1464 DISABLE_DEPTH_BIAS
|
1467 DISABLE_ALPHA_TEST
|
1468 DISABLE_COLOR_BLEND
|
1469 DISABLE_DEPTH_TEST
);
1471 if (imesa
->hw_stencil
) {
1472 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1473 ENABLE_STENCIL_WRITE
|
1477 /* set no color comps disabled */
1478 ENABLE_COLOR_WRITE
|
1479 ENABLE_DEPTH_WRITE
);
1481 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1482 DISABLE_STENCIL_WRITE
|
1486 /* set no color comps disabled */
1487 ENABLE_COLOR_WRITE
|
1488 ENABLE_DEPTH_WRITE
);
1491 imesa
->Setup
[I830_CTXREG_STATE1
] = (STATE3D_MODES_1_CMD
|
1492 ENABLE_COLR_BLND_FUNC
|
1494 ENABLE_SRC_BLND_FACTOR
|
1495 SRC_BLND_FACT(BLENDFACT_ONE
) |
1496 ENABLE_DST_BLND_FACTOR
|
1497 DST_BLND_FACT(BLENDFACT_ZERO
) );
1499 imesa
->Setup
[I830_CTXREG_STATE2
] = (STATE3D_MODES_2_CMD
|
1500 ENABLE_GLOBAL_DEPTH_BIAS
|
1501 GLOBAL_DEPTH_BIAS(0) |
1502 ENABLE_ALPHA_TEST_FUNC
|
1503 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1504 ALPHA_REF_VALUE(0) );
1506 imesa
->Setup
[I830_CTXREG_STATE3
] = (STATE3D_MODES_3_CMD
|
1507 ENABLE_DEPTH_TEST_FUNC
|
1508 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1509 ENABLE_ALPHA_SHADE_MODE
|
1510 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1511 ENABLE_FOG_SHADE_MODE
|
1512 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1513 ENABLE_SPEC_SHADE_MODE
|
1514 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1515 ENABLE_COLOR_SHADE_MODE
|
1516 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1520 imesa
->Setup
[I830_CTXREG_STATE4
] = (STATE3D_MODES_4_CMD
|
1521 ENABLE_LOGIC_OP_FUNC
|
1522 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1523 ENABLE_STENCIL_TEST_MASK
|
1524 STENCIL_TEST_MASK(0xff) |
1525 ENABLE_STENCIL_WRITE_MASK
|
1526 STENCIL_WRITE_MASK(0xff));
1528 imesa
->Setup
[I830_CTXREG_STENCILTST
] = (STATE3D_STENCIL_TEST_CMD
|
1529 ENABLE_STENCIL_PARMS
|
1530 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1531 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1532 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1533 ENABLE_STENCIL_TEST_FUNC
|
1534 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1535 ENABLE_STENCIL_REF_VALUE
|
1536 STENCIL_REF_VALUE(0) );
1538 imesa
->Setup
[I830_CTXREG_STATE5
] = (STATE3D_MODES_5_CMD
|
1539 FLUSH_TEXTURE_CACHE
|
1540 ENABLE_SPRITE_POINT_TEX
|
1541 SPRITE_POINT_TEX_OFF
|
1542 ENABLE_FIXED_LINE_WIDTH
|
1543 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1544 ENABLE_FIXED_POINT_WIDTH
|
1545 FIXED_POINT_WIDTH(1) );
1547 imesa
->Setup
[I830_CTXREG_IALPHAB
] = (STATE3D_INDPT_ALPHA_BLEND_CMD
|
1548 DISABLE_INDPT_ALPHA_BLEND
|
1549 ENABLE_ALPHA_BLENDFUNC
|
1552 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
|
1554 FOG_COLOR_GREEN(0) |
1557 imesa
->Setup
[I830_CTXREG_BLENDCOLR0
] = (STATE3D_CONST_BLEND_COLOR_CMD
);
1559 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = 0;
1561 imesa
->Setup
[I830_CTXREG_MCSB0
] = STATE3D_MAP_COORD_SETBIND_CMD
;
1562 imesa
->Setup
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1563 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1564 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1565 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1567 imesa
->LcsCullMode
= CULLMODE_CW
; /* GL default */
1569 memset(imesa
->BufferSetup
, 0, sizeof(imesa
->BufferSetup
));
1570 memset(imesa
->StippleSetup
, 0, sizeof(imesa
->StippleSetup
));
1573 if (imesa
->glCtx
->Visual
.doubleBufferMode
&&
1574 imesa
->sarea
->pf_current_page
== 0) {
1575 imesa
->drawMap
= i830Screen
->back
.map
;
1576 imesa
->readMap
= i830Screen
->back
.map
;
1577 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
1578 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1580 /* use front buffer by default */
1581 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
1582 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
1583 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
1584 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1587 imesa
->BufferSetup
[I830_DESTREG_DV0
] = STATE3D_DST_BUF_VARS_CMD
;
1589 switch (i830Screen
->fbFormat
) {
1592 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1593 DSTORG_VERT_BIAS(0x8) | /* .5 */
1594 i830Screen
->fbFormat
|
1596 DEPTH_FRMT_16_FIXED
);
1599 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1600 DSTORG_VERT_BIAS(0x8) | /* .5 */
1601 i830Screen
->fbFormat
|
1603 DEPTH_FRMT_24_FIXED_8_OTHER
);
1606 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] = (STATE3D_SCISSOR_ENABLE_CMD
|
1607 DISABLE_SCISSOR_RECT
);
1608 imesa
->BufferSetup
[I830_DESTREG_SR0
] = STATE3D_SCISSOR_RECT_0_CMD
;
1609 imesa
->BufferSetup
[I830_DESTREG_SR1
] = 0;
1610 imesa
->BufferSetup
[I830_DESTREG_SR2
] = 0;
1612 imesa
->BufferSetup
[I830_DESTREG_DR0
] = STATE3D_DRAW_RECT_CMD
;
1613 imesa
->BufferSetup
[I830_DESTREG_DR1
] = 0;
1614 imesa
->BufferSetup
[I830_DESTREG_DR2
] = 0;
1615 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((i830Screen
->height
)<<16) |
1616 (i830Screen
->width
));
1617 imesa
->BufferSetup
[I830_DESTREG_DR4
] = 0;
1619 memcpy( imesa
->Init_Setup
,
1621 sizeof(imesa
->Setup
) );
1622 memcpy( imesa
->Init_BufferSetup
,
1624 sizeof(imesa
->BufferSetup
) );
1628 static void i830InvalidateState( GLcontext
*ctx
, GLuint new_state
)
1630 _swrast_InvalidateState( ctx
, new_state
);
1631 _swsetup_InvalidateState( ctx
, new_state
);
1632 _ac_InvalidateState( ctx
, new_state
);
1633 _tnl_InvalidateState( ctx
, new_state
);
1634 I830_CONTEXT(ctx
)->NewGLState
|= new_state
;
1637 void i830DDInitStateFuncs(GLcontext
*ctx
)
1639 /* Callbacks for internal Mesa events.
1641 ctx
->Driver
.UpdateState
= i830InvalidateState
;
1645 ctx
->Driver
.AlphaFunc
= i830AlphaFunc
;
1646 ctx
->Driver
.BlendEquation
= i830BlendEquation
;
1647 ctx
->Driver
.BlendFuncSeparate
= i830BlendFuncSeparate
;
1648 ctx
->Driver
.BlendColor
= i830BlendColor
;
1649 ctx
->Driver
.ClearColor
= i830ClearColor
;
1650 ctx
->Driver
.ColorMask
= i830ColorMask
;
1651 ctx
->Driver
.CullFace
= i830CullFaceFrontFace
;
1652 ctx
->Driver
.DepthFunc
= i830DepthFunc
;
1653 ctx
->Driver
.DepthMask
= i830DepthMask
;
1654 ctx
->Driver
.Enable
= i830Enable
;
1655 ctx
->Driver
.Fogfv
= i830Fogfv
;
1656 ctx
->Driver
.FrontFace
= i830CullFaceFrontFace
;
1657 ctx
->Driver
.LineWidth
= i830LineWidth
;
1658 ctx
->Driver
.PointSize
= i830PointSize
;
1659 ctx
->Driver
.LogicOpcode
= i830LogicOp
;
1660 ctx
->Driver
.PolygonStipple
= i830PolygonStippleFallback
;
1661 ctx
->Driver
.RenderMode
= i830RenderMode
;
1662 ctx
->Driver
.Scissor
= i830Scissor
;
1663 ctx
->Driver
.DrawBuffer
= i830DrawBuffer
;
1664 ctx
->Driver
.ReadBuffer
= i830ReadBuffer
;
1665 ctx
->Driver
.ShadeModel
= i830ShadeModel
;
1666 ctx
->Driver
.DepthRange
= i830DepthRange
;
1667 ctx
->Driver
.Viewport
= i830Viewport
;
1668 ctx
->Driver
.LightModelfv
= i830LightModelfv
;
1670 ctx
->Driver
.StencilFunc
= i830StencilFunc
;
1671 ctx
->Driver
.StencilMask
= i830StencilMask
;
1672 ctx
->Driver
.StencilOp
= i830StencilOp
;
1674 /* Pixel path fallbacks.
1676 ctx
->Driver
.Accum
= _swrast_Accum
;
1677 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1678 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1679 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1680 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1682 /* Swrast hooks for imaging extensions:
1684 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1685 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1686 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1687 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;