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
) {
834 case DD_FRONT_LEFT_BIT
:
835 I830_FIREVERTICES(imesa
);
836 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
837 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = imesa
->i830Screen
->fbOffset
;
838 i830XMesaSetFrontClipRects( imesa
);
839 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
841 case DD_BACK_LEFT_BIT
:
842 I830_FIREVERTICES(imesa
);
843 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
844 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] =
845 imesa
->i830Screen
->backOffset
;
846 i830XMesaSetBackClipRects( imesa
);
847 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
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%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_TEX2
) ? "upload-tex2, " : "",
1275 (state
& I830_UPLOAD_TEX3
) ? "upload-tex3, " : "",
1276 (state
& I830_UPLOAD_CTX
) ? "upload-ctx, " : "",
1277 (state
& I830_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1278 (state
& I830_UPLOAD_TEXBLEND0
) ? "upload-blend0, " : "",
1279 (state
& I830_UPLOAD_TEXBLEND1
) ? "upload-blend1, " : "",
1280 (state
& I830_UPLOAD_TEXBLEND2
) ? "upload-blend2, " : "",
1281 (state
& I830_UPLOAD_TEXBLEND3
) ? "upload-blend3, " : "",
1282 (state
& I830_UPLOAD_STIPPLE
) ? "stipple, " : ""
1286 /* Push the state into the sarea and/or texture memory.
1288 void i830EmitHwStateLocked( i830ContextPtr imesa
)
1292 if (I830_DEBUG
& DEBUG_STATE
)
1293 i830PrintDirty( __FUNCTION__
, imesa
->dirty
);
1295 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1296 if ( ((imesa
->dirty
& I830_UPLOAD_TEX_N_IMAGE( i
)) != 0)
1297 && (imesa
->CurrentTexObj
[i
] != NULL
) ) {
1298 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[i
]);
1302 if (imesa
->dirty
& I830_UPLOAD_CTX
) {
1303 memcpy( imesa
->sarea
->ContextState
,
1304 imesa
->Setup
, sizeof(imesa
->Setup
) );
1307 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1308 if ((imesa
->dirty
& I830_UPLOAD_TEX_N(i
)) && imesa
->CurrentTexObj
[i
]) {
1309 unsigned * TexState
;
1311 imesa
->sarea
->dirty
|= I830_UPLOAD_TEX_N(i
);
1316 TexState
= imesa
->sarea
->TexState
[i
];
1320 TexState
= imesa
->sarea
->TexState2
;
1324 TexState
= imesa
->sarea
->TexState3
;
1328 memcpy(TexState
, imesa
->CurrentTexObj
[i
]->Setup
,
1329 sizeof(imesa
->sarea
->TexState
[i
]));
1331 TexState
[I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
1332 TexState
[I830_TEXREG_TM0S3
] |= imesa
->LodBias
[i
];
1334 /* Update the LRU usage */
1335 if (imesa
->CurrentTexObj
[i
]->base
.memBlock
)
1336 driUpdateTextureLRU( (driTextureObject
*)
1337 imesa
->CurrentTexObj
[i
] );
1340 /* Need to figure out if texturing state, or enable changed. */
1342 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1343 if (imesa
->dirty
& I830_UPLOAD_TEXBLEND_N(i
)) {
1344 unsigned * TexBlendState
;
1345 unsigned * words_used
;
1347 imesa
->sarea
->dirty
|= I830_UPLOAD_TEXBLEND_N(i
);
1352 TexBlendState
= imesa
->sarea
->TexBlendState
[i
];
1353 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed
[i
];
1357 TexBlendState
= imesa
->sarea
->TexBlendState2
;
1358 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed2
;
1362 TexBlendState
= imesa
->sarea
->TexBlendState3
;
1363 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed3
;
1367 memcpy(TexBlendState
, imesa
->TexBlend
[i
],
1368 imesa
->TexBlendWordsUsed
[i
] * 4);
1369 *words_used
= imesa
->TexBlendWordsUsed
[i
];
1373 if (imesa
->dirty
& I830_UPLOAD_BUFFERS
) {
1374 memcpy( imesa
->sarea
->BufferState
,imesa
->BufferSetup
,
1375 sizeof(imesa
->BufferSetup
) );
1378 if (imesa
->dirty
& I830_UPLOAD_STIPPLE
) {
1379 memcpy( imesa
->sarea
->StippleState
,imesa
->StippleSetup
,
1380 sizeof(imesa
->StippleSetup
) );
1383 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_SHARED
) {
1384 memcpy( imesa
->sarea
->Palette
[0],imesa
->palette
,
1385 sizeof(imesa
->sarea
->Palette
[0]));
1387 i830TextureObjectPtr p
;
1388 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(0)) {
1389 p
= imesa
->CurrentTexObj
[0];
1390 memcpy( imesa
->sarea
->Palette
[0],p
->palette
,
1391 sizeof(imesa
->sarea
->Palette
[0]));
1393 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(1)) {
1394 p
= imesa
->CurrentTexObj
[1];
1395 memcpy( imesa
->sarea
->Palette
[1],
1397 sizeof(imesa
->sarea
->Palette
[1]));
1401 imesa
->sarea
->dirty
|= (imesa
->dirty
& ~(I830_UPLOAD_TEX_MASK
|
1402 I830_UPLOAD_TEXBLEND_MASK
));
1404 imesa
->upload_cliprects
= GL_TRUE
;
1409 void i830DDInitState( GLcontext
*ctx
)
1411 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1412 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1415 imesa
->clear_red
= 0;
1416 imesa
->clear_green
= 0;
1417 imesa
->clear_blue
= 0;
1418 imesa
->clear_alpha
= 0;
1420 imesa
->mask_red
= GL_FALSE
;
1421 imesa
->mask_green
= GL_FALSE
;
1422 imesa
->mask_blue
= GL_FALSE
;
1423 imesa
->mask_alpha
= GL_FALSE
;
1425 /* Zero all texture state */
1426 for (i
= 0; i
< I830_MAX_TEXTURE_UNITS
; i
++) {
1427 (void) memset( imesa
->TexBlend
[i
], 0, sizeof( imesa
->TexBlend
[i
] ) );
1428 (void) memset( imesa
->Init_TexBlend
[i
], 0, sizeof( imesa
->Init_TexBlend
[i
] ) );
1430 imesa
->TexBlendWordsUsed
[i
] = 0;
1431 imesa
->Init_TexBlendWordsUsed
[i
] = 0;
1432 imesa
->TexBlendColorPipeNum
[i
] = 0;
1433 imesa
->Init_TexBlendColorPipeNum
[i
] = 0;
1436 /* Set default blend state */
1437 imesa
->TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1439 ENABLE_TEXOUTPUT_WRT_SEL
|
1440 TEXOP_OUTPUT_CURRENT
|
1441 DISABLE_TEX_CNTRL_STAGE
|
1443 TEXOP_MODIFY_PARMS
|
1446 imesa
->TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1448 ENABLE_TEXOUTPUT_WRT_SEL
|
1449 TEXOP_OUTPUT_CURRENT
|
1451 TEXOP_MODIFY_PARMS
|
1453 imesa
->TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1456 TEXBLENDARG_MODIFY_PARMS
|
1457 TEXBLENDARG_DIFFUSE
);
1458 imesa
->TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1461 TEXBLENDARG_MODIFY_PARMS
|
1462 TEXBLENDARG_DIFFUSE
);
1464 imesa
->TexBlendWordsUsed
[0] = 4;
1465 imesa
->TexBlendColorPipeNum
[0] = 0;
1467 imesa
->Init_TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1469 ENABLE_TEXOUTPUT_WRT_SEL
|
1470 TEXOP_OUTPUT_CURRENT
|
1471 DISABLE_TEX_CNTRL_STAGE
|
1473 TEXOP_MODIFY_PARMS
|
1476 imesa
->Init_TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1478 ENABLE_TEXOUTPUT_WRT_SEL
|
1479 TEXOP_OUTPUT_CURRENT
|
1481 TEXOP_MODIFY_PARMS
|
1483 imesa
->Init_TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1486 TEXBLENDARG_MODIFY_PARMS
|
1487 TEXBLENDARG_CURRENT
);
1488 imesa
->Init_TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1491 TEXBLENDARG_MODIFY_PARMS
|
1492 TEXBLENDARG_CURRENT
);
1493 imesa
->Init_TexBlendWordsUsed
[0] = 4;
1494 imesa
->Init_TexBlendColorPipeNum
[0] = 0;
1496 memset(imesa
->Setup
, 0, sizeof(imesa
->Setup
));
1498 imesa
->Setup
[I830_CTXREG_VF
] = 0;
1499 imesa
->Setup
[I830_CTXREG_VF2
] = 0;
1501 imesa
->Setup
[I830_CTXREG_AA
] = (STATE3D_AA_CMD
|
1502 AA_LINE_ECAAR_WIDTH_ENABLE
|
1503 AA_LINE_ECAAR_WIDTH_1_0
|
1504 AA_LINE_REGION_WIDTH_ENABLE
|
1505 AA_LINE_REGION_WIDTH_1_0
|
1508 imesa
->Setup
[I830_CTXREG_ENABLES_1
] = (STATE3D_ENABLES_1_CMD
|
1510 DISABLE_STENCIL_TEST
|
1511 DISABLE_DEPTH_BIAS
|
1514 DISABLE_ALPHA_TEST
|
1515 DISABLE_COLOR_BLEND
|
1516 DISABLE_DEPTH_TEST
);
1518 if (imesa
->hw_stencil
) {
1519 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1520 ENABLE_STENCIL_WRITE
|
1524 /* set no color comps disabled */
1525 ENABLE_COLOR_WRITE
|
1526 ENABLE_DEPTH_WRITE
);
1528 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1529 DISABLE_STENCIL_WRITE
|
1533 /* set no color comps disabled */
1534 ENABLE_COLOR_WRITE
|
1535 ENABLE_DEPTH_WRITE
);
1538 imesa
->Setup
[I830_CTXREG_STATE1
] = (STATE3D_MODES_1_CMD
|
1539 ENABLE_COLR_BLND_FUNC
|
1541 ENABLE_SRC_BLND_FACTOR
|
1542 SRC_BLND_FACT(BLENDFACT_ONE
) |
1543 ENABLE_DST_BLND_FACTOR
|
1544 DST_BLND_FACT(BLENDFACT_ZERO
) );
1546 imesa
->Setup
[I830_CTXREG_STATE2
] = (STATE3D_MODES_2_CMD
|
1547 ENABLE_GLOBAL_DEPTH_BIAS
|
1548 GLOBAL_DEPTH_BIAS(0) |
1549 ENABLE_ALPHA_TEST_FUNC
|
1550 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1551 ALPHA_REF_VALUE(0) );
1553 imesa
->Setup
[I830_CTXREG_STATE3
] = (STATE3D_MODES_3_CMD
|
1554 ENABLE_DEPTH_TEST_FUNC
|
1555 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1556 ENABLE_ALPHA_SHADE_MODE
|
1557 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1558 ENABLE_FOG_SHADE_MODE
|
1559 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1560 ENABLE_SPEC_SHADE_MODE
|
1561 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1562 ENABLE_COLOR_SHADE_MODE
|
1563 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1567 imesa
->Setup
[I830_CTXREG_STATE4
] = (STATE3D_MODES_4_CMD
|
1568 ENABLE_LOGIC_OP_FUNC
|
1569 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1570 ENABLE_STENCIL_TEST_MASK
|
1571 STENCIL_TEST_MASK(0xff) |
1572 ENABLE_STENCIL_WRITE_MASK
|
1573 STENCIL_WRITE_MASK(0xff));
1575 imesa
->Setup
[I830_CTXREG_STENCILTST
] = (STATE3D_STENCIL_TEST_CMD
|
1576 ENABLE_STENCIL_PARMS
|
1577 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1578 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1579 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1580 ENABLE_STENCIL_TEST_FUNC
|
1581 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1582 ENABLE_STENCIL_REF_VALUE
|
1583 STENCIL_REF_VALUE(0) );
1585 imesa
->Setup
[I830_CTXREG_STATE5
] = (STATE3D_MODES_5_CMD
|
1586 FLUSH_TEXTURE_CACHE
|
1587 ENABLE_SPRITE_POINT_TEX
|
1588 SPRITE_POINT_TEX_OFF
|
1589 ENABLE_FIXED_LINE_WIDTH
|
1590 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1591 ENABLE_FIXED_POINT_WIDTH
|
1592 FIXED_POINT_WIDTH(1) );
1594 imesa
->Setup
[I830_CTXREG_IALPHAB
] = (STATE3D_INDPT_ALPHA_BLEND_CMD
|
1595 DISABLE_INDPT_ALPHA_BLEND
|
1596 ENABLE_ALPHA_BLENDFUNC
|
1599 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
|
1601 FOG_COLOR_GREEN(0) |
1604 imesa
->Setup
[I830_CTXREG_BLENDCOLR0
] = (STATE3D_CONST_BLEND_COLOR_CMD
);
1606 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = 0;
1608 imesa
->Setup
[I830_CTXREG_MCSB0
] = STATE3D_MAP_COORD_SETBIND_CMD
;
1609 imesa
->Setup
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1610 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1611 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1612 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1614 imesa
->LcsCullMode
= CULLMODE_CW
; /* GL default */
1616 memset(imesa
->BufferSetup
, 0, sizeof(imesa
->BufferSetup
));
1617 memset(imesa
->StippleSetup
, 0, sizeof(imesa
->StippleSetup
));
1620 if (imesa
->glCtx
->Visual
.doubleBufferMode
&&
1621 imesa
->sarea
->pf_current_page
== 0) {
1622 imesa
->drawMap
= i830Screen
->back
.map
;
1623 imesa
->readMap
= i830Screen
->back
.map
;
1624 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
1625 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1627 /* use front buffer by default */
1628 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
1629 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
1630 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
1631 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1634 imesa
->BufferSetup
[I830_DESTREG_DV0
] = STATE3D_DST_BUF_VARS_CMD
;
1636 switch (i830Screen
->fbFormat
) {
1639 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1640 DSTORG_VERT_BIAS(0x8) | /* .5 */
1641 i830Screen
->fbFormat
|
1643 DEPTH_FRMT_16_FIXED
);
1646 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1647 DSTORG_VERT_BIAS(0x8) | /* .5 */
1648 i830Screen
->fbFormat
|
1650 DEPTH_FRMT_24_FIXED_8_OTHER
);
1653 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] = (STATE3D_SCISSOR_ENABLE_CMD
|
1654 DISABLE_SCISSOR_RECT
);
1655 imesa
->BufferSetup
[I830_DESTREG_SR0
] = STATE3D_SCISSOR_RECT_0_CMD
;
1656 imesa
->BufferSetup
[I830_DESTREG_SR1
] = 0;
1657 imesa
->BufferSetup
[I830_DESTREG_SR2
] = 0;
1659 imesa
->BufferSetup
[I830_DESTREG_DR0
] = STATE3D_DRAW_RECT_CMD
;
1660 imesa
->BufferSetup
[I830_DESTREG_DR1
] = 0;
1661 imesa
->BufferSetup
[I830_DESTREG_DR2
] = 0;
1662 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((i830Screen
->height
)<<16) |
1663 (i830Screen
->width
));
1664 imesa
->BufferSetup
[I830_DESTREG_DR4
] = 0;
1666 memcpy( imesa
->Init_Setup
,
1668 sizeof(imesa
->Setup
) );
1669 memcpy( imesa
->Init_BufferSetup
,
1671 sizeof(imesa
->BufferSetup
) );
1675 static void i830InvalidateState( GLcontext
*ctx
, GLuint new_state
)
1677 _swrast_InvalidateState( ctx
, new_state
);
1678 _swsetup_InvalidateState( ctx
, new_state
);
1679 _ac_InvalidateState( ctx
, new_state
);
1680 _tnl_InvalidateState( ctx
, new_state
);
1681 I830_CONTEXT(ctx
)->NewGLState
|= new_state
;
1684 void i830DDInitStateFuncs(GLcontext
*ctx
)
1686 /* Callbacks for internal Mesa events.
1688 ctx
->Driver
.UpdateState
= i830InvalidateState
;
1692 ctx
->Driver
.AlphaFunc
= i830AlphaFunc
;
1693 ctx
->Driver
.BlendEquationSeparate
= i830BlendEquationSeparate
;
1694 ctx
->Driver
.BlendFuncSeparate
= i830BlendFuncSeparate
;
1695 ctx
->Driver
.BlendColor
= i830BlendColor
;
1696 ctx
->Driver
.ClearColor
= i830ClearColor
;
1697 ctx
->Driver
.ColorMask
= i830ColorMask
;
1698 ctx
->Driver
.CullFace
= i830CullFaceFrontFace
;
1699 ctx
->Driver
.DepthFunc
= i830DepthFunc
;
1700 ctx
->Driver
.DepthMask
= i830DepthMask
;
1701 ctx
->Driver
.Enable
= i830Enable
;
1702 ctx
->Driver
.Fogfv
= i830Fogfv
;
1703 ctx
->Driver
.FrontFace
= i830CullFaceFrontFace
;
1704 ctx
->Driver
.LineWidth
= i830LineWidth
;
1705 ctx
->Driver
.PointSize
= i830PointSize
;
1706 ctx
->Driver
.LogicOpcode
= i830LogicOp
;
1707 ctx
->Driver
.PolygonStipple
= i830PolygonStippleFallback
;
1708 ctx
->Driver
.RenderMode
= i830RenderMode
;
1709 ctx
->Driver
.Scissor
= i830Scissor
;
1710 ctx
->Driver
.DrawBuffer
= i830DrawBuffer
;
1711 ctx
->Driver
.ReadBuffer
= i830ReadBuffer
;
1712 ctx
->Driver
.ShadeModel
= i830ShadeModel
;
1713 ctx
->Driver
.DepthRange
= i830DepthRange
;
1714 ctx
->Driver
.Viewport
= i830Viewport
;
1715 ctx
->Driver
.LightModelfv
= i830LightModelfv
;
1717 ctx
->Driver
.StencilFunc
= i830StencilFunc
;
1718 ctx
->Driver
.StencilMask
= i830StencilMask
;
1719 ctx
->Driver
.StencilOp
= i830StencilOp
;
1721 /* Pixel path fallbacks.
1723 ctx
->Driver
.Accum
= _swrast_Accum
;
1724 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1725 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1726 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1727 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1729 /* Swrast hooks for imaging extensions:
1731 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1732 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1733 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1734 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;