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 i830BlendEquationSeparate(GLcontext
*ctx
,
363 GLenum modeRGB
, GLenum modeA
)
365 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
366 int func
= ENABLE_ALPHA_BLENDFUNC
;
368 if (I830_DEBUG
&DEBUG_DRI
)
369 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
370 _mesa_lookup_enum_by_nr(modeRGB
));
372 assert( modeRGB
== modeA
);
374 /* This will catch a logicop blend equation */
375 i830EvalLogicOpBlendState(ctx
);
378 case GL_FUNC_ADD_EXT
:
379 func
|= BLENDFUNC_ADD
;
382 func
|= BLENDFUNC_MIN
;
385 func
|= BLENDFUNC_MAX
;
387 case GL_FUNC_SUBTRACT_EXT
:
388 func
|= BLENDFUNC_SUB
;
390 case GL_FUNC_REVERSE_SUBTRACT_EXT
:
391 func
|= BLENDFUNC_RVRSE_SUB
;
396 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
397 imesa
->Setup
[I830_CTXREG_STATE1
] &= ~BLENDFUNC_MASK
;
398 imesa
->Setup
[I830_CTXREG_STATE1
] |= func
;
399 if (0) fprintf(stderr
, "%s : STATE1 : 0x%08x\n",
401 imesa
->Setup
[I830_CTXREG_STATE1
]);
404 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
405 GLenum dfactorRGB
, GLenum sfactorA
,
408 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
409 int funcA
= (ENABLE_SRC_ABLEND_FACTOR
|ENABLE_DST_ABLEND_FACTOR
);
410 int funcRGB
= (ENABLE_SRC_BLND_FACTOR
|ENABLE_DST_BLND_FACTOR
);
412 if (I830_DEBUG
&DEBUG_DRI
)
413 fprintf(stderr
, "%s\n", __FUNCTION__
);
417 funcA
|= SRC_ABLEND_FACT(BLENDFACT_ZERO
);
420 funcA
|= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA
);
423 funcA
|= SRC_ABLEND_FACT(BLENDFACT_ONE
);
426 funcA
|= SRC_ABLEND_FACT(BLENDFACT_DST_COLR
);
428 case GL_ONE_MINUS_DST_COLOR
:
429 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_DST_COLR
);
431 case GL_ONE_MINUS_SRC_ALPHA
:
432 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA
);
435 funcA
|= SRC_ABLEND_FACT(BLENDFACT_DST_ALPHA
);
437 case GL_ONE_MINUS_DST_ALPHA
:
438 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA
);
440 case GL_SRC_ALPHA_SATURATE
:
441 funcA
|= SRC_ABLEND_FACT(BLENDFACT_SRC_ALPHA_SATURATE
);
443 case GL_CONSTANT_COLOR_EXT
:
444 funcA
|= SRC_ABLEND_FACT(BLENDFACT_CONST_COLOR
);
446 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
447 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR
);
449 case GL_CONSTANT_ALPHA_EXT
:
450 funcA
|= SRC_ABLEND_FACT(BLENDFACT_CONST_ALPHA
);
452 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
453 funcA
|= SRC_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA
);
460 funcA
|= DST_ABLEND_FACT(BLENDFACT_SRC_ALPHA
);
462 case GL_ONE_MINUS_SRC_ALPHA
:
463 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_SRC_ALPHA
);
466 funcA
|= DST_ABLEND_FACT(BLENDFACT_ZERO
);
469 funcA
|= DST_ABLEND_FACT(BLENDFACT_ONE
);
472 funcA
|= DST_ABLEND_FACT(BLENDFACT_SRC_COLR
);
474 case GL_ONE_MINUS_SRC_COLOR
:
475 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_SRC_COLR
);
478 funcA
|= DST_ABLEND_FACT(BLENDFACT_DST_ALPHA
);
480 case GL_ONE_MINUS_DST_ALPHA
:
481 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_DST_ALPHA
);
483 case GL_CONSTANT_COLOR_EXT
:
484 funcA
|= DST_ABLEND_FACT(BLENDFACT_CONST_COLOR
);
486 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
487 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_CONST_COLOR
);
489 case GL_CONSTANT_ALPHA_EXT
:
490 funcA
|= DST_ABLEND_FACT(BLENDFACT_CONST_ALPHA
);
492 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
493 funcA
|= DST_ABLEND_FACT(BLENDFACT_INV_CONST_ALPHA
);
500 funcRGB
|= SRC_BLND_FACT(BLENDFACT_ZERO
);
503 funcRGB
|= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA
);
506 funcRGB
|= SRC_BLND_FACT(BLENDFACT_ONE
);
509 funcRGB
|= SRC_BLND_FACT(BLENDFACT_DST_COLR
);
511 case GL_ONE_MINUS_DST_COLOR
:
512 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_DST_COLR
);
514 case GL_ONE_MINUS_SRC_ALPHA
:
515 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_SRC_ALPHA
);
518 funcRGB
|= SRC_BLND_FACT(BLENDFACT_DST_ALPHA
);
520 case GL_ONE_MINUS_DST_ALPHA
:
521 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_DST_ALPHA
);
523 case GL_SRC_ALPHA_SATURATE
:
524 funcRGB
|= SRC_BLND_FACT(BLENDFACT_SRC_ALPHA_SATURATE
);
526 case GL_CONSTANT_COLOR_EXT
:
527 funcRGB
|= SRC_BLND_FACT(BLENDFACT_CONST_COLOR
);
529 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
530 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_CONST_COLOR
);
532 case GL_CONSTANT_ALPHA_EXT
:
533 funcRGB
|= SRC_BLND_FACT(BLENDFACT_CONST_ALPHA
);
535 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
536 funcRGB
|= SRC_BLND_FACT(BLENDFACT_INV_CONST_ALPHA
);
543 funcRGB
|= DST_BLND_FACT(BLENDFACT_SRC_ALPHA
);
545 case GL_ONE_MINUS_SRC_ALPHA
:
546 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_SRC_ALPHA
);
549 funcRGB
|= DST_BLND_FACT(BLENDFACT_ZERO
);
552 funcRGB
|= DST_BLND_FACT(BLENDFACT_ONE
);
555 funcRGB
|= DST_BLND_FACT(BLENDFACT_SRC_COLR
);
557 case GL_ONE_MINUS_SRC_COLOR
:
558 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_SRC_COLR
);
561 funcRGB
|= DST_BLND_FACT(BLENDFACT_DST_ALPHA
);
563 case GL_ONE_MINUS_DST_ALPHA
:
564 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_DST_ALPHA
);
566 case GL_CONSTANT_COLOR_EXT
:
567 funcRGB
|= DST_BLND_FACT(BLENDFACT_CONST_COLOR
);
569 case GL_ONE_MINUS_CONSTANT_COLOR_EXT
:
570 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_CONST_COLOR
);
572 case GL_CONSTANT_ALPHA_EXT
:
573 funcRGB
|= DST_BLND_FACT(BLENDFACT_CONST_ALPHA
);
575 case GL_ONE_MINUS_CONSTANT_ALPHA_EXT
:
576 funcRGB
|= DST_BLND_FACT(BLENDFACT_INV_CONST_ALPHA
);
581 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
582 imesa
->Setup
[I830_CTXREG_IALPHAB
] &= ~SRC_DST_ABLEND_MASK
;
583 imesa
->Setup
[I830_CTXREG_STATE1
] &= ~SRC_DST_BLND_MASK
;
584 imesa
->Setup
[I830_CTXREG_STATE1
] |= funcRGB
;
586 if ( (dfactorRGB
!= dfactorA
) || (sfactorRGB
!= sfactorA
) ) {
587 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= funcA
;
590 /* Ensure Independant Alpha Blend is really in the correct state (either
591 * enabled or disabled) if blending is already enabled.
593 i830EvalLogicOpBlendState(ctx
);
596 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
598 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
601 if (I830_DEBUG
&DEBUG_DRI
)
602 fprintf(stderr
, "%s\n", __FUNCTION__
);
606 test
= COMPAREFUNC_NEVER
;
609 test
= COMPAREFUNC_LESS
;
612 test
= COMPAREFUNC_LEQUAL
;
615 test
= COMPAREFUNC_GREATER
;
618 test
= COMPAREFUNC_GEQUAL
;
621 test
= COMPAREFUNC_NOTEQUAL
;
624 test
= COMPAREFUNC_EQUAL
;
627 test
= COMPAREFUNC_ALWAYS
;
632 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
633 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
634 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
635 DEPTH_TEST_FUNC(test
));
638 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
640 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
642 if (I830_DEBUG
&DEBUG_DRI
)
643 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
645 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
647 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
649 if (flag
&& ctx
->Depth
.Test
)
650 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
652 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
655 /* =============================================================
658 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
659 * Fortunately stipple is usually a repeating pattern.
661 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
663 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
664 const GLubyte
*m
= mask
;
667 int active
= (ctx
->Polygon
.StippleFlag
&&
668 imesa
->reduced_primitive
== GL_TRIANGLES
);
672 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
673 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
676 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
677 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
678 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
679 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
681 for (k
= 0 ; k
< 8 ; k
++)
682 for (j
= 3 ; j
>= 0; j
--)
683 for (i
= 0 ; i
< 4 ; i
++, m
++)
685 imesa
->hw_stipple
= 0;
689 newMask
= (((p
[0] & 0xf) << 0) |
690 ((p
[1] & 0xf) << 4) |
691 ((p
[2] & 0xf) << 8) |
692 ((p
[3] & 0xf) << 12));
695 if (newMask
== 0xffff || newMask
== 0x0) {
696 /* this is needed to make conform pass */
697 imesa
->hw_stipple
= 0;
701 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~0xffff;
702 imesa
->StippleSetup
[I830_STPREG_ST1
] |= newMask
;
703 imesa
->hw_stipple
= 1;
706 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
709 static void i830PolygonStippleFallback( GLcontext
*ctx
, const GLubyte
*mask
)
711 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
712 imesa
->hw_stipple
= 0;
713 (void) i830PolygonStipple
;
716 /* =============================================================
719 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
720 GLsizei w
, GLsizei h
)
722 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
724 int y1
= imesa
->driDrawable
->h
- (y
+ h
);
728 if (I830_DEBUG
&DEBUG_DRI
)
729 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
737 if (x2
>= imesa
->i830Screen
->width
) x2
= imesa
->i830Screen
->width
-1;
738 if (y2
>= imesa
->i830Screen
->height
) y2
= imesa
->i830Screen
->height
-1;
739 if (x1
>= imesa
->i830Screen
->width
) x1
= imesa
->i830Screen
->width
-1;
740 if (y1
>= imesa
->i830Screen
->height
) y1
= imesa
->i830Screen
->height
-1;
743 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
744 imesa
->BufferSetup
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
745 imesa
->BufferSetup
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
748 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
750 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
753 if (I830_DEBUG
&DEBUG_DRI
)
754 fprintf(stderr
, "%s\n", __FUNCTION__
);
756 /* FIXME: This should be a look-up table, like the r200 driver. */
765 tmp
= LOGICOP_AND_RVRSE
;
770 case GL_COPY_INVERTED
:
771 tmp
= LOGICOP_COPY_INV
;
773 case GL_AND_INVERTED
:
774 tmp
= LOGICOP_AND_INV
;
786 tmp
= LOGICOP_OR_INV
;
798 tmp
= LOGICOP_OR_RVRSE
;
810 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
811 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
812 imesa
->Setup
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
814 /* Make sure all the enables are correct */
815 i830EvalLogicOpBlendState(ctx
);
818 /* Fallback to swrast for select and feedback.
820 static void i830RenderMode( GLcontext
*ctx
, GLenum mode
)
822 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
823 FALLBACK( imesa
, I830_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
826 static void i830DrawBuffer(GLcontext
*ctx
, GLenum mode
)
828 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
831 * _DrawDestMask is easier to cope with than <mode>.
833 switch ( ctx
->Color
._DrawDestMask
) {
835 I830_FIREVERTICES(imesa
);
836 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
837 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = imesa
->i830Screen
->fbOffset
;
838 i830XMesaSetFrontClipRects( imesa
);
839 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
842 I830_FIREVERTICES(imesa
);
843 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
844 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] =
845 imesa
->i830Screen
->backOffset
;
846 i830XMesaSetBackClipRects( imesa
);
847 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
850 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
851 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
855 /* We want to update the s/w rast state too so that i830SetBuffer()
858 _swrast_DrawBuffer(ctx
, mode
);
861 static void i830ReadBuffer(GLcontext
*ctx
, GLenum mode
)
863 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
866 static void i830ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
868 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
870 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_red
, color
[0]);
871 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_green
, color
[1]);
872 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_blue
, color
[2]);
873 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_alpha
, color
[3]);
875 imesa
->ClearColor
= i830PackColor(imesa
->i830Screen
->fbFormat
,
882 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
884 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
885 GLuint mode
= CULLMODE_BOTH
;
887 if (I830_DEBUG
&DEBUG_DRI
)
888 fprintf(stderr
, "%s\n", __FUNCTION__
);
890 if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
893 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
894 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
895 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
896 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
899 imesa
->LcsCullMode
= mode
;
901 if (ctx
->Polygon
.CullFlag
) {
902 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
903 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
904 imesa
->Setup
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
908 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
910 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
913 if (I830_DEBUG
&DEBUG_DRI
)
914 fprintf(stderr
, "%s\n", __FUNCTION__
);
916 width
= FloatToInt(widthf
* 2);
917 CLAMP_SELF(width
, 1, 15);
919 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
920 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_LINE_WIDTH_MASK
;
921 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_LINE_WIDTH
|
922 FIXED_LINE_WIDTH(width
));
925 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
927 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
928 GLint point_size
= FloatToInt(size
);
930 if (I830_DEBUG
&DEBUG_DRI
)
931 fprintf(stderr
, "%s\n", __FUNCTION__
);
933 CLAMP_SELF(point_size
, 1, 256);
934 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
935 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
936 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
937 FIXED_POINT_WIDTH(point_size
));
941 /* =============================================================
945 static void i830ColorMask(GLcontext
*ctx
,
946 GLboolean r
, GLboolean g
,
947 GLboolean b
, GLboolean a
)
949 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
952 if (I830_DEBUG
&DEBUG_DRI
)
953 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
955 imesa
->mask_red
= !r
;
956 imesa
->mask_green
= !g
;
957 imesa
->mask_blue
= !b
;
958 imesa
->mask_alpha
= !a
;
960 tmp
= (imesa
->Setup
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
963 ((!r
) << WRITEMASK_RED_SHIFT
) |
964 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
965 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
966 ((!a
) << WRITEMASK_ALPHA_SHIFT
);
968 if (tmp
!= imesa
->Setup
[I830_CTXREG_ENABLES_2
]) {
969 I830_FIREVERTICES(imesa
);
970 imesa
->dirty
|= I830_UPLOAD_CTX
;
971 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = tmp
;
975 static void update_specular( GLcontext
*ctx
)
977 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
979 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
980 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
982 if (NEED_SECONDARY_COLOR(ctx
))
983 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
985 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
988 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
989 const GLfloat
*param
)
991 if (I830_DEBUG
&DEBUG_DRI
)
992 fprintf(stderr
, "%s\n", __FUNCTION__
);
994 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
995 update_specular( ctx
);
999 /* In Mesa 3.5 we can reliably do native flatshading.
1001 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
1003 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1004 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1007 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
1009 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
1011 if (mode
== GL_FLAT
) {
1012 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
1013 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
1014 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
1015 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
1017 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1018 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1019 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1020 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
1024 /* =============================================================
1027 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
1029 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1031 if (I830_DEBUG
&DEBUG_DRI
)
1032 fprintf(stderr
, "%s\n", __FUNCTION__
);
1034 if (pname
== GL_FOG_COLOR
) {
1035 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
1036 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
1037 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
1039 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1040 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
| color
);
1044 /* =============================================================
1047 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1049 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1053 case GL_COLOR_SUM_EXT
:
1054 update_specular( ctx
);
1058 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1059 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
1061 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
1063 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
1068 case GL_COLOR_LOGIC_OP
:
1069 case GL_INDEX_LOGIC_OP
:
1070 i830EvalLogicOpBlendState(ctx
);
1074 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1075 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
1078 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
1080 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
1084 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1085 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
1088 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
1090 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
1092 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1094 i830DepthMask( ctx
, state
);
1097 case GL_SCISSOR_TEST
:
1098 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
1101 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1102 (STATE3D_SCISSOR_ENABLE_CMD
|
1103 ENABLE_SCISSOR_RECT
);
1105 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1106 (STATE3D_SCISSOR_ENABLE_CMD
|
1107 DISABLE_SCISSOR_RECT
);
1109 imesa
->upload_cliprects
= GL_TRUE
;
1112 case GL_LINE_SMOOTH
:
1113 if (imesa
->reduced_primitive
== GL_LINES
) {
1114 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1116 imesa
->Setup
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
1118 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
1120 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
1125 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1126 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
1128 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_ENABLE_FOG
;
1130 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_DISABLE_FOG
;
1134 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1135 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
1137 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1138 imesa
->LcsCullMode
);
1140 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1145 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1146 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1149 case GL_STENCIL_TEST
:
1150 if (imesa
->hw_stencil
) {
1151 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1152 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
1153 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
1156 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
1157 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
1159 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
1160 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
1163 FALLBACK( imesa
, I830_FALLBACK_STENCIL
, state
);
1167 case GL_POLYGON_STIPPLE
:
1169 /* The stipple command worked on my 855GM box, but not my 845G.
1170 * I'll do more testing later to find out exactly which hardware
1171 * supports it. Disabled for now.
1173 if (imesa
->hw_stipple
&& imesa
->reduced_primitive
== GL_TRIANGLES
)
1175 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
1176 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
1178 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
1189 void i830EmitDrawingRectangle( i830ContextPtr imesa
)
1191 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1192 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1193 int x0
= imesa
->drawX
;
1194 int y0
= imesa
->drawY
;
1195 int x1
= x0
+ dPriv
->w
;
1196 int y1
= y0
+ dPriv
->h
;
1198 /* Don't set drawing rectangle */
1199 if (I830_DEBUG
& DEBUG_IOCTL
)
1200 fprintf(stderr
, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__
,
1203 /* Coordinate origin of the window - may be offscreen.
1205 imesa
->BufferSetup
[I830_DESTREG_DR4
] = ((y0
<<16) |
1206 (((unsigned)x0
)&0xFFFF));
1212 if (x1
> i830Screen
->width
-1) x1
= i830Screen
->width
-1;
1213 if (y1
> i830Screen
->height
-1) y1
= i830Screen
->height
-1;
1216 /* Onscreen drawing rectangle.
1218 imesa
->BufferSetup
[I830_DESTREG_DR2
] = ((y0
<<16) | x0
);
1219 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((y1
+1)<<16) | (x1
+1));
1222 /* Just add in our dirty flag, since we might be called when locked */
1223 /* Might want to modify how this is done. */
1224 imesa
->dirty
|= I830_UPLOAD_BUFFERS
;
1227 fprintf(stderr
, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1229 imesa
->BufferSetup
[I830_DESTREG_DR2
],
1230 imesa
->BufferSetup
[I830_DESTREG_DR3
],
1231 imesa
->BufferSetup
[I830_DESTREG_DR4
]);
1234 /* This could be done in hardware, will do once I have the driver
1237 static void i830CalcViewport( GLcontext
*ctx
)
1239 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1240 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1241 GLfloat
*m
= imesa
->ViewportMatrix
.m
;
1243 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1244 * via state vars, too.
1246 m
[MAT_SX
] = v
[MAT_SX
];
1247 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
1248 m
[MAT_SY
] = - v
[MAT_SY
];
1249 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ SUBPIXEL_Y
;
1250 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
1251 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
1254 static void i830Viewport( GLcontext
*ctx
,
1256 GLsizei width
, GLsizei height
)
1258 i830CalcViewport( ctx
);
1261 static void i830DepthRange( GLcontext
*ctx
,
1262 GLclampd nearval
, GLclampd farval
)
1264 i830CalcViewport( ctx
);
1267 void i830PrintDirty( const char *msg
, GLuint state
)
1269 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s%s\n",
1271 (unsigned int) state
,
1272 (state
& I830_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1273 (state
& I830_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1274 (state
& I830_UPLOAD_CTX
) ? "upload-ctx, " : "",
1275 (state
& I830_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1276 (state
& I830_UPLOAD_TEXBLEND0
) ? "upload-blend0, " : "",
1277 (state
& I830_UPLOAD_TEXBLEND1
) ? "upload-blend1, " : "",
1278 (state
& I830_UPLOAD_STIPPLE
) ? "stipple, " : ""
1282 /* Push the state into the sarea and/or texture memory.
1284 void i830EmitHwStateLocked( i830ContextPtr imesa
)
1288 if (I830_DEBUG
& DEBUG_STATE
)
1289 i830PrintDirty( __FUNCTION__
, imesa
->dirty
);
1291 if ((imesa
->dirty
& I830_UPLOAD_TEX0_IMAGE
) && imesa
->CurrentTexObj
[0])
1292 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[0]);
1293 if ((imesa
->dirty
& I830_UPLOAD_TEX1_IMAGE
) && imesa
->CurrentTexObj
[1])
1294 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[1]);
1295 if (imesa
->dirty
& I830_UPLOAD_CTX
) {
1296 memcpy( imesa
->sarea
->ContextState
,
1297 imesa
->Setup
, sizeof(imesa
->Setup
) );
1300 for (i
= 0; i
< I830_TEXTURE_COUNT
; i
++) {
1301 if ((imesa
->dirty
& I830_UPLOAD_TEX_N(i
)) && imesa
->CurrentTexObj
[i
]) {
1302 imesa
->sarea
->dirty
|= I830_UPLOAD_TEX_N(i
);
1303 memcpy(imesa
->sarea
->TexState
[i
],
1304 imesa
->CurrentTexObj
[i
]->Setup
,
1305 sizeof(imesa
->sarea
->TexState
[i
]));
1307 imesa
->sarea
->TexState
[i
][I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
1308 imesa
->sarea
->TexState
[i
][I830_TEXREG_TM0S3
] |= imesa
->LodBias
[i
];
1310 /* Update the LRU usage */
1311 if (imesa
->CurrentTexObj
[i
]->base
.memBlock
)
1312 driUpdateTextureLRU( (driTextureObject
*)
1313 imesa
->CurrentTexObj
[i
] );
1316 /* Need to figure out if texturing state, or enable changed. */
1318 for (i
= 0; i
< I830_TEXBLEND_COUNT
; i
++) {
1319 if (imesa
->dirty
& I830_UPLOAD_TEXBLEND_N(i
)) {
1320 imesa
->sarea
->dirty
|= I830_UPLOAD_TEXBLEND_N(i
);
1321 memcpy(imesa
->sarea
->TexBlendState
[i
],imesa
->TexBlend
[i
],
1322 imesa
->TexBlendWordsUsed
[i
] * 4);
1323 imesa
->sarea
->TexBlendStateWordsUsed
[i
] =
1324 imesa
->TexBlendWordsUsed
[i
];
1328 if (imesa
->dirty
& I830_UPLOAD_BUFFERS
) {
1329 memcpy( imesa
->sarea
->BufferState
,imesa
->BufferSetup
,
1330 sizeof(imesa
->BufferSetup
) );
1333 if (imesa
->dirty
& I830_UPLOAD_STIPPLE
) {
1334 memcpy( imesa
->sarea
->StippleState
,imesa
->StippleSetup
,
1335 sizeof(imesa
->StippleSetup
) );
1338 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_SHARED
) {
1339 memcpy( imesa
->sarea
->Palette
[0],imesa
->palette
,
1340 sizeof(imesa
->sarea
->Palette
[0]));
1342 i830TextureObjectPtr p
;
1343 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(0)) {
1344 p
= imesa
->CurrentTexObj
[0];
1345 memcpy( imesa
->sarea
->Palette
[0],p
->palette
,
1346 sizeof(imesa
->sarea
->Palette
[0]));
1348 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(1)) {
1349 p
= imesa
->CurrentTexObj
[1];
1350 memcpy( imesa
->sarea
->Palette
[1],
1352 sizeof(imesa
->sarea
->Palette
[1]));
1356 imesa
->sarea
->dirty
|= (imesa
->dirty
& ~(I830_UPLOAD_TEX_MASK
|
1357 I830_UPLOAD_TEXBLEND_MASK
));
1359 imesa
->upload_cliprects
= GL_TRUE
;
1364 void i830DDInitState( GLcontext
*ctx
)
1366 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1367 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1370 imesa
->clear_red
= 0;
1371 imesa
->clear_green
= 0;
1372 imesa
->clear_blue
= 0;
1373 imesa
->clear_alpha
= 0;
1375 imesa
->mask_red
= GL_FALSE
;
1376 imesa
->mask_green
= GL_FALSE
;
1377 imesa
->mask_blue
= GL_FALSE
;
1378 imesa
->mask_alpha
= GL_FALSE
;
1380 /* Zero all texture state */
1381 for (i
= 0; i
< I830_TEXBLEND_COUNT
; i
++) {
1382 for (j
= 0; j
< I830_TEXBLEND_SIZE
; j
++) {
1383 imesa
->TexBlend
[i
][j
] = 0;
1384 imesa
->Init_TexBlend
[i
][j
] = 0;
1386 imesa
->TexBlendWordsUsed
[i
] = 0;
1387 imesa
->Init_TexBlendWordsUsed
[i
] = 0;
1388 imesa
->TexBlendColorPipeNum
[i
] = 0;
1389 imesa
->Init_TexBlendColorPipeNum
[i
] = 0;
1392 /* Set default blend state */
1393 imesa
->TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1395 ENABLE_TEXOUTPUT_WRT_SEL
|
1396 TEXOP_OUTPUT_CURRENT
|
1397 DISABLE_TEX_CNTRL_STAGE
|
1399 TEXOP_MODIFY_PARMS
|
1402 imesa
->TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1404 ENABLE_TEXOUTPUT_WRT_SEL
|
1405 TEXOP_OUTPUT_CURRENT
|
1407 TEXOP_MODIFY_PARMS
|
1409 imesa
->TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1412 TEXBLENDARG_MODIFY_PARMS
|
1413 TEXBLENDARG_DIFFUSE
);
1414 imesa
->TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1417 TEXBLENDARG_MODIFY_PARMS
|
1418 TEXBLENDARG_DIFFUSE
);
1420 imesa
->TexBlendWordsUsed
[0] = 4;
1421 imesa
->TexBlendColorPipeNum
[0] = 0;
1423 imesa
->Init_TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1425 ENABLE_TEXOUTPUT_WRT_SEL
|
1426 TEXOP_OUTPUT_CURRENT
|
1427 DISABLE_TEX_CNTRL_STAGE
|
1429 TEXOP_MODIFY_PARMS
|
1432 imesa
->Init_TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1434 ENABLE_TEXOUTPUT_WRT_SEL
|
1435 TEXOP_OUTPUT_CURRENT
|
1437 TEXOP_MODIFY_PARMS
|
1439 imesa
->Init_TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1442 TEXBLENDARG_MODIFY_PARMS
|
1443 TEXBLENDARG_CURRENT
);
1444 imesa
->Init_TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1447 TEXBLENDARG_MODIFY_PARMS
|
1448 TEXBLENDARG_CURRENT
);
1449 imesa
->Init_TexBlendWordsUsed
[0] = 4;
1450 imesa
->Init_TexBlendColorPipeNum
[0] = 0;
1452 memset(imesa
->Setup
, 0, sizeof(imesa
->Setup
));
1454 imesa
->Setup
[I830_CTXREG_VF
] = 0;
1455 imesa
->Setup
[I830_CTXREG_VF2
] = 0;
1457 imesa
->Setup
[I830_CTXREG_AA
] = (STATE3D_AA_CMD
|
1458 AA_LINE_ECAAR_WIDTH_ENABLE
|
1459 AA_LINE_ECAAR_WIDTH_1_0
|
1460 AA_LINE_REGION_WIDTH_ENABLE
|
1461 AA_LINE_REGION_WIDTH_1_0
|
1464 imesa
->Setup
[I830_CTXREG_ENABLES_1
] = (STATE3D_ENABLES_1_CMD
|
1466 DISABLE_STENCIL_TEST
|
1467 DISABLE_DEPTH_BIAS
|
1470 DISABLE_ALPHA_TEST
|
1471 DISABLE_COLOR_BLEND
|
1472 DISABLE_DEPTH_TEST
);
1474 if (imesa
->hw_stencil
) {
1475 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1476 ENABLE_STENCIL_WRITE
|
1480 /* set no color comps disabled */
1481 ENABLE_COLOR_WRITE
|
1482 ENABLE_DEPTH_WRITE
);
1484 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1485 DISABLE_STENCIL_WRITE
|
1489 /* set no color comps disabled */
1490 ENABLE_COLOR_WRITE
|
1491 ENABLE_DEPTH_WRITE
);
1494 imesa
->Setup
[I830_CTXREG_STATE1
] = (STATE3D_MODES_1_CMD
|
1495 ENABLE_COLR_BLND_FUNC
|
1497 ENABLE_SRC_BLND_FACTOR
|
1498 SRC_BLND_FACT(BLENDFACT_ONE
) |
1499 ENABLE_DST_BLND_FACTOR
|
1500 DST_BLND_FACT(BLENDFACT_ZERO
) );
1502 imesa
->Setup
[I830_CTXREG_STATE2
] = (STATE3D_MODES_2_CMD
|
1503 ENABLE_GLOBAL_DEPTH_BIAS
|
1504 GLOBAL_DEPTH_BIAS(0) |
1505 ENABLE_ALPHA_TEST_FUNC
|
1506 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1507 ALPHA_REF_VALUE(0) );
1509 imesa
->Setup
[I830_CTXREG_STATE3
] = (STATE3D_MODES_3_CMD
|
1510 ENABLE_DEPTH_TEST_FUNC
|
1511 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1512 ENABLE_ALPHA_SHADE_MODE
|
1513 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1514 ENABLE_FOG_SHADE_MODE
|
1515 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1516 ENABLE_SPEC_SHADE_MODE
|
1517 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1518 ENABLE_COLOR_SHADE_MODE
|
1519 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1523 imesa
->Setup
[I830_CTXREG_STATE4
] = (STATE3D_MODES_4_CMD
|
1524 ENABLE_LOGIC_OP_FUNC
|
1525 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1526 ENABLE_STENCIL_TEST_MASK
|
1527 STENCIL_TEST_MASK(0xff) |
1528 ENABLE_STENCIL_WRITE_MASK
|
1529 STENCIL_WRITE_MASK(0xff));
1531 imesa
->Setup
[I830_CTXREG_STENCILTST
] = (STATE3D_STENCIL_TEST_CMD
|
1532 ENABLE_STENCIL_PARMS
|
1533 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1534 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1535 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1536 ENABLE_STENCIL_TEST_FUNC
|
1537 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1538 ENABLE_STENCIL_REF_VALUE
|
1539 STENCIL_REF_VALUE(0) );
1541 imesa
->Setup
[I830_CTXREG_STATE5
] = (STATE3D_MODES_5_CMD
|
1542 FLUSH_TEXTURE_CACHE
|
1543 ENABLE_SPRITE_POINT_TEX
|
1544 SPRITE_POINT_TEX_OFF
|
1545 ENABLE_FIXED_LINE_WIDTH
|
1546 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1547 ENABLE_FIXED_POINT_WIDTH
|
1548 FIXED_POINT_WIDTH(1) );
1550 imesa
->Setup
[I830_CTXREG_IALPHAB
] = (STATE3D_INDPT_ALPHA_BLEND_CMD
|
1551 DISABLE_INDPT_ALPHA_BLEND
|
1552 ENABLE_ALPHA_BLENDFUNC
|
1555 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
|
1557 FOG_COLOR_GREEN(0) |
1560 imesa
->Setup
[I830_CTXREG_BLENDCOLR0
] = (STATE3D_CONST_BLEND_COLOR_CMD
);
1562 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = 0;
1564 imesa
->Setup
[I830_CTXREG_MCSB0
] = STATE3D_MAP_COORD_SETBIND_CMD
;
1565 imesa
->Setup
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1566 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1567 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1568 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1570 imesa
->LcsCullMode
= CULLMODE_CW
; /* GL default */
1572 memset(imesa
->BufferSetup
, 0, sizeof(imesa
->BufferSetup
));
1573 memset(imesa
->StippleSetup
, 0, sizeof(imesa
->StippleSetup
));
1576 if (imesa
->glCtx
->Visual
.doubleBufferMode
&&
1577 imesa
->sarea
->pf_current_page
== 0) {
1578 imesa
->drawMap
= i830Screen
->back
.map
;
1579 imesa
->readMap
= i830Screen
->back
.map
;
1580 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
1581 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1583 /* use front buffer by default */
1584 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
1585 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
1586 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
1587 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1590 imesa
->BufferSetup
[I830_DESTREG_DV0
] = STATE3D_DST_BUF_VARS_CMD
;
1592 switch (i830Screen
->fbFormat
) {
1595 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1596 DSTORG_VERT_BIAS(0x8) | /* .5 */
1597 i830Screen
->fbFormat
|
1599 DEPTH_FRMT_16_FIXED
);
1602 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1603 DSTORG_VERT_BIAS(0x8) | /* .5 */
1604 i830Screen
->fbFormat
|
1606 DEPTH_FRMT_24_FIXED_8_OTHER
);
1609 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] = (STATE3D_SCISSOR_ENABLE_CMD
|
1610 DISABLE_SCISSOR_RECT
);
1611 imesa
->BufferSetup
[I830_DESTREG_SR0
] = STATE3D_SCISSOR_RECT_0_CMD
;
1612 imesa
->BufferSetup
[I830_DESTREG_SR1
] = 0;
1613 imesa
->BufferSetup
[I830_DESTREG_SR2
] = 0;
1615 imesa
->BufferSetup
[I830_DESTREG_DR0
] = STATE3D_DRAW_RECT_CMD
;
1616 imesa
->BufferSetup
[I830_DESTREG_DR1
] = 0;
1617 imesa
->BufferSetup
[I830_DESTREG_DR2
] = 0;
1618 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((i830Screen
->height
)<<16) |
1619 (i830Screen
->width
));
1620 imesa
->BufferSetup
[I830_DESTREG_DR4
] = 0;
1622 memcpy( imesa
->Init_Setup
,
1624 sizeof(imesa
->Setup
) );
1625 memcpy( imesa
->Init_BufferSetup
,
1627 sizeof(imesa
->BufferSetup
) );
1631 static void i830InvalidateState( GLcontext
*ctx
, GLuint new_state
)
1633 _swrast_InvalidateState( ctx
, new_state
);
1634 _swsetup_InvalidateState( ctx
, new_state
);
1635 _ac_InvalidateState( ctx
, new_state
);
1636 _tnl_InvalidateState( ctx
, new_state
);
1637 I830_CONTEXT(ctx
)->NewGLState
|= new_state
;
1640 void i830DDInitStateFuncs(GLcontext
*ctx
)
1642 /* Callbacks for internal Mesa events.
1644 ctx
->Driver
.UpdateState
= i830InvalidateState
;
1648 ctx
->Driver
.AlphaFunc
= i830AlphaFunc
;
1649 ctx
->Driver
.BlendEquationSeparate
= i830BlendEquationSeparate
;
1650 ctx
->Driver
.BlendFuncSeparate
= i830BlendFuncSeparate
;
1651 ctx
->Driver
.BlendColor
= i830BlendColor
;
1652 ctx
->Driver
.ClearColor
= i830ClearColor
;
1653 ctx
->Driver
.ColorMask
= i830ColorMask
;
1654 ctx
->Driver
.CullFace
= i830CullFaceFrontFace
;
1655 ctx
->Driver
.DepthFunc
= i830DepthFunc
;
1656 ctx
->Driver
.DepthMask
= i830DepthMask
;
1657 ctx
->Driver
.Enable
= i830Enable
;
1658 ctx
->Driver
.Fogfv
= i830Fogfv
;
1659 ctx
->Driver
.FrontFace
= i830CullFaceFrontFace
;
1660 ctx
->Driver
.LineWidth
= i830LineWidth
;
1661 ctx
->Driver
.PointSize
= i830PointSize
;
1662 ctx
->Driver
.LogicOpcode
= i830LogicOp
;
1663 ctx
->Driver
.PolygonStipple
= i830PolygonStippleFallback
;
1664 ctx
->Driver
.RenderMode
= i830RenderMode
;
1665 ctx
->Driver
.Scissor
= i830Scissor
;
1666 ctx
->Driver
.DrawBuffer
= i830DrawBuffer
;
1667 ctx
->Driver
.ReadBuffer
= i830ReadBuffer
;
1668 ctx
->Driver
.ShadeModel
= i830ShadeModel
;
1669 ctx
->Driver
.DepthRange
= i830DepthRange
;
1670 ctx
->Driver
.Viewport
= i830Viewport
;
1671 ctx
->Driver
.LightModelfv
= i830LightModelfv
;
1673 ctx
->Driver
.StencilFunc
= i830StencilFunc
;
1674 ctx
->Driver
.StencilMask
= i830StencilMask
;
1675 ctx
->Driver
.StencilOp
= i830StencilOp
;
1677 /* Pixel path fallbacks.
1679 ctx
->Driver
.Accum
= _swrast_Accum
;
1680 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1681 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1682 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1683 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1685 /* Swrast hooks for imaging extensions:
1687 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1688 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1689 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1690 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;