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
);
85 i830StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
, GLint ref
,
88 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
93 if (I830_DEBUG
&DEBUG_DRI
)
94 fprintf(stderr
, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__
,
95 _mesa_lookup_enum_by_nr(func
), ref
, mask
);
99 test
= COMPAREFUNC_NEVER
;
102 test
= COMPAREFUNC_LESS
;
105 test
= COMPAREFUNC_LEQUAL
;
108 test
= COMPAREFUNC_GREATER
;
111 test
= COMPAREFUNC_GEQUAL
;
114 test
= COMPAREFUNC_NOTEQUAL
;
117 test
= COMPAREFUNC_EQUAL
;
120 test
= COMPAREFUNC_ALWAYS
;
126 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
127 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
128 imesa
->Setup
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
129 STENCIL_TEST_MASK(mask
));
130 imesa
->Setup
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
131 ENABLE_STENCIL_TEST_FUNC_MASK
);
132 imesa
->Setup
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
133 ENABLE_STENCIL_TEST_FUNC
|
134 STENCIL_REF_VALUE(ref
) |
135 STENCIL_TEST_FUNC(test
));
139 i830StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
141 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
143 if (I830_DEBUG
&DEBUG_DRI
)
144 fprintf(stderr
, "%s : mask 0x%x\n", __FUNCTION__
, mask
);
148 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
149 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
150 imesa
->Setup
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
151 STENCIL_WRITE_MASK(mask
));
155 i830StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
, GLenum zfail
,
158 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
161 if (I830_DEBUG
&DEBUG_DRI
)
162 fprintf(stderr
, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__
,
163 _mesa_lookup_enum_by_nr(fail
),
164 _mesa_lookup_enum_by_nr(zfail
),
165 _mesa_lookup_enum_by_nr(zpass
));
167 fop
= 0; dfop
= 0; dpop
= 0;
171 fop
= STENCILOP_KEEP
;
174 fop
= STENCILOP_ZERO
;
177 fop
= STENCILOP_REPLACE
;
180 fop
= STENCILOP_INCRSAT
;
183 fop
= STENCILOP_DECRSAT
;
186 fop
= STENCILOP_INCR
;
189 fop
= STENCILOP_DECR
;
192 fop
= STENCILOP_INVERT
;
199 dfop
= STENCILOP_KEEP
;
202 dfop
= STENCILOP_ZERO
;
205 dfop
= STENCILOP_REPLACE
;
208 dfop
= STENCILOP_INCRSAT
;
211 dfop
= STENCILOP_DECRSAT
;
214 dfop
= STENCILOP_INCR
;
217 dfop
= STENCILOP_DECR
;
220 dfop
= STENCILOP_INVERT
;
227 dpop
= STENCILOP_KEEP
;
230 dpop
= STENCILOP_ZERO
;
233 dpop
= STENCILOP_REPLACE
;
236 dpop
= STENCILOP_INCRSAT
;
239 dpop
= STENCILOP_DECRSAT
;
242 dpop
= STENCILOP_INCR
;
245 dpop
= STENCILOP_DECR
;
248 dpop
= STENCILOP_INVERT
;
255 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
256 imesa
->Setup
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
257 imesa
->Setup
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
258 STENCIL_FAIL_OP(fop
) |
259 STENCIL_PASS_DEPTH_FAIL_OP(dfop
) |
260 STENCIL_PASS_DEPTH_PASS_OP(dpop
));
263 static void i830AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
265 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
267 GLuint refByte
= (GLint
) (ref
* 255.0);
271 test
= COMPAREFUNC_NEVER
;
274 test
= COMPAREFUNC_LESS
;
277 test
= COMPAREFUNC_LEQUAL
;
280 test
= COMPAREFUNC_GREATER
;
283 test
= COMPAREFUNC_GEQUAL
;
286 test
= COMPAREFUNC_NOTEQUAL
;
289 test
= COMPAREFUNC_EQUAL
;
292 test
= COMPAREFUNC_ALWAYS
;
298 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
299 imesa
->Setup
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
300 imesa
->Setup
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
301 ENABLE_ALPHA_REF_VALUE
|
302 ALPHA_TEST_FUNC(test
) |
303 ALPHA_REF_VALUE(refByte
));
306 /* This function makes sure that the proper enables are
307 * set for LogicOp, Independant Alpha Blend, and Blending.
308 * It needs to be called from numerous places where we
309 * could change the LogicOp or Independant Alpha Blend without subsequent
312 static void i830EvalLogicOpBlendState(GLcontext
*ctx
)
314 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
316 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
318 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
319 ENABLE_LOGIC_OP_MASK
);
320 imesa
->Setup
[I830_CTXREG_IALPHAB
] &= ~ENABLE_INDPT_ALPHA_BLEND
;
322 if (ctx
->Color
.ColorLogicOpEnabled
) {
323 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
325 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
326 } else if (ctx
->Color
.BlendEnabled
) {
327 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
330 /* If the alpha blend state does not match the color blend state,
331 * enable independent alpha blending. Otherwise, leave it disabled
332 * and the hardware will use the color blend state for both.
335 if ( 0 && (imesa
->Setup
[I830_CTXREG_IALPHAB
] & BLEND_STATE_MASK
)
336 != (imesa
->Setup
[I830_CTXREG_STATE1
] & BLEND_STATE_MASK
) ) {
337 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= ENABLE_INDPT_ALPHA_BLEND
;
339 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
342 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
344 imesa
->Setup
[I830_CTXREG_IALPHAB
] |= DISABLE_INDPT_ALPHA_BLEND
;
348 static void i830BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
350 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
353 if (I830_DEBUG
&DEBUG_DRI
)
354 fprintf(stderr
, "%s\n", __FUNCTION__
);
356 FLOAT_COLOR_TO_UBYTE_COLOR(r
, color
[RCOMP
]);
357 FLOAT_COLOR_TO_UBYTE_COLOR(g
, color
[GCOMP
]);
358 FLOAT_COLOR_TO_UBYTE_COLOR(b
, color
[BCOMP
]);
359 FLOAT_COLOR_TO_UBYTE_COLOR(a
, color
[ACOMP
]);
361 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
362 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = ((a
<< 24) |
369 * Calculate the hardware blend factor setting. This same function is used
370 * for source and destination of both alpha and RGB.
373 * The hardware register value for the specified blend factor. This value
374 * will need to be shifted into the correct position for either source or
375 * destination factor.
378 * Since the two cases where source and destination are handled differently
379 * are essentially error cases, they should never happen. Determine if these
380 * cases can be removed.
382 static int blend_factor( GLenum factor
, GLboolean is_src
)
388 func
= BLENDFACT_ZERO
;
391 func
= BLENDFACT_ONE
;
394 func
= BLENDFACT_SRC_COLR
;
396 case GL_ONE_MINUS_SRC_COLOR
:
397 func
= BLENDFACT_INV_SRC_COLR
;
400 func
= BLENDFACT_SRC_ALPHA
;
402 case GL_ONE_MINUS_SRC_ALPHA
:
403 func
= BLENDFACT_INV_SRC_ALPHA
;
406 func
= BLENDFACT_DST_ALPHA
;
408 case GL_ONE_MINUS_DST_ALPHA
:
409 func
= BLENDFACT_INV_DST_ALPHA
;
412 func
= BLENDFACT_DST_COLR
;
414 case GL_ONE_MINUS_DST_COLOR
:
415 func
= BLENDFACT_INV_DST_COLR
;
417 case GL_SRC_ALPHA_SATURATE
:
418 func
= (is_src
) ? BLENDFACT_SRC_ALPHA_SATURATE
: BLENDFACT_ZERO
;
420 case GL_CONSTANT_COLOR
:
421 func
= BLENDFACT_CONST_COLOR
;
423 case GL_ONE_MINUS_CONSTANT_COLOR
:
424 func
= BLENDFACT_INV_CONST_COLOR
;
426 case GL_CONSTANT_ALPHA
:
427 func
= BLENDFACT_CONST_ALPHA
;
429 case GL_ONE_MINUS_CONSTANT_ALPHA
:
430 func
= BLENDFACT_INV_CONST_ALPHA
;
433 func
= (is_src
) ? BLENDFACT_ONE
: BLENDFACT_ZERO
;
441 * Sets both the blend equation (called "function" in i830 docs) and the
442 * blend function (called "factor" in i830 docs). This is done in a single
443 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
444 * change the interpretation of the blend function.
447 static void i830_set_blend_state( GLcontext
* ctx
)
449 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
456 funcRGB
= SRC_BLND_FACT( blend_factor( ctx
->Color
.BlendSrcRGB
, GL_TRUE
) )
457 | DST_BLND_FACT( blend_factor( ctx
->Color
.BlendDstRGB
, GL_FALSE
) );
459 switch(ctx
->Color
.BlendEquationRGB
) {
461 eqnRGB
= BLENDFUNC_ADD
;
464 eqnRGB
= BLENDFUNC_MIN
;
465 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
468 eqnRGB
= BLENDFUNC_MAX
;
469 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
471 case GL_FUNC_SUBTRACT
:
472 eqnRGB
= BLENDFUNC_SUB
;
474 case GL_FUNC_REVERSE_SUBTRACT
:
475 eqnRGB
= BLENDFUNC_RVRSE_SUB
;
478 fprintf( stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
479 __func__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
484 funcA
= SRC_ABLEND_FACT( blend_factor( ctx
->Color
.BlendSrcA
, GL_TRUE
) )
485 | DST_ABLEND_FACT( blend_factor( ctx
->Color
.BlendDstA
, GL_FALSE
) );
487 switch(ctx
->Color
.BlendEquationA
) {
489 eqnA
= BLENDFUNC_ADD
;
492 eqnA
= BLENDFUNC_MIN
;
493 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
496 eqnA
= BLENDFUNC_MAX
;
497 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
499 case GL_FUNC_SUBTRACT
:
500 eqnA
= BLENDFUNC_SUB
;
502 case GL_FUNC_REVERSE_SUBTRACT
:
503 eqnA
= BLENDFUNC_RVRSE_SUB
;
506 fprintf( stderr
, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
507 __func__
, __LINE__
, ctx
->Color
.BlendEquationA
);
511 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
513 imesa
->Setup
[I830_CTXREG_STATE1
] = eqnRGB
| funcRGB
514 | STATE3D_MODES_1_CMD
515 | ENABLE_SRC_BLND_FACTOR
| ENABLE_DST_BLND_FACTOR
516 | ENABLE_COLR_BLND_FUNC
;
518 imesa
->Setup
[I830_CTXREG_IALPHAB
] = eqnA
| funcA
519 | STATE3D_INDPT_ALPHA_BLEND_CMD
520 | ENABLE_SRC_ABLEND_FACTOR
| ENABLE_DST_ABLEND_FACTOR
521 | ENABLE_ALPHA_BLENDFUNC
;
524 /* This will catch a logicop blend equation. It will also ensure
525 * independant alpha blend is really in the correct state (either enabled
526 * or disabled) if blending is already enabled.
529 i830EvalLogicOpBlendState(ctx
);
532 fprintf(stderr
, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
534 imesa
->Setup
[I830_CTXREG_STATE1
],
535 imesa
->Setup
[I830_CTXREG_IALPHAB
],
536 (ctx
->Color
.BlendEnabled
) ? "en" : "dis");
540 static void i830BlendEquationSeparate(GLcontext
*ctx
,
541 GLenum modeRGB
, GLenum modeA
)
543 if (I830_DEBUG
&DEBUG_DRI
)
544 fprintf(stderr
, "%s -> %s, %s\n", __FUNCTION__
,
545 _mesa_lookup_enum_by_nr(modeRGB
),
546 _mesa_lookup_enum_by_nr(modeA
));
550 i830_set_blend_state( ctx
);
555 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
556 GLenum dfactorRGB
, GLenum sfactorA
,
559 if (I830_DEBUG
&DEBUG_DRI
)
560 fprintf(stderr
, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__
,
561 _mesa_lookup_enum_by_nr(sfactorRGB
),
562 _mesa_lookup_enum_by_nr(dfactorRGB
),
563 _mesa_lookup_enum_by_nr(sfactorA
),
564 _mesa_lookup_enum_by_nr(dfactorA
));
570 i830_set_blend_state( ctx
);
573 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
575 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
578 if (I830_DEBUG
&DEBUG_DRI
)
579 fprintf(stderr
, "%s\n", __FUNCTION__
);
583 test
= COMPAREFUNC_NEVER
;
586 test
= COMPAREFUNC_LESS
;
589 test
= COMPAREFUNC_LEQUAL
;
592 test
= COMPAREFUNC_GREATER
;
595 test
= COMPAREFUNC_GEQUAL
;
598 test
= COMPAREFUNC_NOTEQUAL
;
601 test
= COMPAREFUNC_EQUAL
;
604 test
= COMPAREFUNC_ALWAYS
;
609 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
610 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
611 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
612 DEPTH_TEST_FUNC(test
));
615 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
617 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
619 if (I830_DEBUG
&DEBUG_DRI
)
620 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
622 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
624 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
626 if (flag
&& ctx
->Depth
.Test
)
627 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
629 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
632 /* =============================================================
635 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
636 * Fortunately stipple is usually a repeating pattern.
638 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
640 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
641 const GLubyte
*m
= mask
;
644 int active
= (ctx
->Polygon
.StippleFlag
&&
645 imesa
->reduced_primitive
== GL_TRIANGLES
);
649 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
650 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
653 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
654 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
655 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
656 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
658 for (k
= 0 ; k
< 8 ; k
++)
659 for (j
= 3 ; j
>= 0; j
--)
660 for (i
= 0 ; i
< 4 ; i
++, m
++)
662 imesa
->hw_stipple
= 0;
666 newMask
= (((p
[0] & 0xf) << 0) |
667 ((p
[1] & 0xf) << 4) |
668 ((p
[2] & 0xf) << 8) |
669 ((p
[3] & 0xf) << 12));
672 if (newMask
== 0xffff || newMask
== 0x0) {
673 /* this is needed to make conform pass */
674 imesa
->hw_stipple
= 0;
678 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~0xffff;
679 imesa
->StippleSetup
[I830_STPREG_ST1
] |= newMask
;
680 imesa
->hw_stipple
= 1;
683 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
686 static void i830PolygonStippleFallback( GLcontext
*ctx
, const GLubyte
*mask
)
688 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
689 imesa
->hw_stipple
= 0;
690 (void) i830PolygonStipple
;
693 /* =============================================================
696 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
697 GLsizei w
, GLsizei h
)
699 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
701 int y1
= imesa
->driDrawable
->h
- (y
+ h
);
705 if (I830_DEBUG
&DEBUG_DRI
)
706 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
714 if (x2
>= imesa
->i830Screen
->width
) x2
= imesa
->i830Screen
->width
-1;
715 if (y2
>= imesa
->i830Screen
->height
) y2
= imesa
->i830Screen
->height
-1;
716 if (x1
>= imesa
->i830Screen
->width
) x1
= imesa
->i830Screen
->width
-1;
717 if (y1
>= imesa
->i830Screen
->height
) y1
= imesa
->i830Screen
->height
-1;
720 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
721 imesa
->BufferSetup
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
722 imesa
->BufferSetup
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
725 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
727 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
730 if (I830_DEBUG
&DEBUG_DRI
)
731 fprintf(stderr
, "%s\n", __FUNCTION__
);
733 /* FIXME: This should be a look-up table, like the r200 driver. */
742 tmp
= LOGICOP_AND_RVRSE
;
747 case GL_COPY_INVERTED
:
748 tmp
= LOGICOP_COPY_INV
;
750 case GL_AND_INVERTED
:
751 tmp
= LOGICOP_AND_INV
;
763 tmp
= LOGICOP_OR_INV
;
775 tmp
= LOGICOP_OR_RVRSE
;
787 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
788 imesa
->Setup
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
789 imesa
->Setup
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
791 /* Make sure all the enables are correct */
792 i830EvalLogicOpBlendState(ctx
);
795 /* Fallback to swrast for select and feedback.
797 static void i830RenderMode( GLcontext
*ctx
, GLenum mode
)
799 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
800 FALLBACK( imesa
, I830_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
) );
803 static void i830DrawBuffer(GLcontext
*ctx
, GLenum mode
)
805 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
808 * _ColorDrawBufferMask is easier to cope with than <mode>.
810 switch ( ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] ) {
811 case BUFFER_BIT_FRONT_LEFT
:
812 I830_FIREVERTICES(imesa
);
813 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
814 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = imesa
->i830Screen
->fbOffset
;
815 i830XMesaSetFrontClipRects( imesa
);
816 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
818 case BUFFER_BIT_BACK_LEFT
:
819 I830_FIREVERTICES(imesa
);
820 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
821 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] =
822 imesa
->i830Screen
->backOffset
;
823 i830XMesaSetBackClipRects( imesa
);
824 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_FALSE
);
827 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
828 FALLBACK( imesa
, I830_FALLBACK_DRAW_BUFFER
, GL_TRUE
);
833 static void i830ReadBuffer(GLcontext
*ctx
, GLenum mode
)
835 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
838 static void i830ClearColor(GLcontext
*ctx
, const GLfloat color
[4])
840 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
842 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_red
, color
[0]);
843 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_green
, color
[1]);
844 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_blue
, color
[2]);
845 CLAMPED_FLOAT_TO_UBYTE(imesa
->clear_alpha
, color
[3]);
847 imesa
->ClearColor
= i830PackColor(imesa
->i830Screen
->fbFormat
,
854 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
856 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
857 GLuint mode
= CULLMODE_BOTH
;
859 if (I830_DEBUG
&DEBUG_DRI
)
860 fprintf(stderr
, "%s\n", __FUNCTION__
);
862 if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
865 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
866 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
867 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
868 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
871 imesa
->LcsCullMode
= mode
;
873 if (ctx
->Polygon
.CullFlag
) {
874 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
875 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
876 imesa
->Setup
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
880 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
882 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
885 if (I830_DEBUG
&DEBUG_DRI
)
886 fprintf(stderr
, "%s\n", __FUNCTION__
);
888 width
= FloatToInt(widthf
* 2);
889 CLAMP_SELF(width
, 1, 15);
891 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
892 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_LINE_WIDTH_MASK
;
893 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_LINE_WIDTH
|
894 FIXED_LINE_WIDTH(width
));
897 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
899 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
900 GLint point_size
= FloatToInt(size
);
902 if (I830_DEBUG
&DEBUG_DRI
)
903 fprintf(stderr
, "%s\n", __FUNCTION__
);
905 CLAMP_SELF(point_size
, 1, 256);
906 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
907 imesa
->Setup
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
908 imesa
->Setup
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
909 FIXED_POINT_WIDTH(point_size
));
913 /* =============================================================
917 static void i830ColorMask(GLcontext
*ctx
,
918 GLboolean r
, GLboolean g
,
919 GLboolean b
, GLboolean a
)
921 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
924 if (I830_DEBUG
&DEBUG_DRI
)
925 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
927 imesa
->mask_red
= !r
;
928 imesa
->mask_green
= !g
;
929 imesa
->mask_blue
= !b
;
930 imesa
->mask_alpha
= !a
;
932 tmp
= (imesa
->Setup
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
935 ((!r
) << WRITEMASK_RED_SHIFT
) |
936 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
937 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
938 ((!a
) << WRITEMASK_ALPHA_SHIFT
);
940 if (tmp
!= imesa
->Setup
[I830_CTXREG_ENABLES_2
]) {
941 I830_FIREVERTICES(imesa
);
942 imesa
->dirty
|= I830_UPLOAD_CTX
;
943 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = tmp
;
947 static void update_specular( GLcontext
*ctx
)
949 i830ContextPtr imesa
= I830_CONTEXT( ctx
);
951 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
952 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
954 if (NEED_SECONDARY_COLOR(ctx
))
955 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
957 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
960 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
961 const GLfloat
*param
)
963 if (I830_DEBUG
&DEBUG_DRI
)
964 fprintf(stderr
, "%s\n", __FUNCTION__
);
966 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
967 update_specular( ctx
);
971 /* In Mesa 3.5 we can reliably do native flatshading.
973 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
975 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
976 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
979 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
981 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
983 if (mode
== GL_FLAT
) {
984 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
985 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
986 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
987 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
989 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
990 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
991 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
992 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
996 /* =============================================================
999 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
1001 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1003 if (I830_DEBUG
&DEBUG_DRI
)
1004 fprintf(stderr
, "%s\n", __FUNCTION__
);
1006 if (pname
== GL_FOG_COLOR
) {
1007 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
1008 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
1009 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
1011 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1012 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
| color
);
1016 /* =============================================================
1019 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
1021 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1025 case GL_COLOR_SUM_EXT
:
1026 update_specular( ctx
);
1030 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1031 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
1033 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
1035 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
1040 case GL_COLOR_LOGIC_OP
:
1041 case GL_INDEX_LOGIC_OP
:
1042 i830EvalLogicOpBlendState(ctx
);
1046 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1047 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
1050 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
1052 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
1056 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1057 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
1060 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
1062 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
1064 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
1066 i830DepthMask( ctx
, state
);
1069 case GL_SCISSOR_TEST
:
1070 I830_STATECHANGE(imesa
, I830_UPLOAD_BUFFERS
);
1073 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1074 (STATE3D_SCISSOR_ENABLE_CMD
|
1075 ENABLE_SCISSOR_RECT
);
1077 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] =
1078 (STATE3D_SCISSOR_ENABLE_CMD
|
1079 DISABLE_SCISSOR_RECT
);
1081 imesa
->upload_cliprects
= GL_TRUE
;
1084 case GL_LINE_SMOOTH
:
1085 if (imesa
->reduced_primitive
== GL_LINES
) {
1086 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1088 imesa
->Setup
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
1090 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
1092 imesa
->Setup
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
1097 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1098 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
1100 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_ENABLE_FOG
;
1102 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= I830_DISABLE_FOG
;
1106 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1107 imesa
->Setup
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
1109 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1110 imesa
->LcsCullMode
);
1112 imesa
->Setup
[I830_CTXREG_STATE3
] |= (ENABLE_CULL_MODE
|
1117 /* I830_STATECHANGE(imesa, I830_UPLOAD_CTX); */
1118 /* imesa->Setup[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; */
1121 case GL_STENCIL_TEST
:
1122 if (imesa
->hw_stencil
) {
1123 I830_STATECHANGE(imesa
, I830_UPLOAD_CTX
);
1124 imesa
->Setup
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
1125 imesa
->Setup
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
1128 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
1129 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
1131 imesa
->Setup
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
1132 imesa
->Setup
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
1135 FALLBACK( imesa
, I830_FALLBACK_STENCIL
, state
);
1139 case GL_POLYGON_STIPPLE
:
1141 /* The stipple command worked on my 855GM box, but not my 845G.
1142 * I'll do more testing later to find out exactly which hardware
1143 * supports it. Disabled for now.
1145 if (imesa
->hw_stipple
&& imesa
->reduced_primitive
== GL_TRIANGLES
)
1147 I830_STATECHANGE(imesa
, I830_UPLOAD_STIPPLE
);
1148 imesa
->StippleSetup
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
1150 imesa
->StippleSetup
[I830_STPREG_ST1
] |= ST1_ENABLE
;
1161 void i830EmitDrawingRectangle( i830ContextPtr imesa
)
1163 __DRIdrawablePrivate
*dPriv
= imesa
->driDrawable
;
1164 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1165 int x0
= imesa
->drawX
;
1166 int y0
= imesa
->drawY
;
1167 int x1
= x0
+ dPriv
->w
;
1168 int y1
= y0
+ dPriv
->h
;
1170 /* Don't set drawing rectangle */
1171 if (I830_DEBUG
& DEBUG_IOCTL
)
1172 fprintf(stderr
, "%s x0(%d) x1(%d) y0(%d) y1(%d)\n", __FUNCTION__
,
1175 /* Coordinate origin of the window - may be offscreen.
1177 imesa
->BufferSetup
[I830_DESTREG_DR4
] = ((y0
<<16) |
1178 (((unsigned)x0
)&0xFFFF));
1184 if (x1
> i830Screen
->width
-1) x1
= i830Screen
->width
-1;
1185 if (y1
> i830Screen
->height
-1) y1
= i830Screen
->height
-1;
1188 /* Onscreen drawing rectangle.
1190 imesa
->BufferSetup
[I830_DESTREG_DR2
] = ((y0
<<16) | x0
);
1191 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((y1
+1)<<16) | (x1
+1));
1194 /* Just add in our dirty flag, since we might be called when locked */
1195 /* Might want to modify how this is done. */
1196 imesa
->dirty
|= I830_UPLOAD_BUFFERS
;
1199 fprintf(stderr
, "[%s] DR2(0x%08x) DR3(0x%08x) DR4(0x%08x)\n",
1201 imesa
->BufferSetup
[I830_DESTREG_DR2
],
1202 imesa
->BufferSetup
[I830_DESTREG_DR3
],
1203 imesa
->BufferSetup
[I830_DESTREG_DR4
]);
1206 /* This could be done in hardware, will do once I have the driver
1209 static void i830CalcViewport( GLcontext
*ctx
)
1211 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1212 const GLfloat
*v
= ctx
->Viewport
._WindowMap
.m
;
1213 GLfloat
*m
= imesa
->ViewportMatrix
.m
;
1215 /* See also i830_translate_vertex. SUBPIXEL adjustments can be done
1216 * via state vars, too.
1218 m
[MAT_SX
] = v
[MAT_SX
];
1219 m
[MAT_TX
] = v
[MAT_TX
] + SUBPIXEL_X
;
1220 m
[MAT_SY
] = - v
[MAT_SY
];
1221 m
[MAT_TY
] = - v
[MAT_TY
] + imesa
->driDrawable
->h
+ SUBPIXEL_Y
;
1222 m
[MAT_SZ
] = v
[MAT_SZ
] * imesa
->depth_scale
;
1223 m
[MAT_TZ
] = v
[MAT_TZ
] * imesa
->depth_scale
;
1226 static void i830Viewport( GLcontext
*ctx
,
1228 GLsizei width
, GLsizei height
)
1230 /* update size of Mesa/software ancillary buffers */
1231 _mesa_ResizeBuffersMESA();
1232 i830CalcViewport( ctx
);
1235 static void i830DepthRange( GLcontext
*ctx
,
1236 GLclampd nearval
, GLclampd farval
)
1238 i830CalcViewport( ctx
);
1241 void i830PrintDirty( const char *msg
, GLuint state
)
1243 fprintf(stderr
, "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s\n",
1245 (unsigned int) state
,
1246 (state
& I830_UPLOAD_TEX0
) ? "upload-tex0, " : "",
1247 (state
& I830_UPLOAD_TEX1
) ? "upload-tex1, " : "",
1248 (state
& I830_UPLOAD_TEX2
) ? "upload-tex2, " : "",
1249 (state
& I830_UPLOAD_TEX3
) ? "upload-tex3, " : "",
1250 (state
& I830_UPLOAD_CTX
) ? "upload-ctx, " : "",
1251 (state
& I830_UPLOAD_BUFFERS
) ? "upload-bufs, " : "",
1252 (state
& I830_UPLOAD_TEXBLEND0
) ? "upload-blend0, " : "",
1253 (state
& I830_UPLOAD_TEXBLEND1
) ? "upload-blend1, " : "",
1254 (state
& I830_UPLOAD_TEXBLEND2
) ? "upload-blend2, " : "",
1255 (state
& I830_UPLOAD_TEXBLEND3
) ? "upload-blend3, " : "",
1256 (state
& I830_UPLOAD_STIPPLE
) ? "stipple, " : ""
1260 /* Push the state into the sarea and/or texture memory.
1262 void i830EmitHwStateLocked( i830ContextPtr imesa
)
1266 if (I830_DEBUG
& DEBUG_STATE
)
1267 i830PrintDirty( __FUNCTION__
, imesa
->dirty
);
1269 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1270 if ( ((imesa
->dirty
& I830_UPLOAD_TEX_N_IMAGE( i
)) != 0)
1271 && (imesa
->CurrentTexObj
[i
] != NULL
) ) {
1272 i830UploadTexImagesLocked(imesa
, imesa
->CurrentTexObj
[i
]);
1276 if (imesa
->dirty
& I830_UPLOAD_CTX
) {
1277 memcpy( imesa
->sarea
->ContextState
,
1278 imesa
->Setup
, sizeof(imesa
->Setup
) );
1281 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1282 if ((imesa
->dirty
& I830_UPLOAD_TEX_N(i
)) && imesa
->CurrentTexObj
[i
]) {
1283 unsigned * TexState
;
1285 imesa
->sarea
->dirty
|= I830_UPLOAD_TEX_N(i
);
1290 TexState
= imesa
->sarea
->TexState
[i
];
1294 TexState
= imesa
->sarea
->TexState2
;
1298 TexState
= imesa
->sarea
->TexState3
;
1302 memcpy(TexState
, imesa
->CurrentTexObj
[i
]->Setup
,
1303 sizeof(imesa
->sarea
->TexState
[i
]));
1305 TexState
[I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
1306 TexState
[I830_TEXREG_TM0S3
] |= imesa
->LodBias
[i
];
1308 /* Update the LRU usage */
1309 if (imesa
->CurrentTexObj
[i
]->base
.memBlock
)
1310 driUpdateTextureLRU( (driTextureObject
*)
1311 imesa
->CurrentTexObj
[i
] );
1314 /* Need to figure out if texturing state, or enable changed. */
1316 for ( i
= 0 ; i
< imesa
->glCtx
->Const
.MaxTextureUnits
; i
++ ) {
1317 if (imesa
->dirty
& I830_UPLOAD_TEXBLEND_N(i
)) {
1318 unsigned * TexBlendState
;
1319 unsigned * words_used
;
1321 imesa
->sarea
->dirty
|= I830_UPLOAD_TEXBLEND_N(i
);
1326 TexBlendState
= imesa
->sarea
->TexBlendState
[i
];
1327 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed
[i
];
1331 TexBlendState
= imesa
->sarea
->TexBlendState2
;
1332 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed2
;
1336 TexBlendState
= imesa
->sarea
->TexBlendState3
;
1337 words_used
= & imesa
->sarea
->TexBlendStateWordsUsed3
;
1341 memcpy(TexBlendState
, imesa
->TexBlend
[i
],
1342 imesa
->TexBlendWordsUsed
[i
] * 4);
1343 *words_used
= imesa
->TexBlendWordsUsed
[i
];
1347 if (imesa
->dirty
& I830_UPLOAD_BUFFERS
) {
1348 memcpy( imesa
->sarea
->BufferState
,imesa
->BufferSetup
,
1349 sizeof(imesa
->BufferSetup
) );
1352 if (imesa
->dirty
& I830_UPLOAD_STIPPLE
) {
1353 memcpy( imesa
->sarea
->StippleState
,imesa
->StippleSetup
,
1354 sizeof(imesa
->StippleSetup
) );
1357 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_SHARED
) {
1358 memcpy( imesa
->sarea
->Palette
[0],imesa
->palette
,
1359 sizeof(imesa
->sarea
->Palette
[0]));
1361 i830TextureObjectPtr p
;
1362 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(0)) {
1363 p
= imesa
->CurrentTexObj
[0];
1364 memcpy( imesa
->sarea
->Palette
[0],p
->palette
,
1365 sizeof(imesa
->sarea
->Palette
[0]));
1367 if (imesa
->dirty
& I830_UPLOAD_TEX_PALETTE_N(1)) {
1368 p
= imesa
->CurrentTexObj
[1];
1369 memcpy( imesa
->sarea
->Palette
[1],
1371 sizeof(imesa
->sarea
->Palette
[1]));
1375 imesa
->sarea
->dirty
|= (imesa
->dirty
& ~(I830_UPLOAD_TEX_MASK
|
1376 I830_UPLOAD_TEXBLEND_MASK
));
1378 imesa
->upload_cliprects
= GL_TRUE
;
1383 void i830DDInitState( GLcontext
*ctx
)
1385 i830ContextPtr imesa
= I830_CONTEXT(ctx
);
1386 i830ScreenPrivate
*i830Screen
= imesa
->i830Screen
;
1389 imesa
->clear_red
= 0;
1390 imesa
->clear_green
= 0;
1391 imesa
->clear_blue
= 0;
1392 imesa
->clear_alpha
= 0;
1394 imesa
->mask_red
= GL_FALSE
;
1395 imesa
->mask_green
= GL_FALSE
;
1396 imesa
->mask_blue
= GL_FALSE
;
1397 imesa
->mask_alpha
= GL_FALSE
;
1399 /* Zero all texture state */
1400 for (i
= 0; i
< I830_MAX_TEXTURE_UNITS
; i
++) {
1401 (void) memset( imesa
->TexBlend
[i
], 0, sizeof( imesa
->TexBlend
[i
] ) );
1402 (void) memset( imesa
->Init_TexBlend
[i
], 0, sizeof( imesa
->Init_TexBlend
[i
] ) );
1404 imesa
->TexBlendWordsUsed
[i
] = 0;
1405 imesa
->Init_TexBlendWordsUsed
[i
] = 0;
1408 /* Set default blend state */
1409 imesa
->TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1411 ENABLE_TEXOUTPUT_WRT_SEL
|
1412 TEXOP_OUTPUT_CURRENT
|
1413 DISABLE_TEX_CNTRL_STAGE
|
1415 TEXOP_MODIFY_PARMS
|
1418 imesa
->TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1420 ENABLE_TEXOUTPUT_WRT_SEL
|
1421 TEXOP_OUTPUT_CURRENT
|
1423 TEXOP_MODIFY_PARMS
|
1425 imesa
->TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1428 TEXBLENDARG_MODIFY_PARMS
|
1429 TEXBLENDARG_DIFFUSE
);
1430 imesa
->TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1433 TEXBLENDARG_MODIFY_PARMS
|
1434 TEXBLENDARG_DIFFUSE
);
1436 imesa
->TexBlendWordsUsed
[0] = 4;
1438 imesa
->Init_TexBlend
[0][0] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1440 ENABLE_TEXOUTPUT_WRT_SEL
|
1441 TEXOP_OUTPUT_CURRENT
|
1442 DISABLE_TEX_CNTRL_STAGE
|
1444 TEXOP_MODIFY_PARMS
|
1447 imesa
->Init_TexBlend
[0][1] = (STATE3D_MAP_BLEND_OP_CMD(0) |
1449 ENABLE_TEXOUTPUT_WRT_SEL
|
1450 TEXOP_OUTPUT_CURRENT
|
1452 TEXOP_MODIFY_PARMS
|
1454 imesa
->Init_TexBlend
[0][2] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1457 TEXBLENDARG_MODIFY_PARMS
|
1458 TEXBLENDARG_CURRENT
);
1459 imesa
->Init_TexBlend
[0][3] = (STATE3D_MAP_BLEND_ARG_CMD(0) |
1462 TEXBLENDARG_MODIFY_PARMS
|
1463 TEXBLENDARG_CURRENT
);
1464 imesa
->Init_TexBlendWordsUsed
[0] = 4;
1466 memset(imesa
->Setup
, 0, sizeof(imesa
->Setup
));
1468 imesa
->Setup
[I830_CTXREG_VF
] = 0;
1469 imesa
->Setup
[I830_CTXREG_VF2
] = 0;
1471 imesa
->Setup
[I830_CTXREG_AA
] = (STATE3D_AA_CMD
|
1472 AA_LINE_ECAAR_WIDTH_ENABLE
|
1473 AA_LINE_ECAAR_WIDTH_1_0
|
1474 AA_LINE_REGION_WIDTH_ENABLE
|
1475 AA_LINE_REGION_WIDTH_1_0
|
1478 imesa
->Setup
[I830_CTXREG_ENABLES_1
] = (STATE3D_ENABLES_1_CMD
|
1480 DISABLE_STENCIL_TEST
|
1481 DISABLE_DEPTH_BIAS
|
1484 DISABLE_ALPHA_TEST
|
1485 DISABLE_COLOR_BLEND
|
1486 DISABLE_DEPTH_TEST
);
1488 if (imesa
->hw_stencil
) {
1489 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1490 ENABLE_STENCIL_WRITE
|
1494 /* set no color comps disabled */
1495 ENABLE_COLOR_WRITE
|
1496 ENABLE_DEPTH_WRITE
);
1498 imesa
->Setup
[I830_CTXREG_ENABLES_2
] = (STATE3D_ENABLES_2_CMD
|
1499 DISABLE_STENCIL_WRITE
|
1503 /* set no color comps disabled */
1504 ENABLE_COLOR_WRITE
|
1505 ENABLE_DEPTH_WRITE
);
1508 imesa
->Setup
[I830_CTXREG_STATE1
] = (STATE3D_MODES_1_CMD
|
1509 ENABLE_COLR_BLND_FUNC
|
1511 ENABLE_SRC_BLND_FACTOR
|
1512 SRC_BLND_FACT(BLENDFACT_ONE
) |
1513 ENABLE_DST_BLND_FACTOR
|
1514 DST_BLND_FACT(BLENDFACT_ZERO
) );
1516 imesa
->Setup
[I830_CTXREG_STATE2
] = (STATE3D_MODES_2_CMD
|
1517 ENABLE_GLOBAL_DEPTH_BIAS
|
1518 GLOBAL_DEPTH_BIAS(0) |
1519 ENABLE_ALPHA_TEST_FUNC
|
1520 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1521 ALPHA_REF_VALUE(0) );
1523 imesa
->Setup
[I830_CTXREG_STATE3
] = (STATE3D_MODES_3_CMD
|
1524 ENABLE_DEPTH_TEST_FUNC
|
1525 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1526 ENABLE_ALPHA_SHADE_MODE
|
1527 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1528 ENABLE_FOG_SHADE_MODE
|
1529 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1530 ENABLE_SPEC_SHADE_MODE
|
1531 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1532 ENABLE_COLOR_SHADE_MODE
|
1533 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1537 imesa
->Setup
[I830_CTXREG_STATE4
] = (STATE3D_MODES_4_CMD
|
1538 ENABLE_LOGIC_OP_FUNC
|
1539 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1540 ENABLE_STENCIL_TEST_MASK
|
1541 STENCIL_TEST_MASK(0xff) |
1542 ENABLE_STENCIL_WRITE_MASK
|
1543 STENCIL_WRITE_MASK(0xff));
1545 imesa
->Setup
[I830_CTXREG_STENCILTST
] = (STATE3D_STENCIL_TEST_CMD
|
1546 ENABLE_STENCIL_PARMS
|
1547 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1548 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1549 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1550 ENABLE_STENCIL_TEST_FUNC
|
1551 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1552 ENABLE_STENCIL_REF_VALUE
|
1553 STENCIL_REF_VALUE(0) );
1555 imesa
->Setup
[I830_CTXREG_STATE5
] = (STATE3D_MODES_5_CMD
|
1556 FLUSH_TEXTURE_CACHE
|
1557 ENABLE_SPRITE_POINT_TEX
|
1558 SPRITE_POINT_TEX_OFF
|
1559 ENABLE_FIXED_LINE_WIDTH
|
1560 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1561 ENABLE_FIXED_POINT_WIDTH
|
1562 FIXED_POINT_WIDTH(1) );
1564 imesa
->Setup
[I830_CTXREG_IALPHAB
] = (STATE3D_INDPT_ALPHA_BLEND_CMD
|
1565 DISABLE_INDPT_ALPHA_BLEND
|
1566 ENABLE_ALPHA_BLENDFUNC
|
1569 imesa
->Setup
[I830_CTXREG_FOGCOLOR
] = (STATE3D_FOG_COLOR_CMD
|
1571 FOG_COLOR_GREEN(0) |
1574 imesa
->Setup
[I830_CTXREG_BLENDCOLR0
] = (STATE3D_CONST_BLEND_COLOR_CMD
);
1576 imesa
->Setup
[I830_CTXREG_BLENDCOLR
] = 0;
1578 imesa
->Setup
[I830_CTXREG_MCSB0
] = STATE3D_MAP_COORD_SETBIND_CMD
;
1579 imesa
->Setup
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1580 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1581 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1582 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1584 imesa
->LcsCullMode
= CULLMODE_CW
; /* GL default */
1586 memset(imesa
->BufferSetup
, 0, sizeof(imesa
->BufferSetup
));
1587 memset(imesa
->StippleSetup
, 0, sizeof(imesa
->StippleSetup
));
1590 if (imesa
->glCtx
->Visual
.doubleBufferMode
&&
1591 imesa
->sarea
->pf_current_page
== 0) {
1592 imesa
->drawMap
= i830Screen
->back
.map
;
1593 imesa
->readMap
= i830Screen
->back
.map
;
1594 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->backOffset
;
1595 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1597 /* use front buffer by default */
1598 imesa
->drawMap
= (char *)imesa
->driScreen
->pFB
;
1599 imesa
->readMap
= (char *)imesa
->driScreen
->pFB
;
1600 imesa
->BufferSetup
[I830_DESTREG_CBUFADDR
] = i830Screen
->fbOffset
;
1601 imesa
->BufferSetup
[I830_DESTREG_DBUFADDR
] = 0;
1604 imesa
->BufferSetup
[I830_DESTREG_DV0
] = STATE3D_DST_BUF_VARS_CMD
;
1606 switch (i830Screen
->fbFormat
) {
1609 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1610 DSTORG_VERT_BIAS(0x8) | /* .5 */
1611 i830Screen
->fbFormat
|
1613 DEPTH_FRMT_16_FIXED
);
1616 imesa
->BufferSetup
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1617 DSTORG_VERT_BIAS(0x8) | /* .5 */
1618 i830Screen
->fbFormat
|
1620 DEPTH_FRMT_24_FIXED_8_OTHER
);
1623 imesa
->BufferSetup
[I830_DESTREG_SENABLE
] = (STATE3D_SCISSOR_ENABLE_CMD
|
1624 DISABLE_SCISSOR_RECT
);
1625 imesa
->BufferSetup
[I830_DESTREG_SR0
] = STATE3D_SCISSOR_RECT_0_CMD
;
1626 imesa
->BufferSetup
[I830_DESTREG_SR1
] = 0;
1627 imesa
->BufferSetup
[I830_DESTREG_SR2
] = 0;
1629 imesa
->BufferSetup
[I830_DESTREG_DR0
] = STATE3D_DRAW_RECT_CMD
;
1630 imesa
->BufferSetup
[I830_DESTREG_DR1
] = 0;
1631 imesa
->BufferSetup
[I830_DESTREG_DR2
] = 0;
1632 imesa
->BufferSetup
[I830_DESTREG_DR3
] = (((i830Screen
->height
)<<16) |
1633 (i830Screen
->width
));
1634 imesa
->BufferSetup
[I830_DESTREG_DR4
] = 0;
1636 memcpy( imesa
->Init_Setup
,
1638 sizeof(imesa
->Setup
) );
1639 memcpy( imesa
->Init_BufferSetup
,
1641 sizeof(imesa
->BufferSetup
) );
1645 static void i830InvalidateState( GLcontext
*ctx
, GLuint new_state
)
1647 _swrast_InvalidateState( ctx
, new_state
);
1648 _swsetup_InvalidateState( ctx
, new_state
);
1649 _ac_InvalidateState( ctx
, new_state
);
1650 _tnl_InvalidateState( ctx
, new_state
);
1651 I830_CONTEXT(ctx
)->NewGLState
|= new_state
;
1654 void i830DDInitStateFuncs(GLcontext
*ctx
)
1656 /* Callbacks for internal Mesa events.
1658 ctx
->Driver
.UpdateState
= i830InvalidateState
;
1662 ctx
->Driver
.AlphaFunc
= i830AlphaFunc
;
1663 ctx
->Driver
.BlendEquationSeparate
= i830BlendEquationSeparate
;
1664 ctx
->Driver
.BlendFuncSeparate
= i830BlendFuncSeparate
;
1665 ctx
->Driver
.BlendColor
= i830BlendColor
;
1666 ctx
->Driver
.ClearColor
= i830ClearColor
;
1667 ctx
->Driver
.ColorMask
= i830ColorMask
;
1668 ctx
->Driver
.CullFace
= i830CullFaceFrontFace
;
1669 ctx
->Driver
.DepthFunc
= i830DepthFunc
;
1670 ctx
->Driver
.DepthMask
= i830DepthMask
;
1671 ctx
->Driver
.Enable
= i830Enable
;
1672 ctx
->Driver
.Fogfv
= i830Fogfv
;
1673 ctx
->Driver
.FrontFace
= i830CullFaceFrontFace
;
1674 ctx
->Driver
.LineWidth
= i830LineWidth
;
1675 ctx
->Driver
.PointSize
= i830PointSize
;
1676 ctx
->Driver
.LogicOpcode
= i830LogicOp
;
1677 ctx
->Driver
.PolygonStipple
= i830PolygonStippleFallback
;
1678 ctx
->Driver
.RenderMode
= i830RenderMode
;
1679 ctx
->Driver
.Scissor
= i830Scissor
;
1680 ctx
->Driver
.DrawBuffer
= i830DrawBuffer
;
1681 ctx
->Driver
.ReadBuffer
= i830ReadBuffer
;
1682 ctx
->Driver
.ShadeModel
= i830ShadeModel
;
1683 ctx
->Driver
.DepthRange
= i830DepthRange
;
1684 ctx
->Driver
.Viewport
= i830Viewport
;
1685 ctx
->Driver
.LightModelfv
= i830LightModelfv
;
1687 ctx
->Driver
.StencilFuncSeparate
= i830StencilFuncSeparate
;
1688 ctx
->Driver
.StencilMaskSeparate
= i830StencilMaskSeparate
;
1689 ctx
->Driver
.StencilOpSeparate
= i830StencilOpSeparate
;
1691 /* Pixel path fallbacks.
1693 ctx
->Driver
.Accum
= _swrast_Accum
;
1694 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
1695 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
1696 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
1697 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
1699 /* Swrast hooks for imaging extensions:
1701 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
1702 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
1703 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
1704 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;