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>
47 #include "i830_screen.h"
50 #include "i830_context.h"
51 #include "i830_state.h"
53 #include "i830_tris.h"
54 #include "i830_ioctl.h"
56 #include "swrast/swrast.h"
57 #include "array_cache/acache.h"
59 #include "swrast_setup/swrast_setup.h"
61 #include "tnl/t_pipeline.h"
63 static __inline__ GLuint
i830PackColor(GLuint format
,
68 if (I830_DEBUG
&DEBUG_DRI
)
69 fprintf(stderr
, "%s\n", __FUNCTION__
);
73 return I830PACKCOLOR1555(r
,g
,b
,a
);
75 return I830PACKCOLOR565(r
,g
,b
);
77 return I830PACKCOLOR8888(r
,g
,b
,a
);
79 fprintf(stderr
, "unknown format %d\n", (int)format
);
84 static void i830StencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
87 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
92 if (I830_DEBUG
&DEBUG_DRI
)
93 fprintf(stderr
, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__
,
94 _mesa_lookup_enum_by_nr(func
), ref
, mask
);
98 test
= COMPAREFUNC_NEVER
;
101 test
= COMPAREFUNC_LESS
;
104 test
= COMPAREFUNC_LEQUAL
;
107 test
= COMPAREFUNC_GREATER
;
110 test
= COMPAREFUNC_GEQUAL
;
113 test
= COMPAREFUNC_NOTEQUAL
;
116 test
= COMPAREFUNC_EQUAL
;
119 test
= COMPAREFUNC_ALWAYS
;
125 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
126 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
127 imesa
->Setup
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
128 STENCIL_TEST_MASK(mask
));
129 imesa
->Setup
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
130 ENABLE_STENCIL_TEST_FUNC_MASK
);
131 imesa
->Setup
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
132 ENABLE_STENCIL_TEST_FUNC
|
133 STENCIL_REF_VALUE(ref
) |
134 STENCIL_TEST_FUNC(test
));
137 static void i830StencilMask(GLcontext
*ctx
, GLuint mask
)
139 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
141 if (I830_DEBUG
&DEBUG_DRI
)
142 fprintf(stderr
, "%s : mask 0x%x\n", __FUNCTION__
, mask
);
146 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
147 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
148 imesa
->Setup
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
149 STENCIL_WRITE_MASK(mask
));
152 static void i830StencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
155 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
158 if (I830_DEBUG
&DEBUG_DRI
)
159 fprintf(stderr
, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__
,
160 _mesa_lookup_enum_by_nr(fail
),
161 _mesa_lookup_enum_by_nr(zfail
),
162 _mesa_lookup_enum_by_nr(zpass
));
164 fop
= 0; dfop
= 0; dpop
= 0;
168 fop
= STENCILOP_KEEP
;
171 fop
= STENCILOP_ZERO
;
174 fop
= STENCILOP_REPLACE
;
177 fop
= STENCILOP_INCRSAT
;
180 fop
= STENCILOP_DECRSAT
;
183 fop
= STENCILOP_INCR
;
186 fop
= STENCILOP_DECR
;
189 fop
= STENCILOP_INVERT
;
196 dfop
= STENCILOP_KEEP
;
199 dfop
= STENCILOP_ZERO
;
202 dfop
= STENCILOP_REPLACE
;
205 dfop
= STENCILOP_INCRSAT
;
208 dfop
= STENCILOP_DECRSAT
;
211 dfop
= STENCILOP_INCR
;
214 dfop
= STENCILOP_DECR
;
217 dfop
= STENCILOP_INVERT
;
224 dpop
= STENCILOP_KEEP
;
227 dpop
= STENCILOP_ZERO
;
230 dpop
= STENCILOP_REPLACE
;
233 dpop
= STENCILOP_INCRSAT
;
236 dpop
= STENCILOP_DECRSAT
;
239 dpop
= STENCILOP_INCR
;
242 dpop
= STENCILOP_DECR
;
245 dpop
= STENCILOP_INVERT
;
252 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
253 imesa
->Setup
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
254 imesa
->Setup
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
255 STENCIL_FAIL_OP(fop
) |
256 STENCIL_PASS_DEPTH_FAIL_OP(dfop
) |
257 STENCIL_PASS_DEPTH_PASS_OP(dpop
));
260 static void i830AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
262 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
264 GLuint refByte
= (GLint
) (ref
* 255.0);
268 test
= COMPAREFUNC_NEVER
;
271 test
= COMPAREFUNC_LESS
;
274 test
= COMPAREFUNC_LEQUAL
;
277 test
= COMPAREFUNC_GREATER
;
280 test
= COMPAREFUNC_GEQUAL
;
283 test
= COMPAREFUNC_NOTEQUAL
;
286 test
= COMPAREFUNC_EQUAL
;
289 test
= COMPAREFUNC_ALWAYS
;
295 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
296 imesa
->Setup
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
297 imesa
->Setup
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
298 ENABLE_ALPHA_REF_VALUE
|
299 ALPHA_TEST_FUNC(test
) |
300 ALPHA_REF_VALUE(refByte
));
303 /* This function makes sure that the proper enables are
304 * set for LogicOp, Independant Alpha Blend, and Blending.
305 * It needs to be called from numerous places where we
306 * could change the LogicOp or Independant Alpha Blend without subsequent
309 static void i830EvalLogicOpBlendState(GLcontext
*ctx
)
311 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
313 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
315 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
316 ENABLE_LOGIC_OP_MASK
);
317 imesa
->Setup
[I830_CTXREG_IALPHAB
] &= ~ENABLE_INDPT_ALPHA_BLEND
;
319 if (ctx
->Color
.ColorLogicOpEnabled
) {
320 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
322 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
323 } else if (ctx
->Color
.BlendEnabled
) {
324 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
327 /* If the alpha blend state does not match the color blend state,
328 * enable independent alpha blending. Otherwise, leave it disabled
329 * and the hardware will use the color blend state for both.
332 if ( 0 && (imesa
->Setup
[I830_CTXREG_IALPHAB
] & BLEND_STATE_MASK
)
333 != (imesa
->Setup
[I830_CTXREG_STATE1
] & BLEND_STATE_MASK
) ) {
334 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= ENABLE_INDPT_ALPHA_BLEND
;
336 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
339 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
341 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
345 static void i830BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
347 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
350 if (I830_DEBUG
&DEBUG_DRI
)
351 fprintf(stderr
, "%s\n", __FUNCTION__
);
353 FLOAT_COLOR_TO_UBYTE_COLOR(r
, color
[RCOMP
]);
354 FLOAT_COLOR_TO_UBYTE_COLOR(g
, color
[GCOMP
]);
355 FLOAT_COLOR_TO_UBYTE_COLOR(b
, color
[BCOMP
]);
356 FLOAT_COLOR_TO_UBYTE_COLOR(a
, color
[ACOMP
]);
358 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
359 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = ((a
<< 24) |
366 * Calculate the hardware blend factor setting. This same function is used
367 * for source and destination of both alpha and RGB.
370 * The hardware register value for the specified blend factor. This value
371 * will need to be shifted into the correct position for either source or
372 * destination factor.
375 * Since the two cases where source and destination are handled differently
376 * are essentially error cases, they should never happen. Determine if these
377 * cases can be removed.
379 static int blend_factor( GLenum factor
, GLboolean is_src
)
385 func
= BLENDFACT_ZERO
;
388 func
= BLENDFACT_ONE
;
391 func
= BLENDFACT_SRC_COLR
;
393 case GL_ONE_MINUS_SRC_COLOR
:
394 func
= BLENDFACT_INV_SRC_COLR
;
397 func
= BLENDFACT_SRC_ALPHA
;
399 case GL_ONE_MINUS_SRC_ALPHA
:
400 func
= BLENDFACT_INV_SRC_ALPHA
;
403 func
= BLENDFACT_DST_ALPHA
;
405 case GL_ONE_MINUS_DST_ALPHA
:
406 func
= BLENDFACT_INV_DST_ALPHA
;
409 func
= BLENDFACT_DST_COLR
;
411 case GL_ONE_MINUS_DST_COLOR
:
412 func
= BLENDFACT_INV_DST_COLR
;
414 case GL_SRC_ALPHA_SATURATE
:
415 func
= (is_src
) ? BLENDFACT_SRC_ALPHA_SATURATE
: BLENDFACT_ZERO
;
417 case GL_CONSTANT_COLOR
:
418 func
= BLENDFACT_CONST_COLOR
;
420 case GL_ONE_MINUS_CONSTANT_COLOR
:
421 func
= BLENDFACT_INV_CONST_COLOR
;
423 case GL_CONSTANT_ALPHA
:
424 func
= BLENDFACT_CONST_ALPHA
;
426 case GL_ONE_MINUS_CONSTANT_ALPHA
:
427 func
= BLENDFACT_INV_CONST_ALPHA
;
430 func
= (is_src
) ? BLENDFACT_ONE
: BLENDFACT_ZERO
;
438 * Sets both the blend equation (called "function" in i830 docs) and the
439 * blend function (called "factor" in i830 docs). This is done in a single
440 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
441 * change the interpretation of the blend function.
444 static void i830_set_blend_state( GLcontext
* ctx
)
446 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
453 funcRGB
= SRC_BLND_FACT( blend_factor( ctx
->Color
.BlendSrcRGB
, GL_TRUE
) )
454 | DST_BLND_FACT( blend_factor( ctx
->Color
.BlendDstRGB
, GL_FALSE
) );
456 switch(ctx
->Color
.BlendEquationRGB
) {
458 eqnRGB
= BLENDFUNC_ADD
;
461 eqnRGB
= BLENDFUNC_MIN
;
462 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
465 eqnRGB
= BLENDFUNC_MAX
;
466 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
468 case GL_FUNC_SUBTRACT
:
469 eqnRGB
= BLENDFUNC_SUB
;
471 case GL_FUNC_REVERSE_SUBTRACT
:
472 eqnRGB
= BLENDFUNC_RVRSE_SUB
;
475 fprintf( stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
476 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
481 funcA
= SRC_ABLEND_FACT( blend_factor( ctx
->Color
.BlendSrcA
, GL_TRUE
) )
482 | DST_ABLEND_FACT( blend_factor( ctx
->Color
.BlendDstA
, GL_FALSE
) );
484 switch(ctx
->Color
.BlendEquationA
) {
486 eqnA
= BLENDFUNC_ADD
;
489 eqnA
= BLENDFUNC_MIN
;
490 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
493 eqnA
= BLENDFUNC_MAX
;
494 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
496 case GL_FUNC_SUBTRACT
:
497 eqnA
= BLENDFUNC_SUB
;
499 case GL_FUNC_REVERSE_SUBTRACT
:
500 eqnA
= BLENDFUNC_RVRSE_SUB
;
503 fprintf( stderr
, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
504 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
508 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
510 imesa
->Setup
[I830_CTXREG_STATE1
] = eqnRGB
| funcRGB
511 | STATE3D_MODES_1_CMD
512 | ENABLE_SRC_BLND_FACTOR
| ENABLE_DST_BLND_FACTOR
513 | ENABLE_COLR_BLND_FUNC
;
515 imesa
->Setup
[I830_CTXREG_IALPHAB
] = eqnA
| funcA
516 | STATE3D_INDPT_ALPHA_BLEND_CMD
517 | ENABLE_SRC_ABLEND_FACTOR
| ENABLE_DST_ABLEND_FACTOR
518 | ENABLE_ALPHA_BLENDFUNC
;
521 /* This will catch a logicop blend equation. It will also ensure
522 * independant alpha blend is really in the correct state (either enabled
523 * or disabled) if blending is already enabled.
526 i830EvalLogicOpBlendState(ctx
);
529 fprintf(stderr
, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
531 imesa
->Setup
[I830_CTXREG_STATE1
],
532 imesa
->Setup
[I830_CTXREG_IALPHAB
],
533 (ctx
->Color
.BlendEnabled
) ? "en" : "dis");
537 static void i830BlendEquationSeparate(GLcontext
*ctx
,
538 GLenum modeRGB
, GLenum modeA
)
540 if (I830_DEBUG
&DEBUG_DRI
)
541 fprintf(stderr
, "%s -> %s, %s\n", __FUNCTION__
,
542 _mesa_lookup_enum_by_nr(modeRGB
),
543 _mesa_lookup_enum_by_nr(modeA
));
547 i830_set_blend_state( ctx
);
552 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
553 GLenum dfactorRGB
, GLenum sfactorA
,
556 if (I830_DEBUG
&DEBUG_DRI
)
557 fprintf(stderr
, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__
,
558 _mesa_lookup_enum_by_nr(sfactorRGB
),
559 _mesa_lookup_enum_by_nr(dfactorRGB
),
560 _mesa_lookup_enum_by_nr(sfactorA
),
561 _mesa_lookup_enum_by_nr(dfactorA
));
567 i830_set_blend_state( ctx
);
570 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
572 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
575 if (I830_DEBUG
&DEBUG_DRI
)
576 fprintf(stderr
, "%s\n", __FUNCTION__
);
580 test
= COMPAREFUNC_NEVER
;
583 test
= COMPAREFUNC_LESS
;
586 test
= COMPAREFUNC_LEQUAL
;
589 test
= COMPAREFUNC_GREATER
;
592 test
= COMPAREFUNC_GEQUAL
;
595 test
= COMPAREFUNC_NOTEQUAL
;
598 test
= COMPAREFUNC_EQUAL
;
601 test
= COMPAREFUNC_ALWAYS
;
606 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
607 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
608 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
609 DEPTH_TEST_FUNC(test
));
612 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
614 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
616 if (I830_DEBUG
&DEBUG_DRI
)
617 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
619 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
621 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
623 if (flag
&& ctx
->Depth
.Test
)
624 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
626 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
629 /* =============================================================
632 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
633 * Fortunately stipple is usually a repeating pattern.
635 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
637 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
638 const GLubyte
*m
= mask
;
641 int active
= (ctx
->Polygon
.StippleFlag
&&
642 imesa
->reduced_primitive
== GL_TRIANGLES
);
646 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
647 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
650 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
651 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
652 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
653 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
655 for (k
= 0 ; k
< 8 ; k
++)
656 for (j
= 3 ; j
>= 0; j
--)
657 for (i
= 0 ; i
< 4 ; i
++, m
++)
659 imesa
->hw_stipple
= 0;
663 newMask
= (((p
[0] & 0xf) << 0) |
664 ((p
[1] & 0xf) << 4) |
665 ((p
[2] & 0xf) << 8) |
666 ((p
[3] & 0xf) << 12));
669 if (newMask
== 0xffff || newMask
== 0x0) {
670 /* this is needed to make conform pass */
671 imesa
->hw_stipple
= 0;
675 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~0xffff;
676 imesa
->StippleSetup
[I830_STPREG_ST1
] |= newMask
;
677 imesa
->hw_stipple
= 1;
680 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
683 static void i830PolygonStippleFallback( GLcontext
*ctx
, const GLubyte
*mask
)
685 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
686 imesa
->hw_stipple
= 0;
687 (void) i830PolygonStipple
;
690 /* =============================================================
693 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
694 GLsizei w
, GLsizei h
)
696 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
698 int y1
= imesa
->driDrawable
->h
- (y
+ h
);
702 if (I830_DEBUG
&DEBUG_DRI
)
703 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
711 if (x2
>= imesa
->i830Screen
->width
) x2
= imesa
->i830Screen
->width
-1;
712 if (y2
>= imesa
->i830Screen
->height
) y2
= imesa
->i830Screen
->height
-1;
713 if (x1
>= imesa
->i830Screen
->width
) x1
= imesa
->i830Screen
->width
-1;
714 if (y1
>= imesa
->i830Screen
->height
) y1
= imesa
->i830Screen
->height
-1;
717 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
718 imesa
->BufferSetup
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
719 imesa
->BufferSetup
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
722 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
724 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
727 if (I830_DEBUG
&DEBUG_DRI
)
728 fprintf(stderr
, "%s\n", __FUNCTION__
);
730 /* FIXME: This should be a look-up table, like the r200 driver. */
739 tmp
= LOGICOP_AND_RVRSE
;
744 case GL_COPY_INVERTED
:
745 tmp
= LOGICOP_COPY_INV
;
747 case GL_AND_INVERTED
:
748 tmp
= LOGICOP_AND_INV
;
760 tmp
= LOGICOP_OR_INV
;
772 tmp
= LOGICOP_OR_RVRSE
;
784 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
785 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
786 imesa
->Setup
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
788 /* Make sure all the enables are correct */
789 i830EvalLogicOpBlendState(ctx
);
792 /* Fallback to swrast for select and feedback.
794 static void i830RenderMode( GLcontext
*ctx
, GLenum mode
)
796 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
797 FALLBACK( imesa
, I830_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
800 static void i830DrawBuffer(GLcontext
*ctx
, GLenum mode
)
802 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
805 * _DrawDestMask is easier to cope with than <mode>.
807 switch ( ctx
->Color
._DrawDestMask
[0] ) {
808 case DD_FRONT_LEFT_BIT
:
809 I830_FIREVERTICES(imesa
);
810 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
811 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = imesa
->i830Screen
->fbOffset
;
812 i830XMesaSetFrontClipRects( imesa
);
813 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
815 case DD_BACK_LEFT_BIT
:
816 I830_FIREVERTICES(imesa
);
817 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
818 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] =
819 imesa
->i830Screen
->backOffset
;
820 i830XMesaSetBackClipRects( imesa
);
821 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
824 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
825 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
829 /* We want to update the s/w rast state too so that i830SetBuffer()
832 _swrast_DrawBuffer(ctx
, mode
);
835 static void i830ReadBuffer(GLcontext
*ctx
, GLenum mode
)
837 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
840 static void i830ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
842 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
844 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_red
, color
[0]);
845 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_green
, color
[1]);
846 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_blue
, color
[2]);
847 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_alpha
, color
[3]);
849 imesa
->ClearColor
= i830PackColor(imesa
->i830Screen
->fbFormat
,
856 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
858 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
859 GLuint mode
= CULLMODE_BOTH
;
861 if (I830_DEBUG
&DEBUG_DRI
)
862 fprintf(stderr
, "%s\n", __FUNCTION__
);
864 if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
867 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
868 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
869 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
870 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
873 imesa
->LcsCullMode
= mode
;
875 if (ctx
->Polygon
.CullFlag
) {
876 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
877 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
878 imesa
->Setup
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
882 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
884 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
887 if (I830_DEBUG
&DEBUG_DRI
)
888 fprintf(stderr
, "%s\n", __FUNCTION__
);
890 width
= FloatToInt(widthf
* 2);
891 CLAMP_SELF(width
, 1, 15);
893 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
894 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_LINE_WIDTH_MASK
;
895 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_LINE_WIDTH
|
896 FIXED_LINE_WIDTH(width
));
899 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
901 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
902 GLint point_size
= FloatToInt(size
);
904 if (I830_DEBUG
&DEBUG_DRI
)
905 fprintf(stderr
, "%s\n", __FUNCTION__
);
907 CLAMP_SELF(point_size
, 1, 256);
908 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
909 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
910 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
911 FIXED_POINT_WIDTH(point_size
));
915 /* =============================================================
919 static void i830ColorMask(GLcontext
*ctx
,
920 GLboolean r
, GLboolean g
,
921 GLboolean b
, GLboolean a
)
923 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
926 if (I830_DEBUG
&DEBUG_DRI
)
927 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
929 imesa
->mask_red
= !r
;
930 imesa
->mask_green
= !g
;
931 imesa
->mask_blue
= !b
;
932 imesa
->mask_alpha
= !a
;
934 tmp
= (imesa
->Setup
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
937 ((!r
) << WRITEMASK_RED_SHIFT
) |
938 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
939 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
940 ((!a
) << WRITEMASK_ALPHA_SHIFT
);
942 if (tmp
!= imesa
->Setup
[I830_CTXREG_ENABLES_2
]) {
943 I830_FIREVERTICES(imesa
);
944 imesa
->dirty
|= I830_UPLOAD_CTX
;
945 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = tmp
;
949 static void update_specular( GLcontext
*ctx
)
951 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
953 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
954 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
956 if (NEED_SECONDARY_COLOR(ctx
))
957 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
959 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
962 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
963 const GLfloat
*param
)
965 if (I830_DEBUG
&DEBUG_DRI
)
966 fprintf(stderr
, "%s\n", __FUNCTION__
);
968 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
969 update_specular( ctx
);
973 /* In Mesa 3.5 we can reliably do native flatshading.
975 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
977 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
978 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
981 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
983 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
985 if (mode
== GL_FLAT
) {
986 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
987 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
988 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
989 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
991 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
992 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
993 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
994 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
998 /* =============================================================
1001 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
1003 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1005 if (I830_DEBUG
&DEBUG_DRI
)
1006 fprintf(stderr
, "%s\n", __FUNCTION__
);
1008 if (pname
== GL_FOG_COLOR
) {
1009 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
1010 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
1011 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
1013 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1014 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
| color
);
1018 /* =============================================================
1021 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1023 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1027 case GL_COLOR_SUM_EXT
:
1028 update_specular( ctx
);
1032 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1033 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
1035 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
1037 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
1042 case GL_COLOR_LOGIC_OP
:
1043 case GL_INDEX_LOGIC_OP
:
1044 i830EvalLogicOpBlendState(ctx
);
1048 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1049 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
1052 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
1054 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
1058 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1059 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
1062 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
1064 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
1066 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1068 i830DepthMask( ctx
, state
);
1071 case GL_SCISSOR_TEST
:
1072 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
1075 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1076 (STATE3D_SCISSOR_ENABLE_CMD
|
1077 ENABLE_SCISSOR_RECT
);
1079 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1080 (STATE3D_SCISSOR_ENABLE_CMD
|
1081 DISABLE_SCISSOR_RECT
);
1083 imesa
->upload_cliprects
= GL_TRUE
;
1086 case GL_LINE_SMOOTH
:
1087 if (imesa
->reduced_primitive
== GL_LINES
) {
1088 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1090 imesa
->Setup
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
1092 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
1094 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
1099 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1100 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
1102 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_ENABLE_FOG
;
1104 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_DISABLE_FOG
;
1108 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1109 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
1111 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1112 imesa
->LcsCullMode
);
1114 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1119 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1120 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1123 case GL_STENCIL_TEST
:
1124 if (imesa
->hw_stencil
) {
1125 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1126 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
1127 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
1130 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
1131 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
1133 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
1134 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
1137 FALLBACK( imesa
, I830_FALLBACK_STENCIL
, state
);
1141 case GL_POLYGON_STIPPLE
:
1143 /* The stipple command worked on my 855GM box, but not my 845G.
1144 * I'll do more testing later to find out exactly which hardware
1145 * supports it. Disabled for now.
1147 if (imesa
->hw_stipple
&& imesa
->reduced_primitive
== GL_TRIANGLES
)
1149 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
1150 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
1152 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
1163 void i830EmitDrawingRectangle( i830ContextPtr imesa
)
1165 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1166 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1167 int x0
= imesa
->drawX
;
1168 int y0
= imesa
->drawY
;
1169 int x1
= x0
+ dPriv
->w
;
1170 int y1
= y0
+ dPriv
->h
;
1172 /* Don't set drawing rectangle */
1173 if (I830_DEBUG
& DEBUG_IOCTL
)
1174 fprintf(stderr
, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__
,
1177 /* Coordinate origin of the window - may be offscreen.
1179 imesa
->BufferSetup
[I830_DESTREG_DR4
] = ((y0
<<16) |
1180 (((unsigned)x0
)&0xFFFF));
1186 if (x1
> i830Screen
->width
-1) x1
= i830Screen
->width
-1;
1187 if (y1
> i830Screen
->height
-1) y1
= i830Screen
->height
-1;
1190 /* Onscreen drawing rectangle.
1192 imesa
->BufferSetup
[I830_DESTREG_DR2
] = ((y0
<<16) | x0
);
1193 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((y1
+1)<<16) | (x1
+1));
1196 /* Just add in our dirty flag, since we might be called when locked */
1197 /* Might want to modify how this is done. */
1198 imesa
->dirty
|= I830_UPLOAD_BUFFERS
;
1201 fprintf(stderr
, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1203 imesa
->BufferSetup
[I830_DESTREG_DR2
],
1204 imesa
->BufferSetup
[I830_DESTREG_DR3
],
1205 imesa
->BufferSetup
[I830_DESTREG_DR4
]);
1208 /* This could be done in hardware, will do once I have the driver
1211 static void i830CalcViewport( GLcontext
*ctx
)
1213 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1214 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1215 GLfloat
*m
= imesa
->ViewportMatrix
.m
;
1217 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1218 * via state vars, too.
1220 m
[MAT_SX
] = v
[MAT_SX
];
1221 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
1222 m
[MAT_SY
] = - v
[MAT_SY
];
1223 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ SUBPIXEL_Y
;
1224 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
1225 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
1228 static void i830Viewport( GLcontext
*ctx
,
1230 GLsizei width
, GLsizei height
)
1232 /* update size of Mesa/software ancillary buffers */
1233 _mesa_ResizeBuffersMESA();
1234 i830CalcViewport( ctx
);
1237 static void i830DepthRange( GLcontext
*ctx
,
1238 GLclampd nearval
, GLclampd farval
)
1240 i830CalcViewport( ctx
);
1243 void i830PrintDirty( const char *msg
, GLuint state
)
1245 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s\n",
1247 (unsigned int) state
,
1248 (state
& I830_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1249 (state
& I830_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1250 (state
& I830_UPLOAD_TEX2
) ? "upload-tex2, " : "",
1251 (state
& I830_UPLOAD_TEX3
) ? "upload-tex3, " : "",
1252 (state
& I830_UPLOAD_CTX
) ? "upload-ctx, " : "",
1253 (state
& I830_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1254 (state
& I830_UPLOAD_TEXBLEND0
) ? "upload-blend0, " : "",
1255 (state
& I830_UPLOAD_TEXBLEND1
) ? "upload-blend1, " : "",
1256 (state
& I830_UPLOAD_TEXBLEND2
) ? "upload-blend2, " : "",
1257 (state
& I830_UPLOAD_TEXBLEND3
) ? "upload-blend3, " : "",
1258 (state
& I830_UPLOAD_STIPPLE
) ? "stipple, " : ""
1262 /* Push the state into the sarea and/or texture memory.
1264 void i830EmitHwStateLocked( i830ContextPtr imesa
)
1268 if (I830_DEBUG
& DEBUG_STATE
)
1269 i830PrintDirty( __FUNCTION__
, imesa
->dirty
);
1271 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1272 if ( ((imesa
->dirty
& I830_UPLOAD_TEX_N_IMAGE( i
)) != 0)
1273 && (imesa
->CurrentTexObj
[i
] != NULL
) ) {
1274 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[i
]);
1278 if (imesa
->dirty
& I830_UPLOAD_CTX
) {
1279 memcpy( imesa
->sarea
->ContextState
,
1280 imesa
->Setup
, sizeof(imesa
->Setup
) );
1283 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1284 if ((imesa
->dirty
& I830_UPLOAD_TEX_N(i
)) && imesa
->CurrentTexObj
[i
]) {
1285 unsigned * TexState
;
1287 imesa
->sarea
->dirty
|= I830_UPLOAD_TEX_N(i
);
1292 TexState
= imesa
->sarea
->TexState
[i
];
1296 TexState
= imesa
->sarea
->TexState2
;
1300 TexState
= imesa
->sarea
->TexState3
;
1304 memcpy(TexState
, imesa
->CurrentTexObj
[i
]->Setup
,
1305 sizeof(imesa
->sarea
->TexState
[i
]));
1307 TexState
[I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
1308 TexState
[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
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1319 if (imesa
->dirty
& I830_UPLOAD_TEXBLEND_N(i
)) {
1320 unsigned * TexBlendState
;
1321 unsigned * words_used
;
1323 imesa
->sarea
->dirty
|= I830_UPLOAD_TEXBLEND_N(i
);
1328 TexBlendState
= imesa
->sarea
->TexBlendState
[i
];
1329 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed
[i
];
1333 TexBlendState
= imesa
->sarea
->TexBlendState2
;
1334 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed2
;
1338 TexBlendState
= imesa
->sarea
->TexBlendState3
;
1339 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed3
;
1343 memcpy(TexBlendState
, imesa
->TexBlend
[i
],
1344 imesa
->TexBlendWordsUsed
[i
] * 4);
1345 *words_used
= imesa
->TexBlendWordsUsed
[i
];
1349 if (imesa
->dirty
& I830_UPLOAD_BUFFERS
) {
1350 memcpy( imesa
->sarea
->BufferState
,imesa
->BufferSetup
,
1351 sizeof(imesa
->BufferSetup
) );
1354 if (imesa
->dirty
& I830_UPLOAD_STIPPLE
) {
1355 memcpy( imesa
->sarea
->StippleState
,imesa
->StippleSetup
,
1356 sizeof(imesa
->StippleSetup
) );
1359 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_SHARED
) {
1360 memcpy( imesa
->sarea
->Palette
[0],imesa
->palette
,
1361 sizeof(imesa
->sarea
->Palette
[0]));
1363 i830TextureObjectPtr p
;
1364 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(0)) {
1365 p
= imesa
->CurrentTexObj
[0];
1366 memcpy( imesa
->sarea
->Palette
[0],p
->palette
,
1367 sizeof(imesa
->sarea
->Palette
[0]));
1369 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(1)) {
1370 p
= imesa
->CurrentTexObj
[1];
1371 memcpy( imesa
->sarea
->Palette
[1],
1373 sizeof(imesa
->sarea
->Palette
[1]));
1377 imesa
->sarea
->dirty
|= (imesa
->dirty
& ~(I830_UPLOAD_TEX_MASK
|
1378 I830_UPLOAD_TEXBLEND_MASK
));
1380 imesa
->upload_cliprects
= GL_TRUE
;
1385 void i830DDInitState( GLcontext
*ctx
)
1387 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1388 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1391 imesa
->clear_red
= 0;
1392 imesa
->clear_green
= 0;
1393 imesa
->clear_blue
= 0;
1394 imesa
->clear_alpha
= 0;
1396 imesa
->mask_red
= GL_FALSE
;
1397 imesa
->mask_green
= GL_FALSE
;
1398 imesa
->mask_blue
= GL_FALSE
;
1399 imesa
->mask_alpha
= GL_FALSE
;
1401 /* Zero all texture state */
1402 for (i
= 0; i
< I830_MAX_TEXTURE_UNITS
; i
++) {
1403 (void) memset( imesa
->TexBlend
[i
], 0, sizeof( imesa
->TexBlend
[i
] ) );
1404 (void) memset( imesa
->Init_TexBlend
[i
], 0, sizeof( imesa
->Init_TexBlend
[i
] ) );
1406 imesa
->TexBlendWordsUsed
[i
] = 0;
1407 imesa
->Init_TexBlendWordsUsed
[i
] = 0;
1410 /* Set default blend state */
1411 imesa
->TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1413 ENABLE_TEXOUTPUT_WRT_SEL
|
1414 TEXOP_OUTPUT_CURRENT
|
1415 DISABLE_TEX_CNTRL_STAGE
|
1417 TEXOP_MODIFY_PARMS
|
1420 imesa
->TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1422 ENABLE_TEXOUTPUT_WRT_SEL
|
1423 TEXOP_OUTPUT_CURRENT
|
1425 TEXOP_MODIFY_PARMS
|
1427 imesa
->TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1430 TEXBLENDARG_MODIFY_PARMS
|
1431 TEXBLENDARG_DIFFUSE
);
1432 imesa
->TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1435 TEXBLENDARG_MODIFY_PARMS
|
1436 TEXBLENDARG_DIFFUSE
);
1438 imesa
->TexBlendWordsUsed
[0] = 4;
1440 imesa
->Init_TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1442 ENABLE_TEXOUTPUT_WRT_SEL
|
1443 TEXOP_OUTPUT_CURRENT
|
1444 DISABLE_TEX_CNTRL_STAGE
|
1446 TEXOP_MODIFY_PARMS
|
1449 imesa
->Init_TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1451 ENABLE_TEXOUTPUT_WRT_SEL
|
1452 TEXOP_OUTPUT_CURRENT
|
1454 TEXOP_MODIFY_PARMS
|
1456 imesa
->Init_TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1459 TEXBLENDARG_MODIFY_PARMS
|
1460 TEXBLENDARG_CURRENT
);
1461 imesa
->Init_TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1464 TEXBLENDARG_MODIFY_PARMS
|
1465 TEXBLENDARG_CURRENT
);
1466 imesa
->Init_TexBlendWordsUsed
[0] = 4;
1468 memset(imesa
->Setup
, 0, sizeof(imesa
->Setup
));
1470 imesa
->Setup
[I830_CTXREG_VF
] = 0;
1471 imesa
->Setup
[I830_CTXREG_VF2
] = 0;
1473 imesa
->Setup
[I830_CTXREG_AA
] = (STATE3D_AA_CMD
|
1474 AA_LINE_ECAAR_WIDTH_ENABLE
|
1475 AA_LINE_ECAAR_WIDTH_1_0
|
1476 AA_LINE_REGION_WIDTH_ENABLE
|
1477 AA_LINE_REGION_WIDTH_1_0
|
1480 imesa
->Setup
[I830_CTXREG_ENABLES_1
] = (STATE3D_ENABLES_1_CMD
|
1482 DISABLE_STENCIL_TEST
|
1483 DISABLE_DEPTH_BIAS
|
1486 DISABLE_ALPHA_TEST
|
1487 DISABLE_COLOR_BLEND
|
1488 DISABLE_DEPTH_TEST
);
1490 if (imesa
->hw_stencil
) {
1491 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1492 ENABLE_STENCIL_WRITE
|
1496 /* set no color comps disabled */
1497 ENABLE_COLOR_WRITE
|
1498 ENABLE_DEPTH_WRITE
);
1500 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1501 DISABLE_STENCIL_WRITE
|
1505 /* set no color comps disabled */
1506 ENABLE_COLOR_WRITE
|
1507 ENABLE_DEPTH_WRITE
);
1510 imesa
->Setup
[I830_CTXREG_STATE1
] = (STATE3D_MODES_1_CMD
|
1511 ENABLE_COLR_BLND_FUNC
|
1513 ENABLE_SRC_BLND_FACTOR
|
1514 SRC_BLND_FACT(BLENDFACT_ONE
) |
1515 ENABLE_DST_BLND_FACTOR
|
1516 DST_BLND_FACT(BLENDFACT_ZERO
) );
1518 imesa
->Setup
[I830_CTXREG_STATE2
] = (STATE3D_MODES_2_CMD
|
1519 ENABLE_GLOBAL_DEPTH_BIAS
|
1520 GLOBAL_DEPTH_BIAS(0) |
1521 ENABLE_ALPHA_TEST_FUNC
|
1522 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1523 ALPHA_REF_VALUE(0) );
1525 imesa
->Setup
[I830_CTXREG_STATE3
] = (STATE3D_MODES_3_CMD
|
1526 ENABLE_DEPTH_TEST_FUNC
|
1527 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1528 ENABLE_ALPHA_SHADE_MODE
|
1529 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1530 ENABLE_FOG_SHADE_MODE
|
1531 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1532 ENABLE_SPEC_SHADE_MODE
|
1533 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1534 ENABLE_COLOR_SHADE_MODE
|
1535 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1539 imesa
->Setup
[I830_CTXREG_STATE4
] = (STATE3D_MODES_4_CMD
|
1540 ENABLE_LOGIC_OP_FUNC
|
1541 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1542 ENABLE_STENCIL_TEST_MASK
|
1543 STENCIL_TEST_MASK(0xff) |
1544 ENABLE_STENCIL_WRITE_MASK
|
1545 STENCIL_WRITE_MASK(0xff));
1547 imesa
->Setup
[I830_CTXREG_STENCILTST
] = (STATE3D_STENCIL_TEST_CMD
|
1548 ENABLE_STENCIL_PARMS
|
1549 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1550 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1551 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1552 ENABLE_STENCIL_TEST_FUNC
|
1553 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1554 ENABLE_STENCIL_REF_VALUE
|
1555 STENCIL_REF_VALUE(0) );
1557 imesa
->Setup
[I830_CTXREG_STATE5
] = (STATE3D_MODES_5_CMD
|
1558 FLUSH_TEXTURE_CACHE
|
1559 ENABLE_SPRITE_POINT_TEX
|
1560 SPRITE_POINT_TEX_OFF
|
1561 ENABLE_FIXED_LINE_WIDTH
|
1562 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1563 ENABLE_FIXED_POINT_WIDTH
|
1564 FIXED_POINT_WIDTH(1) );
1566 imesa
->Setup
[I830_CTXREG_IALPHAB
] = (STATE3D_INDPT_ALPHA_BLEND_CMD
|
1567 DISABLE_INDPT_ALPHA_BLEND
|
1568 ENABLE_ALPHA_BLENDFUNC
|
1571 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
|
1573 FOG_COLOR_GREEN(0) |
1576 imesa
->Setup
[I830_CTXREG_BLENDCOLR0
] = (STATE3D_CONST_BLEND_COLOR_CMD
);
1578 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = 0;
1580 imesa
->Setup
[I830_CTXREG_MCSB0
] = STATE3D_MAP_COORD_SETBIND_CMD
;
1581 imesa
->Setup
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1582 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1583 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1584 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1586 imesa
->LcsCullMode
= CULLMODE_CW
; /* GL default */
1588 memset(imesa
->BufferSetup
, 0, sizeof(imesa
->BufferSetup
));
1589 memset(imesa
->StippleSetup
, 0, sizeof(imesa
->StippleSetup
));
1592 if (imesa
->glCtx
->Visual
.doubleBufferMode
&&
1593 imesa
->sarea
->pf_current_page
== 0) {
1594 imesa
->drawMap
= i830Screen
->back
.map
;
1595 imesa
->readMap
= i830Screen
->back
.map
;
1596 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
1597 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1599 /* use front buffer by default */
1600 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
1601 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
1602 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
1603 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1606 imesa
->BufferSetup
[I830_DESTREG_DV0
] = STATE3D_DST_BUF_VARS_CMD
;
1608 switch (i830Screen
->fbFormat
) {
1611 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1612 DSTORG_VERT_BIAS(0x8) | /* .5 */
1613 i830Screen
->fbFormat
|
1615 DEPTH_FRMT_16_FIXED
);
1618 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1619 DSTORG_VERT_BIAS(0x8) | /* .5 */
1620 i830Screen
->fbFormat
|
1622 DEPTH_FRMT_24_FIXED_8_OTHER
);
1625 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] = (STATE3D_SCISSOR_ENABLE_CMD
|
1626 DISABLE_SCISSOR_RECT
);
1627 imesa
->BufferSetup
[I830_DESTREG_SR0
] = STATE3D_SCISSOR_RECT_0_CMD
;
1628 imesa
->BufferSetup
[I830_DESTREG_SR1
] = 0;
1629 imesa
->BufferSetup
[I830_DESTREG_SR2
] = 0;
1631 imesa
->BufferSetup
[I830_DESTREG_DR0
] = STATE3D_DRAW_RECT_CMD
;
1632 imesa
->BufferSetup
[I830_DESTREG_DR1
] = 0;
1633 imesa
->BufferSetup
[I830_DESTREG_DR2
] = 0;
1634 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((i830Screen
->height
)<<16) |
1635 (i830Screen
->width
));
1636 imesa
->BufferSetup
[I830_DESTREG_DR4
] = 0;
1638 memcpy( imesa
->Init_Setup
,
1640 sizeof(imesa
->Setup
) );
1641 memcpy( imesa
->Init_BufferSetup
,
1643 sizeof(imesa
->BufferSetup
) );
1647 static void i830InvalidateState( GLcontext
*ctx
, GLuint new_state
)
1649 _swrast_InvalidateState( ctx
, new_state
);
1650 _swsetup_InvalidateState( ctx
, new_state
);
1651 _ac_InvalidateState( ctx
, new_state
);
1652 _tnl_InvalidateState( ctx
, new_state
);
1653 I830_CONTEXT(ctx
)->NewGLState
|= new_state
;
1656 void i830DDInitStateFuncs(GLcontext
*ctx
)
1658 /* Callbacks for internal Mesa events.
1660 ctx
->Driver
.UpdateState
= i830InvalidateState
;
1664 ctx
->Driver
.AlphaFunc
= i830AlphaFunc
;
1665 ctx
->Driver
.BlendEquationSeparate
= i830BlendEquationSeparate
;
1666 ctx
->Driver
.BlendFuncSeparate
= i830BlendFuncSeparate
;
1667 ctx
->Driver
.BlendColor
= i830BlendColor
;
1668 ctx
->Driver
.ClearColor
= i830ClearColor
;
1669 ctx
->Driver
.ColorMask
= i830ColorMask
;
1670 ctx
->Driver
.CullFace
= i830CullFaceFrontFace
;
1671 ctx
->Driver
.DepthFunc
= i830DepthFunc
;
1672 ctx
->Driver
.DepthMask
= i830DepthMask
;
1673 ctx
->Driver
.Enable
= i830Enable
;
1674 ctx
->Driver
.Fogfv
= i830Fogfv
;
1675 ctx
->Driver
.FrontFace
= i830CullFaceFrontFace
;
1676 ctx
->Driver
.LineWidth
= i830LineWidth
;
1677 ctx
->Driver
.PointSize
= i830PointSize
;
1678 ctx
->Driver
.LogicOpcode
= i830LogicOp
;
1679 ctx
->Driver
.PolygonStipple
= i830PolygonStippleFallback
;
1680 ctx
->Driver
.RenderMode
= i830RenderMode
;
1681 ctx
->Driver
.Scissor
= i830Scissor
;
1682 ctx
->Driver
.DrawBuffer
= i830DrawBuffer
;
1683 ctx
->Driver
.ReadBuffer
= i830ReadBuffer
;
1684 ctx
->Driver
.ShadeModel
= i830ShadeModel
;
1685 ctx
->Driver
.DepthRange
= i830DepthRange
;
1686 ctx
->Driver
.Viewport
= i830Viewport
;
1687 ctx
->Driver
.LightModelfv
= i830LightModelfv
;
1689 ctx
->Driver
.StencilFunc
= i830StencilFunc
;
1690 ctx
->Driver
.StencilMask
= i830StencilMask
;
1691 ctx
->Driver
.StencilOp
= i830StencilOp
;
1693 /* Pixel path fallbacks.
1695 ctx
->Driver
.Accum
= _swrast_Accum
;
1696 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1697 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1698 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1699 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1701 /* Swrast hooks for imaging extensions:
1703 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1704 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1705 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1706 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;