1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
37 #include "intel_screen.h"
38 #include "intel_batchbuffer.h"
40 #include "i830_context.h"
44 i830StencilFuncSeparate(GLcontext
*ctx
, GLenum face
, GLenum func
, GLint ref
,
47 i830ContextPtr i830
= I830_CONTEXT(ctx
);
48 int test
= intel_translate_compare_func(func
);
52 if (INTEL_DEBUG
&DEBUG_DRI
)
53 fprintf(stderr
, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__
,
54 _mesa_lookup_enum_by_nr(func
), ref
, mask
);
57 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
58 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
59 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
60 STENCIL_TEST_MASK(mask
));
61 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
62 ENABLE_STENCIL_TEST_FUNC_MASK
);
63 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
64 ENABLE_STENCIL_TEST_FUNC
|
65 STENCIL_REF_VALUE(ref
) |
66 STENCIL_TEST_FUNC(test
));
70 i830StencilMaskSeparate(GLcontext
*ctx
, GLenum face
, GLuint mask
)
72 i830ContextPtr i830
= I830_CONTEXT(ctx
);
74 if (INTEL_DEBUG
&DEBUG_DRI
)
75 fprintf(stderr
, "%s : mask 0x%x\n", __FUNCTION__
, mask
);
79 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
80 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
81 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
82 STENCIL_WRITE_MASK(mask
));
86 i830StencilOpSeparate(GLcontext
*ctx
, GLenum face
, GLenum fail
, GLenum zfail
,
89 i830ContextPtr i830
= I830_CONTEXT(ctx
);
92 if (INTEL_DEBUG
&DEBUG_DRI
)
93 fprintf(stderr
, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__
,
94 _mesa_lookup_enum_by_nr(fail
),
95 _mesa_lookup_enum_by_nr(zfail
),
96 _mesa_lookup_enum_by_nr(zpass
));
98 fop
= 0; dfop
= 0; dpop
= 0;
102 fop
= STENCILOP_KEEP
;
105 fop
= STENCILOP_ZERO
;
108 fop
= STENCILOP_REPLACE
;
111 fop
= STENCILOP_INCRSAT
;
114 fop
= STENCILOP_DECRSAT
;
117 fop
= STENCILOP_INCR
;
120 fop
= STENCILOP_DECR
;
123 fop
= STENCILOP_INVERT
;
130 dfop
= STENCILOP_KEEP
;
133 dfop
= STENCILOP_ZERO
;
136 dfop
= STENCILOP_REPLACE
;
139 dfop
= STENCILOP_INCRSAT
;
142 dfop
= STENCILOP_DECRSAT
;
145 dfop
= STENCILOP_INCR
;
148 dfop
= STENCILOP_DECR
;
151 dfop
= STENCILOP_INVERT
;
158 dpop
= STENCILOP_KEEP
;
161 dpop
= STENCILOP_ZERO
;
164 dpop
= STENCILOP_REPLACE
;
167 dpop
= STENCILOP_INCRSAT
;
170 dpop
= STENCILOP_DECRSAT
;
173 dpop
= STENCILOP_INCR
;
176 dpop
= STENCILOP_DECR
;
179 dpop
= STENCILOP_INVERT
;
186 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
187 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
188 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
189 STENCIL_FAIL_OP(fop
) |
190 STENCIL_PASS_DEPTH_FAIL_OP(dfop
) |
191 STENCIL_PASS_DEPTH_PASS_OP(dpop
));
194 static void i830AlphaFunc(GLcontext
*ctx
, GLenum func
, GLfloat ref
)
196 i830ContextPtr i830
= I830_CONTEXT(ctx
);
197 int test
= intel_translate_compare_func(func
);
201 UNCLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
202 refInt
= (GLuint
)refByte
;
204 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
205 i830
->state
.Ctx
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
206 i830
->state
.Ctx
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
207 ENABLE_ALPHA_REF_VALUE
|
208 ALPHA_TEST_FUNC(test
) |
209 ALPHA_REF_VALUE(refInt
));
213 * Makes sure that the proper enables are set for LogicOp, Independant Alpha
214 * Blend, and Blending. It needs to be called from numerous places where we
215 * could change the LogicOp or Independant Alpha Blend without subsequent
219 * This function is substantially different from the old i830-specific driver.
220 * I'm not sure which is correct.
222 static void i830EvalLogicOpBlendState(GLcontext
*ctx
)
224 i830ContextPtr i830
= I830_CONTEXT(ctx
);
226 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
228 if (RGBA_LOGICOP_ENABLED(ctx
)) {
229 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
230 ENABLE_LOGIC_OP_MASK
);
231 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
233 } else if (ctx
->Color
.BlendEnabled
) {
234 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
235 ENABLE_LOGIC_OP_MASK
);
236 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
239 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
240 ENABLE_LOGIC_OP_MASK
);
241 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
246 static void i830BlendColor(GLcontext
*ctx
, const GLfloat color
[4])
248 i830ContextPtr i830
= I830_CONTEXT(ctx
);
251 if (INTEL_DEBUG
&DEBUG_DRI
)
252 fprintf(stderr
, "%s\n", __FUNCTION__
);
254 UNCLAMPED_FLOAT_TO_UBYTE(r
, color
[RCOMP
]);
255 UNCLAMPED_FLOAT_TO_UBYTE(g
, color
[GCOMP
]);
256 UNCLAMPED_FLOAT_TO_UBYTE(b
, color
[BCOMP
]);
257 UNCLAMPED_FLOAT_TO_UBYTE(a
, color
[ACOMP
]);
259 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
260 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = (a
<<24) | (r
<<16) | (g
<<8) | b
;
264 * Sets both the blend equation (called "function" in i830 docs) and the
265 * blend function (called "factor" in i830 docs). This is done in a single
266 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
267 * change the interpretation of the blend function.
269 static void i830_set_blend_state( GLcontext
* ctx
)
271 i830ContextPtr i830
= I830_CONTEXT(ctx
);
280 funcRGB
= SRC_BLND_FACT( intel_translate_blend_factor( ctx
->Color
.BlendSrcRGB
) )
281 | DST_BLND_FACT( intel_translate_blend_factor( ctx
->Color
.BlendDstRGB
) );
283 switch(ctx
->Color
.BlendEquationRGB
) {
285 eqnRGB
= BLENDFUNC_ADD
;
288 eqnRGB
= BLENDFUNC_MIN
;
289 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
292 eqnRGB
= BLENDFUNC_MAX
;
293 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
295 case GL_FUNC_SUBTRACT
:
296 eqnRGB
= BLENDFUNC_SUB
;
298 case GL_FUNC_REVERSE_SUBTRACT
:
299 eqnRGB
= BLENDFUNC_RVRSE_SUB
;
302 fprintf( stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
303 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
308 funcA
= SRC_ABLEND_FACT( intel_translate_blend_factor( ctx
->Color
.BlendSrcA
) )
309 | DST_ABLEND_FACT( intel_translate_blend_factor( ctx
->Color
.BlendDstA
) );
311 switch(ctx
->Color
.BlendEquationA
) {
313 eqnA
= BLENDFUNC_ADD
;
316 eqnA
= BLENDFUNC_MIN
;
317 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
320 eqnA
= BLENDFUNC_MAX
;
321 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
323 case GL_FUNC_SUBTRACT
:
324 eqnA
= BLENDFUNC_SUB
;
326 case GL_FUNC_REVERSE_SUBTRACT
:
327 eqnA
= BLENDFUNC_RVRSE_SUB
;
330 fprintf( stderr
, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
331 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
336 | _3DSTATE_INDPT_ALPHA_BLEND_CMD
337 | ENABLE_SRC_ABLEND_FACTOR
| ENABLE_DST_ABLEND_FACTOR
338 | ENABLE_ALPHA_BLENDFUNC
;
339 s1
= eqnRGB
| funcRGB
340 | _3DSTATE_MODES_1_CMD
341 | ENABLE_SRC_BLND_FACTOR
| ENABLE_DST_BLND_FACTOR
342 | ENABLE_COLR_BLND_FUNC
;
344 if ( (eqnA
| funcA
) != (eqnRGB
| funcRGB
) )
345 iab
|= ENABLE_INDPT_ALPHA_BLEND
;
347 iab
|= DISABLE_INDPT_ALPHA_BLEND
;
349 if (iab
!= i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] ||
350 s1
!= i830
->state
.Ctx
[I830_CTXREG_STATE1
]) {
351 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
352 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = iab
;
353 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = s1
;
356 /* This will catch a logicop blend equation. It will also ensure
357 * independant alpha blend is really in the correct state (either enabled
358 * or disabled) if blending is already enabled.
361 i830EvalLogicOpBlendState(ctx
);
364 fprintf(stderr
, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
365 __FUNCTION__
, __LINE__
,
366 i830
->state
.Ctx
[I830_CTXREG_STATE1
],
367 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
],
368 (ctx
->Color
.BlendEnabled
) ? "en" : "dis");
373 static void i830BlendEquationSeparate(GLcontext
*ctx
, GLenum modeRGB
,
376 if (INTEL_DEBUG
&DEBUG_DRI
)
377 fprintf(stderr
, "%s -> %s, %s\n", __FUNCTION__
,
378 _mesa_lookup_enum_by_nr(modeRGB
),
379 _mesa_lookup_enum_by_nr(modeA
));
383 i830_set_blend_state( ctx
);
387 static void i830BlendFuncSeparate(GLcontext
*ctx
, GLenum sfactorRGB
,
388 GLenum dfactorRGB
, GLenum sfactorA
,
391 if (INTEL_DEBUG
&DEBUG_DRI
)
392 fprintf(stderr
, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__
,
393 _mesa_lookup_enum_by_nr(sfactorRGB
),
394 _mesa_lookup_enum_by_nr(dfactorRGB
),
395 _mesa_lookup_enum_by_nr(sfactorA
),
396 _mesa_lookup_enum_by_nr(dfactorA
));
402 i830_set_blend_state( ctx
);
407 static void i830DepthFunc(GLcontext
*ctx
, GLenum func
)
409 i830ContextPtr i830
= I830_CONTEXT(ctx
);
410 int test
= intel_translate_compare_func(func
);
412 if (INTEL_DEBUG
&DEBUG_DRI
)
413 fprintf(stderr
, "%s\n", __FUNCTION__
);
415 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
416 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
417 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
418 DEPTH_TEST_FUNC(test
));
421 static void i830DepthMask(GLcontext
*ctx
, GLboolean flag
)
423 i830ContextPtr i830
= I830_CONTEXT(ctx
);
425 if (INTEL_DEBUG
&DEBUG_DRI
)
426 fprintf(stderr
, "%s flag (%d)\n", __FUNCTION__
, flag
);
428 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
430 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
432 if (flag
&& ctx
->Depth
.Test
)
433 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
435 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
438 /* =============================================================
441 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
442 * Fortunately stipple is usually a repeating pattern.
444 static void i830PolygonStipple( GLcontext
*ctx
, const GLubyte
*mask
)
446 i830ContextPtr i830
= I830_CONTEXT(ctx
);
447 const GLubyte
*m
= mask
;
450 int active
= (ctx
->Polygon
.StippleFlag
&&
451 i830
->intel
.reduced_primitive
== GL_TRIANGLES
);
455 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
456 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
459 p
[0] = mask
[12] & 0xf; p
[0] |= p
[0] << 4;
460 p
[1] = mask
[8] & 0xf; p
[1] |= p
[1] << 4;
461 p
[2] = mask
[4] & 0xf; p
[2] |= p
[2] << 4;
462 p
[3] = mask
[0] & 0xf; p
[3] |= p
[3] << 4;
464 for (k
= 0 ; k
< 8 ; k
++)
465 for (j
= 3 ; j
>= 0; j
--)
466 for (i
= 0 ; i
< 4 ; i
++, m
++)
468 i830
->intel
.hw_stipple
= 0;
472 newMask
= (((p
[0] & 0xf) << 0) |
473 ((p
[1] & 0xf) << 4) |
474 ((p
[2] & 0xf) << 8) |
475 ((p
[3] & 0xf) << 12));
478 if (newMask
== 0xffff || newMask
== 0x0) {
479 /* this is needed to make conform pass */
480 i830
->intel
.hw_stipple
= 0;
484 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~0xffff;
485 i830
->state
.Stipple
[I830_STPREG_ST1
] |= newMask
;
486 i830
->intel
.hw_stipple
= 1;
489 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
493 /* =============================================================
496 static void i830Scissor(GLcontext
*ctx
, GLint x
, GLint y
,
497 GLsizei w
, GLsizei h
)
499 i830ContextPtr i830
= I830_CONTEXT(ctx
);
500 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
503 if (!i830
->intel
.driDrawable
)
507 y1
= i830
->intel
.driDrawable
->h
- (y
+ h
);
511 if (INTEL_DEBUG
&DEBUG_DRI
)
512 fprintf(stderr
, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__
,
520 if (x2
>= screen
->width
) x2
= screen
->width
-1;
521 if (y2
>= screen
->height
) y2
= screen
->height
-1;
522 if (x1
>= screen
->width
) x1
= screen
->width
-1;
523 if (y1
>= screen
->height
) y1
= screen
->height
-1;
526 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
527 i830
->state
.Buffer
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
528 i830
->state
.Buffer
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
531 static void i830LogicOp(GLcontext
*ctx
, GLenum opcode
)
533 i830ContextPtr i830
= I830_CONTEXT(ctx
);
534 int tmp
= intel_translate_logic_op( opcode
);
536 if (INTEL_DEBUG
&DEBUG_DRI
)
537 fprintf(stderr
, "%s\n", __FUNCTION__
);
539 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
540 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
541 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
546 static void i830CullFaceFrontFace(GLcontext
*ctx
, GLenum unused
)
548 i830ContextPtr i830
= I830_CONTEXT(ctx
);
551 if (INTEL_DEBUG
&DEBUG_DRI
)
552 fprintf(stderr
, "%s\n", __FUNCTION__
);
554 if (!ctx
->Polygon
.CullFlag
) {
555 mode
= CULLMODE_NONE
;
557 else if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
560 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
561 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
562 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
563 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
566 mode
= CULLMODE_BOTH
;
569 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
570 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
571 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
574 static void i830LineWidth( GLcontext
*ctx
, GLfloat widthf
)
576 i830ContextPtr i830
= I830_CONTEXT( ctx
);
580 if (INTEL_DEBUG
&DEBUG_DRI
)
581 fprintf(stderr
, "%s\n", __FUNCTION__
);
583 width
= (int)(widthf
* 2);
584 CLAMP_SELF(width
, 1, 15);
586 state5
= i830
->state
.Ctx
[I830_CTXREG_STATE5
] & ~FIXED_LINE_WIDTH_MASK
;
587 state5
|= (ENABLE_FIXED_LINE_WIDTH
| FIXED_LINE_WIDTH(width
));
589 if (state5
!= i830
->state
.Ctx
[I830_CTXREG_STATE5
]) {
590 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
591 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = state5
;
595 static void i830PointSize(GLcontext
*ctx
, GLfloat size
)
597 i830ContextPtr i830
= I830_CONTEXT(ctx
);
598 GLint point_size
= (int)size
;
600 if (INTEL_DEBUG
&DEBUG_DRI
)
601 fprintf(stderr
, "%s\n", __FUNCTION__
);
603 CLAMP_SELF(point_size
, 1, 256);
604 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
605 i830
->state
.Ctx
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
606 i830
->state
.Ctx
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
607 FIXED_POINT_WIDTH(point_size
));
611 /* =============================================================
615 static void i830ColorMask(GLcontext
*ctx
,
616 GLboolean r
, GLboolean g
,
617 GLboolean b
, GLboolean a
)
619 i830ContextPtr i830
= I830_CONTEXT( ctx
);
622 if (INTEL_DEBUG
&DEBUG_DRI
)
623 fprintf(stderr
, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
625 tmp
= ((i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
628 ((!r
) << WRITEMASK_RED_SHIFT
) |
629 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
630 ((!b
) << WRITEMASK_BLUE_SHIFT
) |
631 ((!a
) << WRITEMASK_ALPHA_SHIFT
));
633 if (tmp
!= i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
]) {
634 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
635 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = tmp
;
639 static void update_specular( GLcontext
*ctx
)
641 i830ContextPtr i830
= I830_CONTEXT( ctx
);
643 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
644 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
646 if (NEED_SECONDARY_COLOR(ctx
))
647 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
649 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
652 static void i830LightModelfv(GLcontext
*ctx
, GLenum pname
,
653 const GLfloat
*param
)
655 if (INTEL_DEBUG
&DEBUG_DRI
)
656 fprintf(stderr
, "%s\n", __FUNCTION__
);
658 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
659 update_specular( ctx
);
663 /* In Mesa 3.5 we can reliably do native flatshading.
665 static void i830ShadeModel(GLcontext
*ctx
, GLenum mode
)
667 i830ContextPtr i830
= I830_CONTEXT(ctx
);
668 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
671 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
673 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
675 if (mode
== GL_FLAT
) {
676 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) |
677 FOG_SHADE_MODE(SHADE_MODE_FLAT
) |
678 SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
679 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
681 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
682 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
683 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
684 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
688 /* =============================================================
691 static void i830Fogfv(GLcontext
*ctx
, GLenum pname
, const GLfloat
*param
)
693 i830ContextPtr i830
= I830_CONTEXT(ctx
);
695 if (INTEL_DEBUG
&DEBUG_DRI
)
696 fprintf(stderr
, "%s\n", __FUNCTION__
);
698 if (pname
== GL_FOG_COLOR
) {
699 GLuint color
= (((GLubyte
)(ctx
->Fog
.Color
[0]*255.0F
) << 16) |
700 ((GLubyte
)(ctx
->Fog
.Color
[1]*255.0F
) << 8) |
701 ((GLubyte
)(ctx
->Fog
.Color
[2]*255.0F
) << 0));
703 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
704 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
| color
);
708 /* =============================================================
711 static void i830Enable(GLcontext
*ctx
, GLenum cap
, GLboolean state
)
713 i830ContextPtr i830
= I830_CONTEXT(ctx
);
718 update_specular( ctx
);
722 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
723 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
725 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
727 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
732 i830EvalLogicOpBlendState(ctx
);
735 case GL_COLOR_LOGIC_OP
:
736 i830EvalLogicOpBlendState(ctx
);
738 /* Logicop doesn't seem to work at 16bpp:
740 if (i830
->intel
.intelScreen
->cpp
== 2)
741 FALLBACK( &i830
->intel
, I830_FALLBACK_LOGICOP
, state
);
745 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
746 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
749 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
751 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
755 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
756 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
759 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
761 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
763 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
765 i830DepthMask( ctx
, ctx
->Depth
.Mask
);
768 case GL_SCISSOR_TEST
:
769 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
772 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
773 (_3DSTATE_SCISSOR_ENABLE_CMD
|
774 ENABLE_SCISSOR_RECT
);
776 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
777 (_3DSTATE_SCISSOR_ENABLE_CMD
|
778 DISABLE_SCISSOR_RECT
);
783 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
785 i830
->state
.Ctx
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
787 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
789 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
793 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
794 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
796 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_FOG
;
798 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_FOG
;
802 i830CullFaceFrontFace(ctx
, 0);
808 case GL_STENCIL_TEST
:
809 if (i830
->intel
.hw_stencil
) {
810 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
813 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
814 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
816 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
817 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_STENCIL_WRITE
;
818 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
819 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_STENCIL_WRITE
;
822 FALLBACK( &i830
->intel
, I830_FALLBACK_STENCIL
, state
);
826 case GL_POLYGON_STIPPLE
:
827 /* The stipple command worked on my 855GM box, but not my 845G.
828 * I'll do more testing later to find out exactly which hardware
829 * supports it. Disabled for now.
831 if (i830
->intel
.hw_stipple
&&
832 i830
->intel
.reduced_primitive
== GL_TRIANGLES
)
834 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
835 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
837 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
847 static void i830_init_packets( i830ContextPtr i830
)
849 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
852 memset(&i830
->state
, 0, sizeof(i830
->state
));
854 /* Set default blend state */
855 i830
->state
.TexBlend
[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
857 ENABLE_TEXOUTPUT_WRT_SEL
|
858 TEXOP_OUTPUT_CURRENT
|
859 DISABLE_TEX_CNTRL_STAGE
|
864 i830
->state
.TexBlend
[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
866 ENABLE_TEXOUTPUT_WRT_SEL
|
867 TEXOP_OUTPUT_CURRENT
|
871 i830
->state
.TexBlend
[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
874 TEXBLENDARG_MODIFY_PARMS
|
875 TEXBLENDARG_DIFFUSE
);
876 i830
->state
.TexBlend
[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
879 TEXBLENDARG_MODIFY_PARMS
|
880 TEXBLENDARG_DIFFUSE
);
882 i830
->state
.TexBlendWordsUsed
[0] = 4;
885 i830
->state
.Ctx
[I830_CTXREG_VF
] = 0;
886 i830
->state
.Ctx
[I830_CTXREG_VF2
] = 0;
888 i830
->state
.Ctx
[I830_CTXREG_AA
] = (_3DSTATE_AA_CMD
|
889 AA_LINE_ECAAR_WIDTH_ENABLE
|
890 AA_LINE_ECAAR_WIDTH_1_0
|
891 AA_LINE_REGION_WIDTH_ENABLE
|
892 AA_LINE_REGION_WIDTH_1_0
|
895 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] = (_3DSTATE_ENABLES_1_CMD
|
897 DISABLE_STENCIL_TEST
|
902 DISABLE_COLOR_BLEND
|
905 if (i830
->intel
.hw_stencil
) {
906 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
907 ENABLE_STENCIL_WRITE
|
911 /* set no color comps disabled */
915 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
916 DISABLE_STENCIL_WRITE
|
920 /* set no color comps disabled */
925 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = (_3DSTATE_MODES_1_CMD
|
926 ENABLE_COLR_BLND_FUNC
|
928 ENABLE_SRC_BLND_FACTOR
|
929 SRC_BLND_FACT(BLENDFACT_ONE
) |
930 ENABLE_DST_BLND_FACTOR
|
931 DST_BLND_FACT(BLENDFACT_ZERO
) );
933 i830
->state
.Ctx
[I830_CTXREG_STATE2
] = (_3DSTATE_MODES_2_CMD
|
934 ENABLE_GLOBAL_DEPTH_BIAS
|
935 GLOBAL_DEPTH_BIAS(0) |
936 ENABLE_ALPHA_TEST_FUNC
|
937 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
938 ALPHA_REF_VALUE(0) );
940 i830
->state
.Ctx
[I830_CTXREG_STATE3
] = (_3DSTATE_MODES_3_CMD
|
941 ENABLE_DEPTH_TEST_FUNC
|
942 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
943 ENABLE_ALPHA_SHADE_MODE
|
944 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
945 ENABLE_FOG_SHADE_MODE
|
946 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
947 ENABLE_SPEC_SHADE_MODE
|
948 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
949 ENABLE_COLOR_SHADE_MODE
|
950 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
) |
954 i830
->state
.Ctx
[I830_CTXREG_STATE4
] = (_3DSTATE_MODES_4_CMD
|
955 ENABLE_LOGIC_OP_FUNC
|
956 LOGIC_OP_FUNC(LOGICOP_COPY
) |
957 ENABLE_STENCIL_TEST_MASK
|
958 STENCIL_TEST_MASK(0xff) |
959 ENABLE_STENCIL_WRITE_MASK
|
960 STENCIL_WRITE_MASK(0xff));
962 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] = (_3DSTATE_STENCIL_TEST_CMD
|
963 ENABLE_STENCIL_PARMS
|
964 STENCIL_FAIL_OP(STENCILOP_KEEP
) |
965 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP
) |
966 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP
) |
967 ENABLE_STENCIL_TEST_FUNC
|
968 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS
) |
969 ENABLE_STENCIL_REF_VALUE
|
970 STENCIL_REF_VALUE(0) );
972 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = (_3DSTATE_MODES_5_CMD
|
973 FLUSH_TEXTURE_CACHE
|
974 ENABLE_SPRITE_POINT_TEX
|
975 SPRITE_POINT_TEX_OFF
|
976 ENABLE_FIXED_LINE_WIDTH
|
977 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
978 ENABLE_FIXED_POINT_WIDTH
|
979 FIXED_POINT_WIDTH(1) );
981 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD
|
982 DISABLE_INDPT_ALPHA_BLEND
|
983 ENABLE_ALPHA_BLENDFUNC
|
986 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
|
991 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR0
] = _3DSTATE_CONST_BLEND_COLOR_CMD
;
992 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = 0;
994 i830
->state
.Ctx
[I830_CTXREG_MCSB0
] = _3DSTATE_MAP_COORD_SETBIND_CMD
;
995 i830
->state
.Ctx
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
996 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
997 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
998 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1001 i830
->state
.Stipple
[I830_STPREG_ST0
] = _3DSTATE_STIPPLE
;
1003 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1004 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR1
] =
1005 (BUF_3D_ID_COLOR_BACK
|
1006 BUF_3D_PITCH(screen
->front
.pitch
) | /* pitch in bytes */
1010 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1011 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR1
] =
1013 BUF_3D_PITCH(screen
->depth
.pitch
) | /* pitch in bytes */
1015 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR2
] = screen
->depth
.offset
;
1018 i830
->state
.Buffer
[I830_DESTREG_DV0
] = _3DSTATE_DST_BUF_VARS_CMD
;
1020 switch (screen
->fbFormat
) {
1023 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1024 DSTORG_VERT_BIAS(0x8) | /* .5 */
1027 DEPTH_FRMT_16_FIXED
);
1030 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1031 DSTORG_VERT_BIAS(0x8) | /* .5 */
1034 DEPTH_FRMT_24_FIXED_8_OTHER
);
1038 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] = (_3DSTATE_SCISSOR_ENABLE_CMD
|
1039 DISABLE_SCISSOR_RECT
);
1040 i830
->state
.Buffer
[I830_DESTREG_SR0
] = _3DSTATE_SCISSOR_RECT_0_CMD
;
1041 i830
->state
.Buffer
[I830_DESTREG_SR1
] = 0;
1042 i830
->state
.Buffer
[I830_DESTREG_SR2
] = 0;
1046 void i830InitStateFuncs( struct dd_function_table
*functions
)
1048 functions
->AlphaFunc
= i830AlphaFunc
;
1049 functions
->BlendColor
= i830BlendColor
;
1050 functions
->BlendEquationSeparate
= i830BlendEquationSeparate
;
1051 functions
->BlendFuncSeparate
= i830BlendFuncSeparate
;
1052 functions
->ColorMask
= i830ColorMask
;
1053 functions
->CullFace
= i830CullFaceFrontFace
;
1054 functions
->DepthFunc
= i830DepthFunc
;
1055 functions
->DepthMask
= i830DepthMask
;
1056 functions
->Enable
= i830Enable
;
1057 functions
->Fogfv
= i830Fogfv
;
1058 functions
->FrontFace
= i830CullFaceFrontFace
;
1059 functions
->LightModelfv
= i830LightModelfv
;
1060 functions
->LineWidth
= i830LineWidth
;
1061 functions
->LogicOpcode
= i830LogicOp
;
1062 functions
->PointSize
= i830PointSize
;
1063 functions
->PolygonStipple
= i830PolygonStipple
;
1064 functions
->Scissor
= i830Scissor
;
1065 functions
->ShadeModel
= i830ShadeModel
;
1066 functions
->StencilFuncSeparate
= i830StencilFuncSeparate
;
1067 functions
->StencilMaskSeparate
= i830StencilMaskSeparate
;
1068 functions
->StencilOpSeparate
= i830StencilOpSeparate
;
1071 void i830InitState( i830ContextPtr i830
)
1073 GLcontext
*ctx
= &i830
->intel
.ctx
;
1075 i830_init_packets( i830
);
1077 intelInitState( ctx
);
1079 memcpy( &i830
->initial
, &i830
->state
, sizeof(i830
->state
) );
1081 i830
->current
= &i830
->state
;
1082 i830
->state
.emitted
= 0;
1083 i830
->state
.active
= (I830_UPLOAD_TEXBLEND(0) |
1084 I830_UPLOAD_STIPPLE
|
1086 I830_UPLOAD_BUFFERS
);