1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 **************************************************************************/
17 #include "intel_screen.h"
18 #include "intel_batchbuffer.h"
20 #include "i830_context.h"
23 static void i830StencilFunc(GLcontext
*ctx
, GLenum func
, GLint ref
,
26 i830ContextPtr i830
= I830_CONTEXT(ctx
);
31 if (INTEL_DEBUG
&DEBUG_DRI
)
32 fprintf(stderr
, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__
,
33 _mesa_lookup_enum_by_nr(func
), ref
, mask
);
37 test
= COMPAREFUNC_NEVER
;
40 test
= COMPAREFUNC_LESS
;
43 test
= COMPAREFUNC_LEQUAL
;
46 test
= COMPAREFUNC_GREATER
;
49 test
= COMPAREFUNC_GEQUAL
;
52 test
= COMPAREFUNC_NOTEQUAL
;
55 test
= COMPAREFUNC_EQUAL
;
58 test
= COMPAREFUNC_ALWAYS
;
64 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
65 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
66 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
67 STENCIL_TEST_MASK(mask
));
68 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
69 ENABLE_STENCIL_TEST_FUNC_MASK
);
70 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
71 ENABLE_STENCIL_TEST_FUNC
|
72 STENCIL_REF_VALUE(ref
) |
73 STENCIL_TEST_FUNC(test
));
76 static void i830StencilMask(GLcontext
*ctx
, GLuint mask
)
78 i830ContextPtr i830
= I830_CONTEXT(ctx
);
80 if (INTEL_DEBUG
&DEBUG_DRI
)
81 fprintf(stderr
, "%s : mask 0x%x\n", __FUNCTION__
, mask
);
85 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
86 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
87 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
88 STENCIL_WRITE_MASK(mask
));
91 static void i830StencilOp(GLcontext
*ctx
, GLenum fail
, GLenum zfail
,
94 i830ContextPtr i830
= I830_CONTEXT(ctx
);
97 if (INTEL_DEBUG
&DEBUG_DRI
)
98 fprintf(stderr
, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__
,
99 _mesa_lookup_enum_by_nr(fail
),
100 _mesa_lookup_enum_by_nr(zfail
),
101 _mesa_lookup_enum_by_nr(zpass
));
103 fop
= 0; dfop
= 0; dpop
= 0;
107 fop
= STENCILOP_KEEP
;
110 fop
= STENCILOP_ZERO
;
113 fop
= STENCILOP_REPLACE
;
116 fop
= STENCILOP_INCRSAT
;
119 fop
= STENCILOP_DECRSAT
;
122 fop
= STENCILOP_INCR
;
125 fop
= STENCILOP_DECR
;
128 fop
= STENCILOP_INVERT
;
135 dfop
= STENCILOP_KEEP
;
138 dfop
= STENCILOP_ZERO
;
141 dfop
= STENCILOP_REPLACE
;
144 dfop
= STENCILOP_INCRSAT
;
147 dfop
= STENCILOP_DECRSAT
;
150 dfop
= STENCILOP_INCR
;
153 dfop
= STENCILOP_DECR
;
156 dfop
= STENCILOP_INVERT
;
163 dpop
= STENCILOP_KEEP
;
166 dpop
= STENCILOP_ZERO
;
169 dpop
= STENCILOP_REPLACE
;
172 dpop
= STENCILOP_INCRSAT
;
175 dpop
= STENCILOP_DECRSAT
;
178 dpop
= STENCILOP_INCR
;
181 dpop
= STENCILOP_DECR
;
184 dpop
= STENCILOP_INVERT
;
191 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
192 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
193 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
194 STENCIL_FAIL_OP(fop
) |
195 STENCIL_PASS_DEPTH_FAIL_OP(dfop
) |
196 STENCIL_PASS_DEPTH_PASS_OP(dpop
));
199 static void i830AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
201 i830ContextPtr i830
= I830_CONTEXT(ctx
);
206 UNCLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
207 refInt
= (GLuint
)refByte
;
211 test
= COMPAREFUNC_NEVER
;
214 test
= COMPAREFUNC_LESS
;
217 test
= COMPAREFUNC_LEQUAL
;
220 test
= COMPAREFUNC_GREATER
;
223 test
= COMPAREFUNC_GEQUAL
;
226 test
= COMPAREFUNC_NOTEQUAL
;
229 test
= COMPAREFUNC_EQUAL
;
232 test
= COMPAREFUNC_ALWAYS
;
238 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
239 i830
->state
.Ctx
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
240 i830
->state
.Ctx
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
241 ENABLE_ALPHA_REF_VALUE
|
242 ALPHA_TEST_FUNC(test
) |
243 ALPHA_REF_VALUE(refInt
));
246 /* This function makes sure that the proper enables are
247 * set for LogicOp, Independant Alpha Blend, and Blending.
248 * It needs to be called from numerous places where we
249 * could change the LogicOp or Independant Alpha Blend without subsequent
252 static void i830EvalLogicOpBlendState(GLcontext
*ctx
)
254 i830ContextPtr i830
= I830_CONTEXT(ctx
);
256 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
258 if (ctx
->Color
._LogicOpEnabled
) {
259 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
260 ENABLE_LOGIC_OP_MASK
);
261 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
263 } else if (ctx
->Color
.BlendEnabled
) {
264 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
265 ENABLE_LOGIC_OP_MASK
);
266 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
269 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
270 ENABLE_LOGIC_OP_MASK
);
271 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
276 static void i830BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
278 i830ContextPtr i830
= I830_CONTEXT(ctx
);
281 if (INTEL_DEBUG
&DEBUG_DRI
)
282 fprintf(stderr
, "%s\n", __FUNCTION__
);
284 UNCLAMPED_FLOAT_TO_UBYTE(r
, color
[RCOMP
]);
285 UNCLAMPED_FLOAT_TO_UBYTE(g
, color
[GCOMP
]);
286 UNCLAMPED_FLOAT_TO_UBYTE(b
, color
[BCOMP
]);
287 UNCLAMPED_FLOAT_TO_UBYTE(a
, color
[ACOMP
]);
289 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
290 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = (a
<<24) | (r
<<16) | (g
<<8) | b
;
293 static void i830BlendEquationSeparate(GLcontext
*ctx
, GLenum modeRGB
,
296 i830ContextPtr i830
= I830_CONTEXT(ctx
);
297 int func
= ENABLE_ALPHA_BLENDFUNC
;
299 assert( modeRGB
== modeA
);
301 if (INTEL_DEBUG
&DEBUG_DRI
)
302 fprintf(stderr
, "%s %s\n", __FUNCTION__
,
303 _mesa_lookup_enum_by_nr(modeRGB
));
305 /* This will catch a logicop blend equation */
306 i830EvalLogicOpBlendState(ctx
);
310 func
|= BLENDFUNC_ADD
;
313 func
|= BLENDFUNC_MIN
;
316 func
|= BLENDFUNC_MAX
;
318 case GL_FUNC_SUBTRACT
:
319 func
|= BLENDFUNC_SUB
;
321 case GL_FUNC_REVERSE_SUBTRACT
:
322 func
|= BLENDFUNC_RVRSE_SUB
;
328 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
329 i830
->state
.Ctx
[I830_CTXREG_STATE1
] &= ~BLENDFUNC_MASK
;
330 i830
->state
.Ctx
[I830_CTXREG_STATE1
] |= func
;
335 static int translate_blend_factor( GLenum factor
)
339 return BLENDFACT_ZERO
;
341 return BLENDFACT_SRC_ALPHA
;
343 return BLENDFACT_ONE
;
345 return BLENDFACT_SRC_COLR
;
346 case GL_ONE_MINUS_SRC_COLOR
:
347 return BLENDFACT_INV_SRC_COLR
;
349 return BLENDFACT_DST_COLR
;
350 case GL_ONE_MINUS_DST_COLOR
:
351 return BLENDFACT_INV_DST_COLR
;
352 case GL_ONE_MINUS_SRC_ALPHA
:
353 return BLENDFACT_INV_SRC_ALPHA
;
355 return BLENDFACT_DST_ALPHA
;
356 case GL_ONE_MINUS_DST_ALPHA
:
357 return BLENDFACT_INV_DST_ALPHA
;
358 case GL_SRC_ALPHA_SATURATE
:
359 return BLENDFACT_SRC_ALPHA_SATURATE
;
360 case GL_CONSTANT_COLOR
:
361 return BLENDFACT_CONST_COLOR
;
362 case GL_ONE_MINUS_CONSTANT_COLOR
:
363 return BLENDFACT_INV_CONST_COLOR
;
364 case GL_CONSTANT_ALPHA
:
365 return BLENDFACT_CONST_ALPHA
;
366 case GL_ONE_MINUS_CONSTANT_ALPHA
:
367 return BLENDFACT_INV_CONST_ALPHA
;
369 return BLENDFACT_ZERO
;
373 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
374 GLenum dfactorRGB
, GLenum sfactorA
,
377 i830ContextPtr i830
= I830_CONTEXT(ctx
);
378 int iab
= i830
->state
.Ctx
[I830_CTXREG_IALPHAB
];
379 int s1
= i830
->state
.Ctx
[I830_CTXREG_STATE1
];
381 if (INTEL_DEBUG
&DEBUG_DRI
)
382 fprintf(stderr
, "%s\n", __FUNCTION__
);
385 iab
&= ~(SRC_DST_ABLEND_MASK
|ENABLE_INDPT_ALPHA_BLEND
);
386 s1
&= ~SRC_DST_BLND_MASK
;
388 iab
|= (ENABLE_SRC_ABLEND_FACTOR
|ENABLE_DST_ABLEND_FACTOR
);
389 s1
|= (ENABLE_SRC_BLND_FACTOR
|ENABLE_DST_BLND_FACTOR
);
391 if (ctx
->Color
.BlendEquationRGB
== GL_MIN
||
392 ctx
->Color
.BlendEquationRGB
== GL_MAX
) {
393 sfactorA
= sfactorRGB
= dfactorA
= dfactorRGB
= GL_ONE
;
396 iab
|= SRC_ABLEND_FACT(translate_blend_factor(sfactorA
));
397 iab
|= DST_ABLEND_FACT(translate_blend_factor(dfactorA
));
398 s1
|= SRC_BLND_FACT(translate_blend_factor(sfactorRGB
));
399 s1
|= DST_BLND_FACT(translate_blend_factor(dfactorRGB
));
401 if (sfactorA
!= sfactorRGB
|| dfactorA
!= dfactorRGB
)
402 iab
|= ENABLE_INDPT_ALPHA_BLEND
;
404 iab
|= DISABLE_INDPT_ALPHA_BLEND
;
406 if (iab
!= i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] ||
407 s1
!= i830
->state
.Ctx
[I830_CTXREG_STATE1
]) {
408 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
409 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = iab
;
410 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = s1
;
416 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
418 i830ContextPtr i830
= I830_CONTEXT(ctx
);
421 if (INTEL_DEBUG
&DEBUG_DRI
)
422 fprintf(stderr
, "%s\n", __FUNCTION__
);
426 test
= COMPAREFUNC_NEVER
;
429 test
= COMPAREFUNC_LESS
;
432 test
= COMPAREFUNC_LEQUAL
;
435 test
= COMPAREFUNC_GREATER
;
438 test
= COMPAREFUNC_GEQUAL
;
441 test
= COMPAREFUNC_NOTEQUAL
;
444 test
= COMPAREFUNC_EQUAL
;
447 test
= COMPAREFUNC_ALWAYS
;
452 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
453 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
454 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
455 DEPTH_TEST_FUNC(test
));
458 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
460 i830ContextPtr i830
= I830_CONTEXT(ctx
);
462 if (INTEL_DEBUG
&DEBUG_DRI
)
463 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
465 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
467 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
469 if (flag
&& ctx
->Depth
.Test
)
470 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
472 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
475 /* =============================================================
478 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
479 * Fortunately stipple is usually a repeating pattern.
481 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
483 i830ContextPtr i830
= I830_CONTEXT(ctx
);
484 const GLubyte
*m
= mask
;
487 int active
= (ctx
->Polygon
.StippleFlag
&&
488 i830
->intel
.reduced_primitive
== GL_TRIANGLES
);
492 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
493 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
496 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
497 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
498 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
499 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
501 for (k
= 0 ; k
< 8 ; k
++)
502 for (j
= 3 ; j
>= 0; j
--)
503 for (i
= 0 ; i
< 4 ; i
++, m
++)
505 i830
->intel
.hw_stipple
= 0;
509 newMask
= (((p
[0] & 0xf) << 0) |
510 ((p
[1] & 0xf) << 4) |
511 ((p
[2] & 0xf) << 8) |
512 ((p
[3] & 0xf) << 12));
515 if (newMask
== 0xffff || newMask
== 0x0) {
516 /* this is needed to make conform pass */
517 i830
->intel
.hw_stipple
= 0;
521 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~0xffff;
522 i830
->state
.Stipple
[I830_STPREG_ST1
] |= newMask
;
523 i830
->intel
.hw_stipple
= 1;
526 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
530 /* =============================================================
533 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
534 GLsizei w
, GLsizei h
)
536 i830ContextPtr i830
= I830_CONTEXT(ctx
);
537 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
540 if (!i830
->intel
.driDrawable
)
544 y1
= i830
->intel
.driDrawable
->h
- (y
+ h
);
548 if (INTEL_DEBUG
&DEBUG_DRI
)
549 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
557 if (x2
>= screen
->width
) x2
= screen
->width
-1;
558 if (y2
>= screen
->height
) y2
= screen
->height
-1;
559 if (x1
>= screen
->width
) x1
= screen
->width
-1;
560 if (y1
>= screen
->height
) y1
= screen
->height
-1;
563 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
564 i830
->state
.Buffer
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
565 i830
->state
.Buffer
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
568 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
570 i830ContextPtr i830
= I830_CONTEXT(ctx
);
573 if (INTEL_DEBUG
&DEBUG_DRI
)
574 fprintf(stderr
, "%s\n", __FUNCTION__
);
576 /* FIXME: This should be a look-up table, like the r200 driver. */
585 tmp
= LOGICOP_AND_RVRSE
;
590 case GL_COPY_INVERTED
:
591 tmp
= LOGICOP_COPY_INV
;
593 case GL_AND_INVERTED
:
594 tmp
= LOGICOP_AND_INV
;
606 tmp
= LOGICOP_OR_INV
;
618 tmp
= LOGICOP_OR_RVRSE
;
630 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
631 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
632 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
637 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
639 i830ContextPtr i830
= I830_CONTEXT(ctx
);
642 if (INTEL_DEBUG
&DEBUG_DRI
)
643 fprintf(stderr
, "%s\n", __FUNCTION__
);
645 if (!ctx
->Polygon
.CullFlag
) {
646 mode
= CULLMODE_NONE
;
648 else if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
651 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
652 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
653 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
654 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
657 mode
= CULLMODE_BOTH
;
660 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
661 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
662 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
665 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
667 i830ContextPtr i830
= I830_CONTEXT( ctx
);
671 if (INTEL_DEBUG
&DEBUG_DRI
)
672 fprintf(stderr
, "%s\n", __FUNCTION__
);
674 width
= (int)(widthf
* 2);
675 CLAMP_SELF(width
, 1, 15);
677 state5
= i830
->state
.Ctx
[I830_CTXREG_STATE5
] & ~FIXED_LINE_WIDTH_MASK
;
678 state5
|= (ENABLE_FIXED_LINE_WIDTH
| FIXED_LINE_WIDTH(width
));
680 if (state5
!= i830
->state
.Ctx
[I830_CTXREG_STATE5
]) {
681 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
682 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = state5
;
686 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
688 i830ContextPtr i830
= I830_CONTEXT(ctx
);
689 GLint point_size
= (int)size
;
691 if (INTEL_DEBUG
&DEBUG_DRI
)
692 fprintf(stderr
, "%s\n", __FUNCTION__
);
694 CLAMP_SELF(point_size
, 1, 256);
695 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
696 i830
->state
.Ctx
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
697 i830
->state
.Ctx
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
698 FIXED_POINT_WIDTH(point_size
));
702 /* =============================================================
706 static void i830ColorMask(GLcontext
*ctx
,
707 GLboolean r
, GLboolean g
,
708 GLboolean b
, GLboolean a
)
710 i830ContextPtr i830
= I830_CONTEXT( ctx
);
713 if (INTEL_DEBUG
&DEBUG_DRI
)
714 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
716 tmp
= ((i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
719 ((!r
) << WRITEMASK_RED_SHIFT
) |
720 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
721 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
722 ((!a
) << WRITEMASK_ALPHA_SHIFT
));
724 if (tmp
!= i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
]) {
725 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
726 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = tmp
;
730 static void update_specular( GLcontext
*ctx
)
732 i830ContextPtr i830
= I830_CONTEXT( ctx
);
734 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
735 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
737 if (NEED_SECONDARY_COLOR(ctx
))
738 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
740 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
743 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
744 const GLfloat
*param
)
746 if (INTEL_DEBUG
&DEBUG_DRI
)
747 fprintf(stderr
, "%s\n", __FUNCTION__
);
749 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
750 update_specular( ctx
);
754 /* In Mesa 3.5 we can reliably do native flatshading.
756 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
758 i830ContextPtr i830
= I830_CONTEXT(ctx
);
759 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
762 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
764 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
766 if (mode
== GL_FLAT
) {
767 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
768 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
769 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
770 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
772 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
773 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
774 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
775 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
779 /* =============================================================
782 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
784 i830ContextPtr i830
= I830_CONTEXT(ctx
);
786 if (INTEL_DEBUG
&DEBUG_DRI
)
787 fprintf(stderr
, "%s\n", __FUNCTION__
);
789 if (pname
== GL_FOG_COLOR
) {
790 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
791 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
792 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
794 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
795 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
| color
);
799 /* =============================================================
802 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
804 i830ContextPtr i830
= I830_CONTEXT(ctx
);
809 update_specular( ctx
);
813 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
814 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
816 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
818 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
823 i830EvalLogicOpBlendState(ctx
);
826 case GL_COLOR_LOGIC_OP
:
827 i830EvalLogicOpBlendState(ctx
);
829 /* Logicop doesn't seem to work at 16bpp:
831 if (i830
->intel
.intelScreen
->cpp
== 2)
832 FALLBACK( &i830
->intel
, I830_FALLBACK_LOGICOP
, state
);
836 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
837 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
840 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
842 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
846 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
847 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
850 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
852 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
854 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
856 i830DepthMask( ctx
, ctx
->Depth
.Mask
);
859 case GL_SCISSOR_TEST
:
860 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
863 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
864 (_3DSTATE_SCISSOR_ENABLE_CMD
|
865 ENABLE_SCISSOR_RECT
);
867 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
868 (_3DSTATE_SCISSOR_ENABLE_CMD
|
869 DISABLE_SCISSOR_RECT
);
874 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
876 i830
->state
.Ctx
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
878 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
880 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
884 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
885 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
887 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_FOG
;
889 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_FOG
;
893 i830CullFaceFrontFace(ctx
, 0);
899 case GL_STENCIL_TEST
:
900 if (i830
->intel
.hw_stencil
) {
901 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
904 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
905 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
907 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
908 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
909 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
910 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
913 FALLBACK( &i830
->intel
, I830_FALLBACK_STENCIL
, state
);
917 case GL_POLYGON_STIPPLE
:
918 /* The stipple command worked on my 855GM box, but not my 845G.
919 * I'll do more testing later to find out exactly which hardware
920 * supports it. Disabled for now.
922 if (i830
->intel
.hw_stipple
&&
923 i830
->intel
.reduced_primitive
== GL_TRIANGLES
)
925 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
926 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
928 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
938 static void i830_init_packets( i830ContextPtr i830
)
940 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
943 memset(&i830
->state
, 0, sizeof(i830
->state
));
945 /* Set default blend state */
946 i830
->state
.TexBlend
[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
948 ENABLE_TEXOUTPUT_WRT_SEL
|
949 TEXOP_OUTPUT_CURRENT
|
950 DISABLE_TEX_CNTRL_STAGE
|
955 i830
->state
.TexBlend
[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
957 ENABLE_TEXOUTPUT_WRT_SEL
|
958 TEXOP_OUTPUT_CURRENT
|
962 i830
->state
.TexBlend
[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
965 TEXBLENDARG_MODIFY_PARMS
|
966 TEXBLENDARG_DIFFUSE
);
967 i830
->state
.TexBlend
[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
970 TEXBLENDARG_MODIFY_PARMS
|
971 TEXBLENDARG_DIFFUSE
);
973 i830
->state
.TexBlendWordsUsed
[0] = 4;
976 i830
->state
.Ctx
[I830_CTXREG_VF
] = 0;
977 i830
->state
.Ctx
[I830_CTXREG_VF2
] = 0;
979 i830
->state
.Ctx
[I830_CTXREG_AA
] = (_3DSTATE_AA_CMD
|
980 AA_LINE_ECAAR_WIDTH_ENABLE
|
981 AA_LINE_ECAAR_WIDTH_1_0
|
982 AA_LINE_REGION_WIDTH_ENABLE
|
983 AA_LINE_REGION_WIDTH_1_0
|
986 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] = (_3DSTATE_ENABLES_1_CMD
|
988 DISABLE_STENCIL_TEST
|
993 DISABLE_COLOR_BLEND
|
996 if (i830
->intel
.hw_stencil
) {
997 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
998 ENABLE_STENCIL_WRITE
|
1002 /* set no color comps disabled */
1003 ENABLE_COLOR_WRITE
|
1004 ENABLE_DEPTH_WRITE
);
1006 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
1007 DISABLE_STENCIL_WRITE
|
1011 /* set no color comps disabled */
1012 ENABLE_COLOR_WRITE
|
1013 ENABLE_DEPTH_WRITE
);
1016 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = (_3DSTATE_MODES_1_CMD
|
1017 ENABLE_COLR_BLND_FUNC
|
1019 ENABLE_SRC_BLND_FACTOR
|
1020 SRC_BLND_FACT(BLENDFACT_ONE
) |
1021 ENABLE_DST_BLND_FACTOR
|
1022 DST_BLND_FACT(BLENDFACT_ZERO
) );
1024 i830
->state
.Ctx
[I830_CTXREG_STATE2
] = (_3DSTATE_MODES_2_CMD
|
1025 ENABLE_GLOBAL_DEPTH_BIAS
|
1026 GLOBAL_DEPTH_BIAS(0) |
1027 ENABLE_ALPHA_TEST_FUNC
|
1028 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1029 ALPHA_REF_VALUE(0) );
1031 i830
->state
.Ctx
[I830_CTXREG_STATE3
] = (_3DSTATE_MODES_3_CMD
|
1032 ENABLE_DEPTH_TEST_FUNC
|
1033 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1034 ENABLE_ALPHA_SHADE_MODE
|
1035 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
1036 ENABLE_FOG_SHADE_MODE
|
1037 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1038 ENABLE_SPEC_SHADE_MODE
|
1039 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1040 ENABLE_COLOR_SHADE_MODE
|
1041 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
1045 i830
->state
.Ctx
[I830_CTXREG_STATE4
] = (_3DSTATE_MODES_4_CMD
|
1046 ENABLE_LOGIC_OP_FUNC
|
1047 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1048 ENABLE_STENCIL_TEST_MASK
|
1049 STENCIL_TEST_MASK(0xff) |
1050 ENABLE_STENCIL_WRITE_MASK
|
1051 STENCIL_WRITE_MASK(0xff));
1053 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] = (_3DSTATE_STENCIL_TEST_CMD
|
1054 ENABLE_STENCIL_PARMS
|
1055 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
1056 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
1057 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
1058 ENABLE_STENCIL_TEST_FUNC
|
1059 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
1060 ENABLE_STENCIL_REF_VALUE
|
1061 STENCIL_REF_VALUE(0) );
1063 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = (_3DSTATE_MODES_5_CMD
|
1064 FLUSH_TEXTURE_CACHE
|
1065 ENABLE_SPRITE_POINT_TEX
|
1066 SPRITE_POINT_TEX_OFF
|
1067 ENABLE_FIXED_LINE_WIDTH
|
1068 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1069 ENABLE_FIXED_POINT_WIDTH
|
1070 FIXED_POINT_WIDTH(1) );
1072 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD
|
1073 DISABLE_INDPT_ALPHA_BLEND
|
1074 ENABLE_ALPHA_BLENDFUNC
|
1077 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
|
1079 FOG_COLOR_GREEN(0) |
1082 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR0
] = _3DSTATE_CONST_BLEND_COLOR_CMD
;
1083 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = 0;
1085 i830
->state
.Ctx
[I830_CTXREG_MCSB0
] = _3DSTATE_MAP_COORD_SETBIND_CMD
;
1086 i830
->state
.Ctx
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1087 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1088 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1089 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1092 i830
->state
.Stipple
[I830_STPREG_ST0
] = _3DSTATE_STIPPLE
;
1094 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1095 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR1
] =
1096 (BUF_3D_ID_COLOR_BACK
|
1097 BUF_3D_PITCH(screen
->frontPitch
* screen
->cpp
) |
1101 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1102 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR1
] =
1104 BUF_3D_PITCH(screen
->depthPitch
* screen
->cpp
) |
1106 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR2
] = screen
->depthOffset
;
1109 i830
->state
.Buffer
[I830_DESTREG_DV0
] = _3DSTATE_DST_BUF_VARS_CMD
;
1111 switch (screen
->fbFormat
) {
1114 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1115 DSTORG_VERT_BIAS(0x8) | /* .5 */
1118 DEPTH_FRMT_16_FIXED
);
1121 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1122 DSTORG_VERT_BIAS(0x8) | /* .5 */
1125 DEPTH_FRMT_24_FIXED_8_OTHER
);
1129 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] = (_3DSTATE_SCISSOR_ENABLE_CMD
|
1130 DISABLE_SCISSOR_RECT
);
1131 i830
->state
.Buffer
[I830_DESTREG_SR0
] = _3DSTATE_SCISSOR_RECT_0_CMD
;
1132 i830
->state
.Buffer
[I830_DESTREG_SR1
] = 0;
1133 i830
->state
.Buffer
[I830_DESTREG_SR2
] = 0;
1137 void i830InitStateFuncs( struct dd_function_table
*functions
)
1139 functions
->AlphaFunc
= i830AlphaFunc
;
1140 functions
->BlendColor
= i830BlendColor
;
1141 functions
->BlendEquationSeparate
= i830BlendEquationSeparate
;
1142 functions
->BlendFuncSeparate
= i830BlendFuncSeparate
;
1143 functions
->ColorMask
= i830ColorMask
;
1144 functions
->CullFace
= i830CullFaceFrontFace
;
1145 functions
->DepthFunc
= i830DepthFunc
;
1146 functions
->DepthMask
= i830DepthMask
;
1147 functions
->Enable
= i830Enable
;
1148 functions
->Fogfv
= i830Fogfv
;
1149 functions
->FrontFace
= i830CullFaceFrontFace
;
1150 functions
->LightModelfv
= i830LightModelfv
;
1151 functions
->LineWidth
= i830LineWidth
;
1152 functions
->LogicOpcode
= i830LogicOp
;
1153 functions
->PointSize
= i830PointSize
;
1154 functions
->PolygonStipple
= i830PolygonStipple
;
1155 functions
->Scissor
= i830Scissor
;
1156 functions
->ShadeModel
= i830ShadeModel
;
1157 functions
->StencilFunc
= i830StencilFunc
;
1158 functions
->StencilMask
= i830StencilMask
;
1159 functions
->StencilOp
= i830StencilOp
;
1162 void i830InitState( i830ContextPtr i830
)
1164 GLcontext
*ctx
= &i830
->intel
.ctx
;
1166 i830_init_packets( i830
);
1168 intelInitState( ctx
);
1170 memcpy( &i830
->initial
, &i830
->state
, sizeof(i830
->state
) );
1172 i830
->current
= &i830
->state
;
1173 i830
->state
.emitted
= 0;
1174 i830
->state
.active
= (I830_UPLOAD_TEXBLEND(0) |
1175 I830_UPLOAD_STIPPLE
|
1177 I830_UPLOAD_BUFFERS
);