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"
39 #include "intel_fbo.h"
41 #include "i830_context.h"
44 #define FILE_DEBUG_FLAG DEBUG_STATE
47 i830StencilFuncSeparate(GLcontext
* ctx
, GLenum face
, GLenum func
, GLint ref
,
50 struct i830_context
*i830
= i830_context(ctx
);
51 int test
= intel_translate_compare_func(func
);
55 DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__
,
56 _mesa_lookup_enum_by_nr(func
), ref
, mask
);
59 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
60 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
61 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
62 STENCIL_TEST_MASK(mask
));
63 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
64 ENABLE_STENCIL_TEST_FUNC_MASK
);
65 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
66 ENABLE_STENCIL_TEST_FUNC
|
67 STENCIL_REF_VALUE(ref
) |
68 STENCIL_TEST_FUNC(test
));
72 i830StencilMaskSeparate(GLcontext
* ctx
, GLenum face
, GLuint mask
)
74 struct i830_context
*i830
= i830_context(ctx
);
76 DBG("%s : mask 0x%x\n", __FUNCTION__
, mask
);
80 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
81 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
82 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
83 STENCIL_WRITE_MASK(mask
));
87 i830StencilOpSeparate(GLcontext
* ctx
, GLenum face
, GLenum fail
, GLenum zfail
,
90 struct i830_context
*i830
= i830_context(ctx
);
93 DBG("%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
));
104 fop
= STENCILOP_KEEP
;
107 fop
= STENCILOP_ZERO
;
110 fop
= STENCILOP_REPLACE
;
113 fop
= STENCILOP_INCRSAT
;
116 fop
= STENCILOP_DECRSAT
;
119 fop
= STENCILOP_INCR
;
122 fop
= STENCILOP_DECR
;
125 fop
= STENCILOP_INVERT
;
132 dfop
= STENCILOP_KEEP
;
135 dfop
= STENCILOP_ZERO
;
138 dfop
= STENCILOP_REPLACE
;
141 dfop
= STENCILOP_INCRSAT
;
144 dfop
= STENCILOP_DECRSAT
;
147 dfop
= STENCILOP_INCR
;
150 dfop
= STENCILOP_DECR
;
153 dfop
= STENCILOP_INVERT
;
160 dpop
= STENCILOP_KEEP
;
163 dpop
= STENCILOP_ZERO
;
166 dpop
= STENCILOP_REPLACE
;
169 dpop
= STENCILOP_INCRSAT
;
172 dpop
= STENCILOP_DECRSAT
;
175 dpop
= STENCILOP_INCR
;
178 dpop
= STENCILOP_DECR
;
181 dpop
= STENCILOP_INVERT
;
188 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
189 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
190 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
191 STENCIL_FAIL_OP(fop
) |
192 STENCIL_PASS_DEPTH_FAIL_OP
194 STENCIL_PASS_DEPTH_PASS_OP
199 i830AlphaFunc(GLcontext
* ctx
, GLenum func
, GLfloat ref
)
201 struct i830_context
*i830
= i830_context(ctx
);
202 int test
= intel_translate_compare_func(func
);
206 UNCLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
207 refInt
= (GLuint
) refByte
;
209 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
210 i830
->state
.Ctx
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
211 i830
->state
.Ctx
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
212 ENABLE_ALPHA_REF_VALUE
|
213 ALPHA_TEST_FUNC(test
) |
214 ALPHA_REF_VALUE(refInt
));
218 * Makes sure that the proper enables are set for LogicOp, Independant Alpha
219 * Blend, and Blending. It needs to be called from numerous places where we
220 * could change the LogicOp or Independant Alpha Blend without subsequent
224 * This function is substantially different from the old i830-specific driver.
225 * I'm not sure which is correct.
228 i830EvalLogicOpBlendState(GLcontext
* ctx
)
230 struct i830_context
*i830
= i830_context(ctx
);
232 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
234 if (ctx
->Color
._LogicOpEnabled
) {
235 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
236 ENABLE_LOGIC_OP_MASK
);
237 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
240 else if (ctx
->Color
.BlendEnabled
) {
241 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
242 ENABLE_LOGIC_OP_MASK
);
243 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
247 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
248 ENABLE_LOGIC_OP_MASK
);
249 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
255 i830BlendColor(GLcontext
* ctx
, const GLfloat color
[4])
257 struct i830_context
*i830
= i830_context(ctx
);
260 DBG("%s\n", __FUNCTION__
);
262 UNCLAMPED_FLOAT_TO_UBYTE(r
, color
[RCOMP
]);
263 UNCLAMPED_FLOAT_TO_UBYTE(g
, color
[GCOMP
]);
264 UNCLAMPED_FLOAT_TO_UBYTE(b
, color
[BCOMP
]);
265 UNCLAMPED_FLOAT_TO_UBYTE(a
, color
[ACOMP
]);
267 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
268 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] =
269 (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
273 * Sets both the blend equation (called "function" in i830 docs) and the
274 * blend function (called "factor" in i830 docs). This is done in a single
275 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
276 * change the interpretation of the blend function.
279 i830_set_blend_state(GLcontext
* ctx
)
281 struct i830_context
*i830
= i830_context(ctx
);
291 SRC_BLND_FACT(intel_translate_blend_factor(ctx
->Color
.BlendSrcRGB
))
292 | DST_BLND_FACT(intel_translate_blend_factor(ctx
->Color
.BlendDstRGB
));
294 switch (ctx
->Color
.BlendEquationRGB
) {
296 eqnRGB
= BLENDFUNC_ADD
;
299 eqnRGB
= BLENDFUNC_MIN
;
300 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
303 eqnRGB
= BLENDFUNC_MAX
;
304 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
306 case GL_FUNC_SUBTRACT
:
307 eqnRGB
= BLENDFUNC_SUB
;
309 case GL_FUNC_REVERSE_SUBTRACT
:
310 eqnRGB
= BLENDFUNC_RVRSE_SUB
;
313 fprintf(stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
314 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationRGB
);
319 funcA
= SRC_ABLEND_FACT(intel_translate_blend_factor(ctx
->Color
.BlendSrcA
))
320 | DST_ABLEND_FACT(intel_translate_blend_factor(ctx
->Color
.BlendDstA
));
322 switch (ctx
->Color
.BlendEquationA
) {
324 eqnA
= BLENDFUNC_ADD
;
327 eqnA
= BLENDFUNC_MIN
;
328 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
331 eqnA
= BLENDFUNC_MAX
;
332 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
334 case GL_FUNC_SUBTRACT
:
335 eqnA
= BLENDFUNC_SUB
;
337 case GL_FUNC_REVERSE_SUBTRACT
:
338 eqnA
= BLENDFUNC_RVRSE_SUB
;
341 fprintf(stderr
, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
342 __FUNCTION__
, __LINE__
, ctx
->Color
.BlendEquationA
);
347 | _3DSTATE_INDPT_ALPHA_BLEND_CMD
348 | ENABLE_SRC_ABLEND_FACTOR
| ENABLE_DST_ABLEND_FACTOR
349 | ENABLE_ALPHA_BLENDFUNC
;
350 s1
= eqnRGB
| funcRGB
351 | _3DSTATE_MODES_1_CMD
352 | ENABLE_SRC_BLND_FACTOR
| ENABLE_DST_BLND_FACTOR
353 | ENABLE_COLR_BLND_FUNC
;
355 if ((eqnA
| funcA
) != (eqnRGB
| funcRGB
))
356 iab
|= ENABLE_INDPT_ALPHA_BLEND
;
358 iab
|= DISABLE_INDPT_ALPHA_BLEND
;
360 if (iab
!= i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] ||
361 s1
!= i830
->state
.Ctx
[I830_CTXREG_STATE1
]) {
362 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
363 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = iab
;
364 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = s1
;
367 /* This will catch a logicop blend equation. It will also ensure
368 * independant alpha blend is really in the correct state (either enabled
369 * or disabled) if blending is already enabled.
372 i830EvalLogicOpBlendState(ctx
);
376 "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
377 __FUNCTION__
, __LINE__
, i830
->state
.Ctx
[I830_CTXREG_STATE1
],
378 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
],
379 (ctx
->Color
.BlendEnabled
) ? "en" : "dis");
385 i830BlendEquationSeparate(GLcontext
* ctx
, GLenum modeRGB
, GLenum modeA
)
387 DBG("%s -> %s, %s\n", __FUNCTION__
,
388 _mesa_lookup_enum_by_nr(modeRGB
),
389 _mesa_lookup_enum_by_nr(modeA
));
393 i830_set_blend_state(ctx
);
398 i830BlendFuncSeparate(GLcontext
* ctx
, GLenum sfactorRGB
,
399 GLenum dfactorRGB
, GLenum sfactorA
, GLenum dfactorA
)
401 DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__
,
402 _mesa_lookup_enum_by_nr(sfactorRGB
),
403 _mesa_lookup_enum_by_nr(dfactorRGB
),
404 _mesa_lookup_enum_by_nr(sfactorA
),
405 _mesa_lookup_enum_by_nr(dfactorA
));
411 i830_set_blend_state(ctx
);
417 i830DepthFunc(GLcontext
* ctx
, GLenum func
)
419 struct i830_context
*i830
= i830_context(ctx
);
420 int test
= intel_translate_compare_func(func
);
422 DBG("%s\n", __FUNCTION__
);
424 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
425 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
426 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
427 DEPTH_TEST_FUNC(test
));
431 i830DepthMask(GLcontext
* ctx
, GLboolean flag
)
433 struct i830_context
*i830
= i830_context(ctx
);
435 DBG("%s flag (%d)\n", __FUNCTION__
, flag
);
437 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
439 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
441 if (flag
&& ctx
->Depth
.Test
)
442 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
444 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
447 /* =============================================================
450 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
451 * Fortunately stipple is usually a repeating pattern.
454 i830PolygonStipple(GLcontext
* ctx
, const GLubyte
* mask
)
456 struct i830_context
*i830
= i830_context(ctx
);
457 const GLubyte
*m
= mask
;
460 int active
= (ctx
->Polygon
.StippleFlag
&&
461 i830
->intel
.reduced_primitive
== GL_TRIANGLES
);
465 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
466 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
469 p
[0] = mask
[12] & 0xf;
471 p
[1] = mask
[8] & 0xf;
473 p
[2] = mask
[4] & 0xf;
475 p
[3] = mask
[0] & 0xf;
478 for (k
= 0; k
< 8; k
++)
479 for (j
= 3; j
>= 0; j
--)
480 for (i
= 0; i
< 4; i
++, m
++)
482 i830
->intel
.hw_stipple
= 0;
486 newMask
= (((p
[0] & 0xf) << 0) |
487 ((p
[1] & 0xf) << 4) |
488 ((p
[2] & 0xf) << 8) | ((p
[3] & 0xf) << 12));
491 if (newMask
== 0xffff || newMask
== 0x0) {
492 /* this is needed to make conform pass */
493 i830
->intel
.hw_stipple
= 0;
497 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~0xffff;
498 i830
->state
.Stipple
[I830_STPREG_ST1
] |= newMask
;
499 i830
->intel
.hw_stipple
= 1;
502 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
506 /* =============================================================
510 i830Scissor(GLcontext
* ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
512 struct i830_context
*i830
= i830_context(ctx
);
515 if (!ctx
->DrawBuffer
)
518 DBG("%s %d,%d %dx%d\n", __FUNCTION__
, x
, y
, w
, h
);
520 if (ctx
->DrawBuffer
->Name
== 0) {
522 y1
= ctx
->DrawBuffer
->Height
- (y
+ h
);
525 DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__
, x1
, x2
, y1
, y2
);
528 /* FBO - not inverted
534 DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__
, x1
, x2
, y1
, y2
);
537 x1
= CLAMP(x1
, 0, ctx
->DrawBuffer
->Width
- 1);
538 y1
= CLAMP(y1
, 0, ctx
->DrawBuffer
->Height
- 1);
539 x2
= CLAMP(x2
, 0, ctx
->DrawBuffer
->Width
- 1);
540 y2
= CLAMP(y2
, 0, ctx
->DrawBuffer
->Height
- 1);
542 DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__
, x1
, x2
, y1
, y2
);
544 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
545 i830
->state
.Buffer
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
546 i830
->state
.Buffer
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
550 i830LogicOp(GLcontext
* ctx
, GLenum opcode
)
552 struct i830_context
*i830
= i830_context(ctx
);
553 int tmp
= intel_translate_logic_op(opcode
);
555 DBG("%s\n", __FUNCTION__
);
557 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
558 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
559 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= LOGIC_OP_FUNC(tmp
);
565 i830CullFaceFrontFace(GLcontext
* ctx
, GLenum unused
)
567 struct i830_context
*i830
= i830_context(ctx
);
570 DBG("%s\n", __FUNCTION__
);
572 if (!ctx
->Polygon
.CullFlag
) {
573 mode
= CULLMODE_NONE
;
575 else if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
578 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
579 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
580 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
581 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
584 mode
= CULLMODE_BOTH
;
587 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
588 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
589 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
593 i830LineWidth(GLcontext
* ctx
, GLfloat widthf
)
595 struct i830_context
*i830
= i830_context(ctx
);
599 DBG("%s\n", __FUNCTION__
);
601 width
= (int) (widthf
* 2);
602 CLAMP_SELF(width
, 1, 15);
604 state5
= i830
->state
.Ctx
[I830_CTXREG_STATE5
] & ~FIXED_LINE_WIDTH_MASK
;
605 state5
|= (ENABLE_FIXED_LINE_WIDTH
| FIXED_LINE_WIDTH(width
));
607 if (state5
!= i830
->state
.Ctx
[I830_CTXREG_STATE5
]) {
608 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
609 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = state5
;
614 i830PointSize(GLcontext
* ctx
, GLfloat size
)
616 struct i830_context
*i830
= i830_context(ctx
);
617 GLint point_size
= (int) size
;
619 DBG("%s\n", __FUNCTION__
);
621 CLAMP_SELF(point_size
, 1, 256);
622 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
623 i830
->state
.Ctx
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
624 i830
->state
.Ctx
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
625 FIXED_POINT_WIDTH(point_size
));
629 /* =============================================================
634 i830ColorMask(GLcontext
* ctx
,
635 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
637 struct i830_context
*i830
= i830_context(ctx
);
640 DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__
, r
, g
, b
, a
);
642 tmp
= ((i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
645 ((!r
) << WRITEMASK_RED_SHIFT
) |
646 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
647 ((!b
) << WRITEMASK_BLUE_SHIFT
) | ((!a
) << WRITEMASK_ALPHA_SHIFT
));
649 if (tmp
!= i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
]) {
650 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
651 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = tmp
;
656 update_specular(GLcontext
* ctx
)
658 struct i830_context
*i830
= i830_context(ctx
);
660 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
661 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
663 if (NEED_SECONDARY_COLOR(ctx
))
664 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
666 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
670 i830LightModelfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
672 DBG("%s\n", __FUNCTION__
);
674 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
675 update_specular(ctx
);
679 /* In Mesa 3.5 we can reliably do native flatshading.
682 i830ShadeModel(GLcontext
* ctx
, GLenum mode
)
684 struct i830_context
*i830
= i830_context(ctx
);
685 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
688 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
690 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
692 if (mode
== GL_FLAT
) {
693 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |=
694 (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) | FOG_SHADE_MODE(SHADE_MODE_FLAT
)
695 | SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
696 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
699 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |=
700 (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
701 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
702 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
703 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
707 /* =============================================================
711 i830Fogfv(GLcontext
* ctx
, GLenum pname
, const GLfloat
* param
)
713 struct i830_context
*i830
= i830_context(ctx
);
715 DBG("%s\n", __FUNCTION__
);
717 if (pname
== GL_FOG_COLOR
) {
718 GLuint color
= (((GLubyte
) (ctx
->Fog
.Color
[0] * 255.0F
) << 16) |
719 ((GLubyte
) (ctx
->Fog
.Color
[1] * 255.0F
) << 8) |
720 ((GLubyte
) (ctx
->Fog
.Color
[2] * 255.0F
) << 0));
722 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
723 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] =
724 (_3DSTATE_FOG_COLOR_CMD
| color
);
728 /* =============================================================
732 i830Enable(GLcontext
* ctx
, GLenum cap
, GLboolean state
)
734 struct i830_context
*i830
= i830_context(ctx
);
739 update_specular(ctx
);
743 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
744 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
746 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
748 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
753 i830EvalLogicOpBlendState(ctx
);
756 case GL_COLOR_LOGIC_OP
:
757 i830EvalLogicOpBlendState(ctx
);
759 /* Logicop doesn't seem to work at 16bpp:
761 if (i830
->intel
.intelScreen
->cpp
== 2)
762 FALLBACK(&i830
->intel
, I830_FALLBACK_LOGICOP
, state
);
766 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
767 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
770 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
772 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
776 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
777 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
780 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
782 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
784 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
786 i830DepthMask(ctx
, ctx
->Depth
.Mask
);
789 case GL_SCISSOR_TEST
:
790 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
793 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
794 (_3DSTATE_SCISSOR_ENABLE_CMD
| ENABLE_SCISSOR_RECT
);
796 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
797 (_3DSTATE_SCISSOR_ENABLE_CMD
| DISABLE_SCISSOR_RECT
);
802 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
804 i830
->state
.Ctx
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
806 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
808 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
812 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
813 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
815 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_FOG
;
817 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_FOG
;
821 i830CullFaceFrontFace(ctx
, 0);
827 case GL_STENCIL_TEST
:
829 GLboolean hw_stencil
= GL_FALSE
;
830 if (ctx
->DrawBuffer
) {
831 struct intel_renderbuffer
*irbStencil
832 = intel_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
833 hw_stencil
= (irbStencil
&& irbStencil
->region
);
836 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
839 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
840 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
843 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
844 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &=
845 ~ENABLE_STENCIL_WRITE
;
846 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
847 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |=
848 DISABLE_STENCIL_WRITE
;
852 FALLBACK(&i830
->intel
, I830_FALLBACK_STENCIL
, state
);
857 case GL_POLYGON_STIPPLE
:
858 /* The stipple command worked on my 855GM box, but not my 845G.
859 * I'll do more testing later to find out exactly which hardware
860 * supports it. Disabled for now.
862 if (i830
->intel
.hw_stipple
&&
863 i830
->intel
.reduced_primitive
== GL_TRIANGLES
) {
864 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
865 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
867 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
878 i830_init_packets(struct i830_context
*i830
)
880 intelScreenPrivate
*screen
= i830
->intel
.intelScreen
;
883 memset(&i830
->state
, 0, sizeof(i830
->state
));
885 /* Set default blend state */
886 i830
->state
.TexBlend
[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
888 ENABLE_TEXOUTPUT_WRT_SEL
|
889 TEXOP_OUTPUT_CURRENT
|
890 DISABLE_TEX_CNTRL_STAGE
|
893 TEXOP_LAST_STAGE
| TEXBLENDOP_ARG1
);
894 i830
->state
.TexBlend
[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
896 ENABLE_TEXOUTPUT_WRT_SEL
|
897 TEXOP_OUTPUT_CURRENT
|
899 TEXOP_MODIFY_PARMS
| TEXBLENDOP_ARG1
);
900 i830
->state
.TexBlend
[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
903 TEXBLENDARG_MODIFY_PARMS
|
904 TEXBLENDARG_DIFFUSE
);
905 i830
->state
.TexBlend
[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
908 TEXBLENDARG_MODIFY_PARMS
|
909 TEXBLENDARG_DIFFUSE
);
911 i830
->state
.TexBlendWordsUsed
[0] = 4;
914 i830
->state
.Ctx
[I830_CTXREG_VF
] = 0;
915 i830
->state
.Ctx
[I830_CTXREG_VF2
] = 0;
917 i830
->state
.Ctx
[I830_CTXREG_AA
] = (_3DSTATE_AA_CMD
|
918 AA_LINE_ECAAR_WIDTH_ENABLE
|
919 AA_LINE_ECAAR_WIDTH_1_0
|
920 AA_LINE_REGION_WIDTH_ENABLE
|
921 AA_LINE_REGION_WIDTH_1_0
|
924 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] = (_3DSTATE_ENABLES_1_CMD
|
926 DISABLE_STENCIL_TEST
|
931 DISABLE_COLOR_BLEND
|
934 #if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */
935 if (i830
->intel
.hw_stencil
) {
936 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
937 ENABLE_STENCIL_WRITE
|
941 /* set no color comps disabled */
948 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
949 DISABLE_STENCIL_WRITE
|
953 /* set no color comps disabled */
958 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = (_3DSTATE_MODES_1_CMD
|
959 ENABLE_COLR_BLND_FUNC
|
961 ENABLE_SRC_BLND_FACTOR
|
962 SRC_BLND_FACT(BLENDFACT_ONE
) |
963 ENABLE_DST_BLND_FACTOR
|
964 DST_BLND_FACT(BLENDFACT_ZERO
));
966 i830
->state
.Ctx
[I830_CTXREG_STATE2
] = (_3DSTATE_MODES_2_CMD
|
967 ENABLE_GLOBAL_DEPTH_BIAS
|
968 GLOBAL_DEPTH_BIAS(0) |
969 ENABLE_ALPHA_TEST_FUNC
|
970 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
)
971 | ALPHA_REF_VALUE(0));
973 i830
->state
.Ctx
[I830_CTXREG_STATE3
] = (_3DSTATE_MODES_3_CMD
|
974 ENABLE_DEPTH_TEST_FUNC
|
975 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
976 ENABLE_ALPHA_SHADE_MODE
|
977 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
)
978 | ENABLE_FOG_SHADE_MODE
|
979 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
980 ENABLE_SPEC_SHADE_MODE
|
981 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
982 ENABLE_COLOR_SHADE_MODE
|
983 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
)
984 | ENABLE_CULL_MODE
| CULLMODE_NONE
);
986 i830
->state
.Ctx
[I830_CTXREG_STATE4
] = (_3DSTATE_MODES_4_CMD
|
987 ENABLE_LOGIC_OP_FUNC
|
988 LOGIC_OP_FUNC(LOGICOP_COPY
) |
989 ENABLE_STENCIL_TEST_MASK
|
990 STENCIL_TEST_MASK(0xff) |
991 ENABLE_STENCIL_WRITE_MASK
|
992 STENCIL_WRITE_MASK(0xff));
994 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] = (_3DSTATE_STENCIL_TEST_CMD
|
995 ENABLE_STENCIL_PARMS
|
996 STENCIL_FAIL_OP(STENCILOP_KEEP
)
998 STENCIL_PASS_DEPTH_FAIL_OP
1000 STENCIL_PASS_DEPTH_PASS_OP
1002 ENABLE_STENCIL_TEST_FUNC
|
1004 (COMPAREFUNC_ALWAYS
) |
1005 ENABLE_STENCIL_REF_VALUE
|
1006 STENCIL_REF_VALUE(0));
1008 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = (_3DSTATE_MODES_5_CMD
| FLUSH_TEXTURE_CACHE
| ENABLE_SPRITE_POINT_TEX
| SPRITE_POINT_TEX_OFF
| ENABLE_FIXED_LINE_WIDTH
| FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1009 ENABLE_FIXED_POINT_WIDTH
|
1010 FIXED_POINT_WIDTH(1));
1012 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD
|
1013 DISABLE_INDPT_ALPHA_BLEND
|
1014 ENABLE_ALPHA_BLENDFUNC
|
1017 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
|
1019 FOG_COLOR_GREEN(0) |
1022 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR0
] = _3DSTATE_CONST_BLEND_COLOR_CMD
;
1023 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = 0;
1025 i830
->state
.Ctx
[I830_CTXREG_MCSB0
] = _3DSTATE_MAP_COORD_SETBIND_CMD
;
1026 i830
->state
.Ctx
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1027 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1028 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1029 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1032 i830
->state
.Stipple
[I830_STPREG_ST0
] = _3DSTATE_STIPPLE
;
1034 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1035 i830
->state
.Buffer
[I830_DESTREG_CBUFADDR1
] = (BUF_3D_ID_COLOR_BACK
| BUF_3D_PITCH(screen
->front
.pitch
) | /* pitch in bytes */
1039 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR0
] = _3DSTATE_BUF_INFO_CMD
;
1040 i830
->state
.Buffer
[I830_DESTREG_DBUFADDR1
] = (BUF_3D_ID_DEPTH
| BUF_3D_PITCH(screen
->depth
.pitch
) | /* pitch in bytes */
1043 i830
->state
.Buffer
[I830_DESTREG_DV0
] = _3DSTATE_DST_BUF_VARS_CMD
;
1045 switch (screen
->fbFormat
) {
1047 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1048 DSTORG_VERT_BIAS(0x8) | /* .5 */
1051 DEPTH_FRMT_16_FIXED
);
1054 i830
->state
.Buffer
[I830_DESTREG_DV1
] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1055 DSTORG_VERT_BIAS(0x8) | /* .5 */
1058 DEPTH_FRMT_24_FIXED_8_OTHER
);
1062 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] = (_3DSTATE_SCISSOR_ENABLE_CMD
|
1063 DISABLE_SCISSOR_RECT
);
1064 i830
->state
.Buffer
[I830_DESTREG_SR0
] = _3DSTATE_SCISSOR_RECT_0_CMD
;
1065 i830
->state
.Buffer
[I830_DESTREG_SR1
] = 0;
1066 i830
->state
.Buffer
[I830_DESTREG_SR2
] = 0;
1071 i830InitStateFuncs(struct dd_function_table
*functions
)
1073 functions
->AlphaFunc
= i830AlphaFunc
;
1074 functions
->BlendColor
= i830BlendColor
;
1075 functions
->BlendEquationSeparate
= i830BlendEquationSeparate
;
1076 functions
->BlendFuncSeparate
= i830BlendFuncSeparate
;
1077 functions
->ColorMask
= i830ColorMask
;
1078 functions
->CullFace
= i830CullFaceFrontFace
;
1079 functions
->DepthFunc
= i830DepthFunc
;
1080 functions
->DepthMask
= i830DepthMask
;
1081 functions
->Enable
= i830Enable
;
1082 functions
->Fogfv
= i830Fogfv
;
1083 functions
->FrontFace
= i830CullFaceFrontFace
;
1084 functions
->LightModelfv
= i830LightModelfv
;
1085 functions
->LineWidth
= i830LineWidth
;
1086 functions
->LogicOpcode
= i830LogicOp
;
1087 functions
->PointSize
= i830PointSize
;
1088 functions
->PolygonStipple
= i830PolygonStipple
;
1089 functions
->Scissor
= i830Scissor
;
1090 functions
->ShadeModel
= i830ShadeModel
;
1091 functions
->StencilFuncSeparate
= i830StencilFuncSeparate
;
1092 functions
->StencilMaskSeparate
= i830StencilMaskSeparate
;
1093 functions
->StencilOpSeparate
= i830StencilOpSeparate
;
1097 i830InitState(struct i830_context
*i830
)
1099 GLcontext
*ctx
= &i830
->intel
.ctx
;
1101 i830_init_packets(i830
);
1103 intelInitState(ctx
);
1105 memcpy(&i830
->initial
, &i830
->state
, sizeof(i830
->state
));
1107 i830
->current
= &i830
->state
;
1108 i830
->state
.emitted
= 0;
1109 i830
->state
.active
= (I830_UPLOAD_INVARIENT
|
1110 I830_UPLOAD_TEXBLEND(0) |
1111 I830_UPLOAD_STIPPLE
|
1112 I830_UPLOAD_CTX
| I830_UPLOAD_BUFFERS
);