1 /**************************************************************************
3 * Copyright 2003 VMware, Inc.
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 VMWARE 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 **************************************************************************/
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/macros.h"
32 #include "main/enums.h"
33 #include "main/fbobject.h"
35 #include "main/state.h"
37 #include "drivers/common/driverfuncs.h"
39 #include "intel_screen.h"
40 #include "intel_batchbuffer.h"
41 #include "intel_mipmap_tree.h"
42 #include "intel_fbo.h"
43 #include "intel_buffers.h"
45 #include "i830_context.h"
48 #define FILE_DEBUG_FLAG DEBUG_STATE
51 i830StencilFuncSeparate(struct gl_context
* ctx
, GLenum face
, GLenum func
, GLint ref
,
54 struct i830_context
*i830
= i830_context(ctx
);
55 int test
= intel_translate_compare_func(func
);
59 DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __func__
,
60 _mesa_enum_to_string(func
), ref
, mask
);
63 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
64 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_TEST_MASK
;
65 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_TEST_MASK
|
66 STENCIL_TEST_MASK(mask
));
67 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_REF_VALUE_MASK
|
68 ENABLE_STENCIL_TEST_FUNC_MASK
);
69 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_REF_VALUE
|
70 ENABLE_STENCIL_TEST_FUNC
|
71 STENCIL_REF_VALUE(ref
) |
72 STENCIL_TEST_FUNC(test
));
76 i830StencilMaskSeparate(struct gl_context
* ctx
, GLenum face
, GLuint mask
)
78 struct i830_context
*i830
= i830_context(ctx
);
80 DBG("%s : mask 0x%x\n", __func__
, mask
);
84 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
85 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK
;
86 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= (ENABLE_STENCIL_WRITE_MASK
|
87 STENCIL_WRITE_MASK(mask
));
91 i830StencilOpSeparate(struct gl_context
* ctx
, GLenum face
, GLenum fail
, GLenum zfail
,
94 struct i830_context
*i830
= i830_context(ctx
);
97 DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __func__
,
98 _mesa_enum_to_string(fail
),
99 _mesa_enum_to_string(zfail
),
100 _mesa_enum_to_string(zpass
));
108 fop
= STENCILOP_KEEP
;
111 fop
= STENCILOP_ZERO
;
114 fop
= STENCILOP_REPLACE
;
117 fop
= STENCILOP_INCRSAT
;
120 fop
= STENCILOP_DECRSAT
;
123 fop
= STENCILOP_INCR
;
126 fop
= STENCILOP_DECR
;
129 fop
= STENCILOP_INVERT
;
136 dfop
= STENCILOP_KEEP
;
139 dfop
= STENCILOP_ZERO
;
142 dfop
= STENCILOP_REPLACE
;
145 dfop
= STENCILOP_INCRSAT
;
148 dfop
= STENCILOP_DECRSAT
;
151 dfop
= STENCILOP_INCR
;
154 dfop
= STENCILOP_DECR
;
157 dfop
= STENCILOP_INVERT
;
164 dpop
= STENCILOP_KEEP
;
167 dpop
= STENCILOP_ZERO
;
170 dpop
= STENCILOP_REPLACE
;
173 dpop
= STENCILOP_INCRSAT
;
176 dpop
= STENCILOP_DECRSAT
;
179 dpop
= STENCILOP_INCR
;
182 dpop
= STENCILOP_DECR
;
185 dpop
= STENCILOP_INVERT
;
192 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
193 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] &= ~(STENCIL_OPS_MASK
);
194 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] |= (ENABLE_STENCIL_PARMS
|
195 STENCIL_FAIL_OP(fop
) |
196 STENCIL_PASS_DEPTH_FAIL_OP
198 STENCIL_PASS_DEPTH_PASS_OP
203 i830AlphaFunc(struct gl_context
* ctx
, GLenum func
, GLfloat ref
)
205 struct i830_context
*i830
= i830_context(ctx
);
206 int test
= intel_translate_compare_func(func
);
210 UNCLAMPED_FLOAT_TO_UBYTE(refByte
, ref
);
211 refInt
= (GLuint
) refByte
;
213 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
214 i830
->state
.Ctx
[I830_CTXREG_STATE2
] &= ~ALPHA_TEST_REF_MASK
;
215 i830
->state
.Ctx
[I830_CTXREG_STATE2
] |= (ENABLE_ALPHA_TEST_FUNC
|
216 ENABLE_ALPHA_REF_VALUE
|
217 ALPHA_TEST_FUNC(test
) |
218 ALPHA_REF_VALUE(refInt
));
222 * Makes sure that the proper enables are set for LogicOp, Independent Alpha
223 * Blend, and Blending. It needs to be called from numerous places where we
224 * could change the LogicOp or Independent Alpha Blend without subsequent
228 * This function is substantially different from the old i830-specific driver.
229 * I'm not sure which is correct.
232 i830EvalLogicOpBlendState(struct gl_context
* ctx
)
234 struct i830_context
*i830
= i830_context(ctx
);
236 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
238 if (ctx
->Color
.ColorLogicOpEnabled
) {
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
|
244 else if (ctx
->Color
.BlendEnabled
) {
245 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
246 ENABLE_LOGIC_OP_MASK
);
247 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (ENABLE_COLOR_BLEND
|
251 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~(ENABLE_COLOR_BLEND
|
252 ENABLE_LOGIC_OP_MASK
);
253 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= (DISABLE_COLOR_BLEND
|
259 i830BlendColor(struct gl_context
* ctx
, const GLfloat color
[4])
261 struct i830_context
*i830
= i830_context(ctx
);
264 DBG("%s\n", __func__
);
266 UNCLAMPED_FLOAT_TO_UBYTE(r
, color
[RCOMP
]);
267 UNCLAMPED_FLOAT_TO_UBYTE(g
, color
[GCOMP
]);
268 UNCLAMPED_FLOAT_TO_UBYTE(b
, color
[BCOMP
]);
269 UNCLAMPED_FLOAT_TO_UBYTE(a
, color
[ACOMP
]);
271 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
272 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] =
273 (a
<< 24) | (r
<< 16) | (g
<< 8) | b
;
277 * Sets both the blend equation (called "function" in i830 docs) and the
278 * blend function (called "factor" in i830 docs). This is done in a single
279 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
280 * change the interpretation of the blend function.
283 i830_set_blend_state(struct gl_context
* ctx
)
285 struct i830_context
*i830
= i830_context(ctx
);
295 SRC_BLND_FACT(intel_translate_blend_factor(ctx
->Color
.Blend
[0].SrcRGB
))
296 | DST_BLND_FACT(intel_translate_blend_factor(ctx
->Color
.Blend
[0].DstRGB
));
298 switch (ctx
->Color
.Blend
[0].EquationRGB
) {
300 eqnRGB
= BLENDFUNC_ADD
;
303 eqnRGB
= BLENDFUNC_MIN
;
304 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
307 eqnRGB
= BLENDFUNC_MAX
;
308 funcRGB
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
310 case GL_FUNC_SUBTRACT
:
311 eqnRGB
= BLENDFUNC_SUB
;
313 case GL_FUNC_REVERSE_SUBTRACT
:
314 eqnRGB
= BLENDFUNC_RVRSE_SUB
;
317 fprintf(stderr
, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
318 __func__
, __LINE__
, ctx
->Color
.Blend
[0].EquationRGB
);
323 funcA
= SRC_ABLEND_FACT(intel_translate_blend_factor(ctx
->Color
.Blend
[0].SrcA
))
324 | DST_ABLEND_FACT(intel_translate_blend_factor(ctx
->Color
.Blend
[0].DstA
));
326 switch (ctx
->Color
.Blend
[0].EquationA
) {
328 eqnA
= BLENDFUNC_ADD
;
331 eqnA
= BLENDFUNC_MIN
;
332 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
335 eqnA
= BLENDFUNC_MAX
;
336 funcA
= SRC_BLND_FACT(BLENDFACT_ONE
) | DST_BLND_FACT(BLENDFACT_ONE
);
338 case GL_FUNC_SUBTRACT
:
339 eqnA
= BLENDFUNC_SUB
;
341 case GL_FUNC_REVERSE_SUBTRACT
:
342 eqnA
= BLENDFUNC_RVRSE_SUB
;
345 fprintf(stderr
, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
346 __func__
, __LINE__
, ctx
->Color
.Blend
[0].EquationA
);
351 | _3DSTATE_INDPT_ALPHA_BLEND_CMD
352 | ENABLE_SRC_ABLEND_FACTOR
| ENABLE_DST_ABLEND_FACTOR
353 | ENABLE_ALPHA_BLENDFUNC
;
354 s1
= eqnRGB
| funcRGB
355 | _3DSTATE_MODES_1_CMD
356 | ENABLE_SRC_BLND_FACTOR
| ENABLE_DST_BLND_FACTOR
357 | ENABLE_COLR_BLND_FUNC
;
359 if ((eqnA
| funcA
) != (eqnRGB
| funcRGB
))
360 iab
|= ENABLE_INDPT_ALPHA_BLEND
;
362 iab
|= DISABLE_INDPT_ALPHA_BLEND
;
364 if (iab
!= i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] ||
365 s1
!= i830
->state
.Ctx
[I830_CTXREG_STATE1
]) {
366 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
367 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = iab
;
368 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = s1
;
371 /* This will catch a logicop blend equation. It will also ensure
372 * independent alpha blend is really in the correct state (either enabled
373 * or disabled) if blending is already enabled.
376 i830EvalLogicOpBlendState(ctx
);
380 "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
381 __func__
, __LINE__
, i830
->state
.Ctx
[I830_CTXREG_STATE1
],
382 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
],
383 (ctx
->Color
.BlendEnabled
) ? "en" : "dis");
389 i830BlendEquationSeparate(struct gl_context
* ctx
, GLenum modeRGB
, GLenum modeA
)
391 DBG("%s -> %s, %s\n", __func__
,
392 _mesa_enum_to_string(modeRGB
),
393 _mesa_enum_to_string(modeA
));
397 i830_set_blend_state(ctx
);
402 i830BlendFuncSeparate(struct gl_context
* ctx
, GLenum sfactorRGB
,
403 GLenum dfactorRGB
, GLenum sfactorA
, GLenum dfactorA
)
405 DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __func__
,
406 _mesa_enum_to_string(sfactorRGB
),
407 _mesa_enum_to_string(dfactorRGB
),
408 _mesa_enum_to_string(sfactorA
),
409 _mesa_enum_to_string(dfactorA
));
415 i830_set_blend_state(ctx
);
421 i830DepthFunc(struct gl_context
* ctx
, GLenum func
)
423 struct i830_context
*i830
= i830_context(ctx
);
424 int test
= intel_translate_compare_func(func
);
426 DBG("%s\n", __func__
);
428 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
429 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~DEPTH_TEST_FUNC_MASK
;
430 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= (ENABLE_DEPTH_TEST_FUNC
|
431 DEPTH_TEST_FUNC(test
));
435 i830DepthMask(struct gl_context
* ctx
, GLboolean flag
)
437 struct i830_context
*i830
= i830_context(ctx
);
439 DBG("%s flag (%d)\n", __func__
, flag
);
441 if (!ctx
->DrawBuffer
|| !ctx
->DrawBuffer
->Visual
.depthBits
)
444 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
446 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DIS_DEPTH_WRITE_MASK
;
448 if (flag
&& ctx
->Depth
.Test
)
449 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DEPTH_WRITE
;
451 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DEPTH_WRITE
;
454 /** Called from ctx->Driver.DepthRange() */
456 i830DepthRange(struct gl_context
*ctx
)
458 intelCalcViewport(ctx
);
461 /* =============================================================
464 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
465 * Fortunately stipple is usually a repeating pattern.
468 i830PolygonStipple(struct gl_context
* ctx
, const GLubyte
* mask
)
470 struct i830_context
*i830
= i830_context(ctx
);
474 int active
= (ctx
->Polygon
.StippleFlag
&&
475 i830
->intel
.reduced_primitive
== GL_TRIANGLES
);
479 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
480 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
483 /* Use the already unpacked stipple data from the context rather than the
484 * uninterpreted mask passed in.
486 mask
= (const GLubyte
*)ctx
->PolygonStipple
;
489 p
[0] = mask
[12] & 0xf;
491 p
[1] = mask
[8] & 0xf;
493 p
[2] = mask
[4] & 0xf;
495 p
[3] = mask
[0] & 0xf;
498 for (k
= 0; k
< 8; k
++)
499 for (j
= 3; j
>= 0; j
--)
500 for (i
= 0; i
< 4; i
++, m
++)
502 i830
->intel
.hw_stipple
= 0;
506 newMask
= (((p
[0] & 0xf) << 0) |
507 ((p
[1] & 0xf) << 4) |
508 ((p
[2] & 0xf) << 8) | ((p
[3] & 0xf) << 12));
511 if (newMask
== 0xffff || newMask
== 0x0) {
512 /* this is needed to make conform pass */
513 i830
->intel
.hw_stipple
= 0;
517 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~0xffff;
518 i830
->state
.Stipple
[I830_STPREG_ST1
] |= newMask
;
519 i830
->intel
.hw_stipple
= 1;
522 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
526 /* =============================================================
530 i830Scissor(struct gl_context
* ctx
)
532 struct i830_context
*i830
= i830_context(ctx
);
535 if (!ctx
->DrawBuffer
)
538 DBG("%s %d,%d %dx%d\n", __func__
,
539 ctx
->Scissor
.ScissorArray
[0].X
, ctx
->Scissor
.ScissorArray
[0].Y
,
540 ctx
->Scissor
.ScissorArray
[0].Width
, ctx
->Scissor
.ScissorArray
[0].Height
);
542 if (_mesa_is_winsys_fbo(ctx
->DrawBuffer
)) {
543 x1
= ctx
->Scissor
.ScissorArray
[0].X
;
544 y1
= ctx
->DrawBuffer
->Height
- (ctx
->Scissor
.ScissorArray
[0].Y
545 + ctx
->Scissor
.ScissorArray
[0].Height
);
546 x2
= ctx
->Scissor
.ScissorArray
[0].X
547 + ctx
->Scissor
.ScissorArray
[0].Width
- 1;
548 y2
= y1
+ ctx
->Scissor
.ScissorArray
[0].Height
- 1;
549 DBG("%s %d..%d,%d..%d (inverted)\n", __func__
, x1
, x2
, y1
, y2
);
552 /* FBO - not inverted
554 x1
= ctx
->Scissor
.ScissorArray
[0].X
;
555 y1
= ctx
->Scissor
.ScissorArray
[0].Y
;
556 x2
= ctx
->Scissor
.ScissorArray
[0].X
557 + ctx
->Scissor
.ScissorArray
[0].Width
- 1;
558 y2
= ctx
->Scissor
.ScissorArray
[0].Y
559 + ctx
->Scissor
.ScissorArray
[0].Height
- 1;
560 DBG("%s %d..%d,%d..%d (not inverted)\n", __func__
, x1
, x2
, y1
, y2
);
563 x1
= CLAMP(x1
, 0, ctx
->DrawBuffer
->Width
- 1);
564 y1
= CLAMP(y1
, 0, ctx
->DrawBuffer
->Height
- 1);
565 x2
= CLAMP(x2
, 0, ctx
->DrawBuffer
->Width
- 1);
566 y2
= CLAMP(y2
, 0, ctx
->DrawBuffer
->Height
- 1);
568 DBG("%s %d..%d,%d..%d (clamped)\n", __func__
, x1
, x2
, y1
, y2
);
570 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
571 i830
->state
.Buffer
[I830_DESTREG_SR1
] = (y1
<< 16) | (x1
& 0xffff);
572 i830
->state
.Buffer
[I830_DESTREG_SR2
] = (y2
<< 16) | (x2
& 0xffff);
576 i830LogicOp(struct gl_context
* ctx
, enum gl_logicop_mode opcode
)
578 struct i830_context
*i830
= i830_context(ctx
);
580 DBG("%s\n", __func__
);
582 assert((unsigned)opcode
<= 15);
583 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
584 i830
->state
.Ctx
[I830_CTXREG_STATE4
] &= ~LOGICOP_MASK
;
585 i830
->state
.Ctx
[I830_CTXREG_STATE4
] |= opcode
;
591 i830CullFaceFrontFace(struct gl_context
* ctx
, GLenum unused
)
593 struct i830_context
*i830
= i830_context(ctx
);
596 DBG("%s\n", __func__
);
598 if (!ctx
->Polygon
.CullFlag
) {
599 mode
= CULLMODE_NONE
;
601 else if (ctx
->Polygon
.CullFaceMode
!= GL_FRONT_AND_BACK
) {
604 if (ctx
->DrawBuffer
&& _mesa_is_user_fbo(ctx
->DrawBuffer
))
605 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
606 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT
)
607 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
608 if (ctx
->Polygon
.FrontFace
!= GL_CCW
)
609 mode
^= (CULLMODE_CW
^ CULLMODE_CCW
);
612 mode
= CULLMODE_BOTH
;
615 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
616 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~CULLMODE_MASK
;
617 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |= ENABLE_CULL_MODE
| mode
;
621 i830LineWidth(struct gl_context
* ctx
, GLfloat widthf
)
623 struct i830_context
*i830
= i830_context(ctx
);
627 DBG("%s\n", __func__
);
629 width
= (int) (widthf
* 2);
630 width
= CLAMP(width
, 1, 15);
632 state5
= i830
->state
.Ctx
[I830_CTXREG_STATE5
] & ~FIXED_LINE_WIDTH_MASK
;
633 state5
|= (ENABLE_FIXED_LINE_WIDTH
| FIXED_LINE_WIDTH(width
));
635 if (state5
!= i830
->state
.Ctx
[I830_CTXREG_STATE5
]) {
636 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
637 i830
->state
.Ctx
[I830_CTXREG_STATE5
] = state5
;
642 i830PointSize(struct gl_context
* ctx
, GLfloat size
)
644 struct i830_context
*i830
= i830_context(ctx
);
645 GLint point_size
= (int) size
;
647 DBG("%s\n", __func__
);
649 point_size
= CLAMP(point_size
, 1, 256);
650 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
651 i830
->state
.Ctx
[I830_CTXREG_STATE5
] &= ~FIXED_POINT_WIDTH_MASK
;
652 i830
->state
.Ctx
[I830_CTXREG_STATE5
] |= (ENABLE_FIXED_POINT_WIDTH
|
653 FIXED_POINT_WIDTH(point_size
));
657 /* =============================================================
662 i830ColorMask(struct gl_context
* ctx
,
663 GLboolean r
, GLboolean g
, GLboolean b
, GLboolean a
)
665 struct i830_context
*i830
= i830_context(ctx
);
668 DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __func__
, r
, g
, b
, a
);
670 tmp
= ((i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] & ~WRITEMASK_MASK
) |
673 ((!r
) << WRITEMASK_RED_SHIFT
) |
674 ((!g
) << WRITEMASK_GREEN_SHIFT
) |
675 ((!b
) << WRITEMASK_BLUE_SHIFT
) | ((!a
) << WRITEMASK_ALPHA_SHIFT
));
677 if (tmp
!= i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
]) {
678 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
679 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = tmp
;
684 update_specular(struct gl_context
* ctx
)
686 struct i830_context
*i830
= i830_context(ctx
);
688 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
689 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_SPEC_ADD_MASK
;
691 if (_mesa_need_secondary_color(ctx
))
692 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_SPEC_ADD
;
694 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_SPEC_ADD
;
698 i830LightModelfv(struct gl_context
* ctx
, GLenum pname
, const GLfloat
* param
)
700 DBG("%s\n", __func__
);
702 if (pname
== GL_LIGHT_MODEL_COLOR_CONTROL
) {
703 update_specular(ctx
);
707 /* In Mesa 3.5 we can reliably do native flatshading.
710 i830ShadeModel(struct gl_context
* ctx
, GLenum mode
)
712 struct i830_context
*i830
= i830_context(ctx
);
713 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
716 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
718 i830
->state
.Ctx
[I830_CTXREG_STATE3
] &= ~SHADE_MODE_MASK
;
720 if (mode
== GL_FLAT
) {
721 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |=
722 (ALPHA_SHADE_MODE(SHADE_MODE_FLAT
) | FOG_SHADE_MODE(SHADE_MODE_FLAT
)
723 | SPEC_SHADE_MODE(SHADE_MODE_FLAT
) |
724 COLOR_SHADE_MODE(SHADE_MODE_FLAT
));
727 i830
->state
.Ctx
[I830_CTXREG_STATE3
] |=
728 (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
) |
729 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
730 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
731 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
));
735 /* =============================================================
739 i830Fogfv(struct gl_context
* ctx
, GLenum pname
, const GLfloat
* param
)
741 struct i830_context
*i830
= i830_context(ctx
);
743 DBG("%s\n", __func__
);
745 if (pname
== GL_FOG_COLOR
) {
746 GLuint color
= (((GLubyte
) (ctx
->Fog
.Color
[0] * 255.0F
) << 16) |
747 ((GLubyte
) (ctx
->Fog
.Color
[1] * 255.0F
) << 8) |
748 ((GLubyte
) (ctx
->Fog
.Color
[2] * 255.0F
) << 0));
750 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
751 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] =
752 (_3DSTATE_FOG_COLOR_CMD
| color
);
756 /* =============================================================
760 i830Enable(struct gl_context
* ctx
, GLenum cap
, GLboolean state
)
762 struct i830_context
*i830
= i830_context(ctx
);
767 update_specular(ctx
);
771 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
772 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_ALPHA_TEST_MASK
;
774 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_ALPHA_TEST
;
776 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_ALPHA_TEST
;
781 i830EvalLogicOpBlendState(ctx
);
784 case GL_COLOR_LOGIC_OP
:
785 i830EvalLogicOpBlendState(ctx
);
787 /* Logicop doesn't seem to work at 16bpp:
789 if (i830
->intel
.ctx
.Visual
.rgbBits
== 16)
790 FALLBACK(&i830
->intel
, I830_FALLBACK_LOGICOP
, state
);
794 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
795 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &= ~ENABLE_DITHER
;
798 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_DITHER
;
800 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= DISABLE_DITHER
;
804 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
805 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_DEPTH_TEST_MASK
;
807 if (!ctx
->DrawBuffer
|| !ctx
->DrawBuffer
->Visual
.depthBits
)
811 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_DEPTH_TEST
;
813 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_DEPTH_TEST
;
815 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
817 i830DepthMask(ctx
, ctx
->Depth
.Mask
);
820 case GL_SCISSOR_TEST
:
821 I830_STATECHANGE(i830
, I830_UPLOAD_BUFFERS
);
824 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
825 (_3DSTATE_SCISSOR_ENABLE_CMD
| ENABLE_SCISSOR_RECT
);
827 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] =
828 (_3DSTATE_SCISSOR_ENABLE_CMD
| DISABLE_SCISSOR_RECT
);
833 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
835 i830
->state
.Ctx
[I830_CTXREG_AA
] &= ~AA_LINE_ENABLE
;
837 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_ENABLE
;
839 i830
->state
.Ctx
[I830_CTXREG_AA
] |= AA_LINE_DISABLE
;
843 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
844 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_DIS_FOG_MASK
;
846 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_FOG
;
848 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_FOG
;
852 i830CullFaceFrontFace(ctx
, 0);
858 case GL_STENCIL_TEST
:
860 bool hw_stencil
= false;
861 if (ctx
->DrawBuffer
) {
862 struct intel_renderbuffer
*irbStencil
863 = intel_get_renderbuffer(ctx
->DrawBuffer
, BUFFER_STENCIL
);
864 hw_stencil
= (irbStencil
&& irbStencil
->mt
);
867 I830_STATECHANGE(i830
, I830_UPLOAD_CTX
);
870 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= ENABLE_STENCIL_TEST
;
871 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |= ENABLE_STENCIL_WRITE
;
874 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] &= ~ENABLE_STENCIL_TEST
;
875 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] &=
876 ~ENABLE_STENCIL_WRITE
;
877 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] |= DISABLE_STENCIL_TEST
;
878 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] |=
879 DISABLE_STENCIL_WRITE
;
883 FALLBACK(&i830
->intel
, I830_FALLBACK_STENCIL
, state
);
888 case GL_POLYGON_STIPPLE
:
889 /* The stipple command worked on my 855GM box, but not my 845G.
890 * I'll do more testing later to find out exactly which hardware
891 * supports it. Disabled for now.
893 if (i830
->intel
.hw_stipple
&&
894 i830
->intel
.reduced_primitive
== GL_TRIANGLES
) {
895 I830_STATECHANGE(i830
, I830_UPLOAD_STIPPLE
);
896 i830
->state
.Stipple
[I830_STPREG_ST1
] &= ~ST1_ENABLE
;
898 i830
->state
.Stipple
[I830_STPREG_ST1
] |= ST1_ENABLE
;
909 i830_init_packets(struct i830_context
*i830
)
912 memset(&i830
->state
, 0, sizeof(i830
->state
));
914 /* Set default blend state */
915 i830
->state
.TexBlend
[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
917 ENABLE_TEXOUTPUT_WRT_SEL
|
918 TEXOP_OUTPUT_CURRENT
|
919 DISABLE_TEX_CNTRL_STAGE
|
922 TEXOP_LAST_STAGE
| TEXBLENDOP_ARG1
);
923 i830
->state
.TexBlend
[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
925 ENABLE_TEXOUTPUT_WRT_SEL
|
926 TEXOP_OUTPUT_CURRENT
|
928 TEXOP_MODIFY_PARMS
| TEXBLENDOP_ARG1
);
929 i830
->state
.TexBlend
[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
932 TEXBLENDARG_MODIFY_PARMS
|
933 TEXBLENDARG_DIFFUSE
);
934 i830
->state
.TexBlend
[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
937 TEXBLENDARG_MODIFY_PARMS
|
938 TEXBLENDARG_DIFFUSE
);
940 i830
->state
.TexBlendWordsUsed
[0] = 4;
943 i830
->state
.Ctx
[I830_CTXREG_VF
] = 0;
944 i830
->state
.Ctx
[I830_CTXREG_VF2
] = 0;
946 i830
->state
.Ctx
[I830_CTXREG_AA
] = (_3DSTATE_AA_CMD
|
947 AA_LINE_ECAAR_WIDTH_ENABLE
|
948 AA_LINE_ECAAR_WIDTH_1_0
|
949 AA_LINE_REGION_WIDTH_ENABLE
|
950 AA_LINE_REGION_WIDTH_1_0
|
953 i830
->state
.Ctx
[I830_CTXREG_ENABLES_1
] = (_3DSTATE_ENABLES_1_CMD
|
955 DISABLE_STENCIL_TEST
|
960 DISABLE_COLOR_BLEND
|
963 #if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */
964 if (i830
->intel
.hw_stencil
) {
965 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
966 ENABLE_STENCIL_WRITE
|
970 /* set no color comps disabled */
977 i830
->state
.Ctx
[I830_CTXREG_ENABLES_2
] = (_3DSTATE_ENABLES_2_CMD
|
978 DISABLE_STENCIL_WRITE
|
982 /* set no color comps disabled */
987 i830
->state
.Ctx
[I830_CTXREG_STATE1
] = (_3DSTATE_MODES_1_CMD
|
988 ENABLE_COLR_BLND_FUNC
|
990 ENABLE_SRC_BLND_FACTOR
|
991 SRC_BLND_FACT(BLENDFACT_ONE
) |
992 ENABLE_DST_BLND_FACTOR
|
993 DST_BLND_FACT(BLENDFACT_ZERO
));
995 i830
->state
.Ctx
[I830_CTXREG_STATE2
] = (_3DSTATE_MODES_2_CMD
|
996 ENABLE_GLOBAL_DEPTH_BIAS
|
997 GLOBAL_DEPTH_BIAS(0) |
998 ENABLE_ALPHA_TEST_FUNC
|
999 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS
)
1000 | ALPHA_REF_VALUE(0));
1002 i830
->state
.Ctx
[I830_CTXREG_STATE3
] = (_3DSTATE_MODES_3_CMD
|
1003 ENABLE_DEPTH_TEST_FUNC
|
1004 DEPTH_TEST_FUNC(COMPAREFUNC_LESS
) |
1005 ENABLE_ALPHA_SHADE_MODE
|
1006 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR
)
1007 | ENABLE_FOG_SHADE_MODE
|
1008 FOG_SHADE_MODE(SHADE_MODE_LINEAR
) |
1009 ENABLE_SPEC_SHADE_MODE
|
1010 SPEC_SHADE_MODE(SHADE_MODE_LINEAR
) |
1011 ENABLE_COLOR_SHADE_MODE
|
1012 COLOR_SHADE_MODE(SHADE_MODE_LINEAR
)
1013 | ENABLE_CULL_MODE
| CULLMODE_NONE
);
1015 i830
->state
.Ctx
[I830_CTXREG_STATE4
] = (_3DSTATE_MODES_4_CMD
|
1016 ENABLE_LOGIC_OP_FUNC
|
1017 LOGIC_OP_FUNC(LOGICOP_COPY
) |
1018 ENABLE_STENCIL_TEST_MASK
|
1019 STENCIL_TEST_MASK(0xff) |
1020 ENABLE_STENCIL_WRITE_MASK
|
1021 STENCIL_WRITE_MASK(0xff));
1023 i830
->state
.Ctx
[I830_CTXREG_STENCILTST
] = (_3DSTATE_STENCIL_TEST_CMD
|
1024 ENABLE_STENCIL_PARMS
|
1025 STENCIL_FAIL_OP(STENCILOP_KEEP
)
1027 STENCIL_PASS_DEPTH_FAIL_OP
1029 STENCIL_PASS_DEPTH_PASS_OP
1031 ENABLE_STENCIL_TEST_FUNC
|
1033 (COMPAREFUNC_ALWAYS
) |
1034 ENABLE_STENCIL_REF_VALUE
|
1035 STENCIL_REF_VALUE(0));
1037 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 */
1038 ENABLE_FIXED_POINT_WIDTH
|
1039 FIXED_POINT_WIDTH(1));
1041 i830
->state
.Ctx
[I830_CTXREG_IALPHAB
] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD
|
1042 DISABLE_INDPT_ALPHA_BLEND
|
1043 ENABLE_ALPHA_BLENDFUNC
|
1046 i830
->state
.Ctx
[I830_CTXREG_FOGCOLOR
] = (_3DSTATE_FOG_COLOR_CMD
|
1048 FOG_COLOR_GREEN(0) |
1051 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR0
] = _3DSTATE_CONST_BLEND_COLOR_CMD
;
1052 i830
->state
.Ctx
[I830_CTXREG_BLENDCOLOR1
] = 0;
1054 i830
->state
.Ctx
[I830_CTXREG_MCSB0
] = _3DSTATE_MAP_COORD_SETBIND_CMD
;
1055 i830
->state
.Ctx
[I830_CTXREG_MCSB1
] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3
) |
1056 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2
) |
1057 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1
) |
1058 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0
));
1060 i830
->state
.RasterRules
[I830_RASTER_RULES
] = (_3DSTATE_RASTER_RULES_CMD
|
1061 ENABLE_POINT_RASTER_RULE
|
1062 OGL_POINT_RASTER_RULE
|
1063 ENABLE_LINE_STRIP_PROVOKE_VRTX
|
1064 ENABLE_TRI_FAN_PROVOKE_VRTX
|
1065 ENABLE_TRI_STRIP_PROVOKE_VRTX
|
1066 LINE_STRIP_PROVOKE_VRTX(1) |
1067 TRI_FAN_PROVOKE_VRTX(2) |
1068 TRI_STRIP_PROVOKE_VRTX(2));
1071 i830
->state
.Stipple
[I830_STPREG_ST0
] = _3DSTATE_STIPPLE
;
1073 i830
->state
.Buffer
[I830_DESTREG_DV0
] = _3DSTATE_DST_BUF_VARS_CMD
;
1074 i830
->state
.Buffer
[I830_DESTREG_SR0
] = _3DSTATE_SCISSOR_RECT_0_CMD
;
1075 i830
->state
.Buffer
[I830_DESTREG_SR1
] = 0;
1076 i830
->state
.Buffer
[I830_DESTREG_SR2
] = 0;
1077 i830
->state
.Buffer
[I830_DESTREG_SENABLE
] = (_3DSTATE_SCISSOR_ENABLE_CMD
|
1078 DISABLE_SCISSOR_RECT
);
1082 i830_update_provoking_vertex(struct gl_context
* ctx
)
1084 struct i830_context
*i830
= i830_context(ctx
);
1086 I830_STATECHANGE(i830
, I830_UPLOAD_RASTER_RULES
);
1087 i830
->state
.RasterRules
[I830_RASTER_RULES
] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK
|
1088 TRI_FAN_PROVOKE_VRTX_MASK
|
1089 TRI_STRIP_PROVOKE_VRTX_MASK
);
1092 if (ctx
->Light
.ProvokingVertex
== GL_LAST_VERTEX_CONVENTION
) {
1093 i830
->state
.RasterRules
[I830_RASTER_RULES
] |= (LINE_STRIP_PROVOKE_VRTX(1) |
1094 TRI_FAN_PROVOKE_VRTX(2) |
1095 TRI_STRIP_PROVOKE_VRTX(2));
1097 i830
->state
.RasterRules
[I830_RASTER_RULES
] |= (LINE_STRIP_PROVOKE_VRTX(0) |
1098 TRI_FAN_PROVOKE_VRTX(1) |
1099 TRI_STRIP_PROVOKE_VRTX(0));
1103 /* Fallback to swrast for select and feedback.
1106 i830RenderMode(struct gl_context
*ctx
, GLenum mode
)
1108 struct intel_context
*intel
= intel_context(ctx
);
1109 FALLBACK(intel
, INTEL_FALLBACK_RENDERMODE
, (mode
!= GL_RENDER
));
1113 i830InitStateFuncs(struct dd_function_table
*functions
)
1115 functions
->AlphaFunc
= i830AlphaFunc
;
1116 functions
->BlendColor
= i830BlendColor
;
1117 functions
->BlendEquationSeparate
= i830BlendEquationSeparate
;
1118 functions
->BlendFuncSeparate
= i830BlendFuncSeparate
;
1119 functions
->ColorMask
= i830ColorMask
;
1120 functions
->CullFace
= i830CullFaceFrontFace
;
1121 functions
->DepthFunc
= i830DepthFunc
;
1122 functions
->DepthMask
= i830DepthMask
;
1123 functions
->Enable
= i830Enable
;
1124 functions
->Fogfv
= i830Fogfv
;
1125 functions
->FrontFace
= i830CullFaceFrontFace
;
1126 functions
->LightModelfv
= i830LightModelfv
;
1127 functions
->LineWidth
= i830LineWidth
;
1128 functions
->LogicOpcode
= i830LogicOp
;
1129 functions
->PointSize
= i830PointSize
;
1130 functions
->PolygonStipple
= i830PolygonStipple
;
1131 functions
->RenderMode
= i830RenderMode
;
1132 functions
->Scissor
= i830Scissor
;
1133 functions
->ShadeModel
= i830ShadeModel
;
1134 functions
->StencilFuncSeparate
= i830StencilFuncSeparate
;
1135 functions
->StencilMaskSeparate
= i830StencilMaskSeparate
;
1136 functions
->StencilOpSeparate
= i830StencilOpSeparate
;
1137 functions
->DepthRange
= i830DepthRange
;
1141 i830InitState(struct i830_context
*i830
)
1143 struct gl_context
*ctx
= &i830
->intel
.ctx
;
1145 i830_init_packets(i830
);
1147 _mesa_init_driver_state(ctx
);
1149 i830
->state
.emitted
= 0;
1150 i830
->state
.active
= (I830_UPLOAD_INVARIENT
|
1151 I830_UPLOAD_RASTER_RULES
|
1152 I830_UPLOAD_TEXBLEND(0) |
1153 I830_UPLOAD_STIPPLE
|
1154 I830_UPLOAD_CTX
| I830_UPLOAD_BUFFERS
);