Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / i915 / i830_state.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28
29 #include "glheader.h"
30 #include "context.h"
31 #include "macros.h"
32 #include "enums.h"
33 #include "dd.h"
34
35 #include "texmem.h"
36
37 #include "intel_screen.h"
38 #include "intel_batchbuffer.h"
39
40 #include "i830_context.h"
41 #include "i830_reg.h"
42
43 static void i830StencilFunc(GLcontext *ctx, GLenum func, GLint ref,
44 GLuint mask)
45 {
46 i830ContextPtr i830 = I830_CONTEXT(ctx);
47 int test = 0;
48
49 mask = mask & 0xff;
50
51 if (INTEL_DEBUG&DEBUG_DRI)
52 fprintf(stderr, "%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
53 _mesa_lookup_enum_by_nr(func), ref, mask);
54
55 switch(func) {
56 case GL_NEVER:
57 test = COMPAREFUNC_NEVER;
58 break;
59 case GL_LESS:
60 test = COMPAREFUNC_LESS;
61 break;
62 case GL_LEQUAL:
63 test = COMPAREFUNC_LEQUAL;
64 break;
65 case GL_GREATER:
66 test = COMPAREFUNC_GREATER;
67 break;
68 case GL_GEQUAL:
69 test = COMPAREFUNC_GEQUAL;
70 break;
71 case GL_NOTEQUAL:
72 test = COMPAREFUNC_NOTEQUAL;
73 break;
74 case GL_EQUAL:
75 test = COMPAREFUNC_EQUAL;
76 break;
77 case GL_ALWAYS:
78 test = COMPAREFUNC_ALWAYS;
79 break;
80 default:
81 return;
82 }
83
84 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
85 i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
86 i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
87 STENCIL_TEST_MASK(mask));
88 i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_REF_VALUE_MASK |
89 ENABLE_STENCIL_TEST_FUNC_MASK);
90 i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_REF_VALUE |
91 ENABLE_STENCIL_TEST_FUNC |
92 STENCIL_REF_VALUE(ref) |
93 STENCIL_TEST_FUNC(test));
94 }
95
96 static void i830StencilMask(GLcontext *ctx, GLuint mask)
97 {
98 i830ContextPtr i830 = I830_CONTEXT(ctx);
99
100 if (INTEL_DEBUG&DEBUG_DRI)
101 fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
102
103 mask = mask & 0xff;
104
105 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
106 i830->state.Ctx[I830_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
107 i830->state.Ctx[I830_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
108 STENCIL_WRITE_MASK(mask));
109 }
110
111 static void i830StencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
112 GLenum zpass)
113 {
114 i830ContextPtr i830 = I830_CONTEXT(ctx);
115 int fop, dfop, dpop;
116
117 if (INTEL_DEBUG&DEBUG_DRI)
118 fprintf(stderr, "%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
119 _mesa_lookup_enum_by_nr(fail),
120 _mesa_lookup_enum_by_nr(zfail),
121 _mesa_lookup_enum_by_nr(zpass));
122
123 fop = 0; dfop = 0; dpop = 0;
124
125 switch(fail) {
126 case GL_KEEP:
127 fop = STENCILOP_KEEP;
128 break;
129 case GL_ZERO:
130 fop = STENCILOP_ZERO;
131 break;
132 case GL_REPLACE:
133 fop = STENCILOP_REPLACE;
134 break;
135 case GL_INCR:
136 fop = STENCILOP_INCRSAT;
137 break;
138 case GL_DECR:
139 fop = STENCILOP_DECRSAT;
140 break;
141 case GL_INCR_WRAP:
142 fop = STENCILOP_INCR;
143 break;
144 case GL_DECR_WRAP:
145 fop = STENCILOP_DECR;
146 break;
147 case GL_INVERT:
148 fop = STENCILOP_INVERT;
149 break;
150 default:
151 break;
152 }
153 switch(zfail) {
154 case GL_KEEP:
155 dfop = STENCILOP_KEEP;
156 break;
157 case GL_ZERO:
158 dfop = STENCILOP_ZERO;
159 break;
160 case GL_REPLACE:
161 dfop = STENCILOP_REPLACE;
162 break;
163 case GL_INCR:
164 dfop = STENCILOP_INCRSAT;
165 break;
166 case GL_DECR:
167 dfop = STENCILOP_DECRSAT;
168 break;
169 case GL_INCR_WRAP:
170 dfop = STENCILOP_INCR;
171 break;
172 case GL_DECR_WRAP:
173 dfop = STENCILOP_DECR;
174 break;
175 case GL_INVERT:
176 dfop = STENCILOP_INVERT;
177 break;
178 default:
179 break;
180 }
181 switch(zpass) {
182 case GL_KEEP:
183 dpop = STENCILOP_KEEP;
184 break;
185 case GL_ZERO:
186 dpop = STENCILOP_ZERO;
187 break;
188 case GL_REPLACE:
189 dpop = STENCILOP_REPLACE;
190 break;
191 case GL_INCR:
192 dpop = STENCILOP_INCRSAT;
193 break;
194 case GL_DECR:
195 dpop = STENCILOP_DECRSAT;
196 break;
197 case GL_INCR_WRAP:
198 dpop = STENCILOP_INCR;
199 break;
200 case GL_DECR_WRAP:
201 dpop = STENCILOP_DECR;
202 break;
203 case GL_INVERT:
204 dpop = STENCILOP_INVERT;
205 break;
206 default:
207 break;
208 }
209
210
211 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
212 i830->state.Ctx[I830_CTXREG_STENCILTST] &= ~(STENCIL_OPS_MASK);
213 i830->state.Ctx[I830_CTXREG_STENCILTST] |= (ENABLE_STENCIL_PARMS |
214 STENCIL_FAIL_OP(fop) |
215 STENCIL_PASS_DEPTH_FAIL_OP(dfop) |
216 STENCIL_PASS_DEPTH_PASS_OP(dpop));
217 }
218
219 static void i830AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
220 {
221 i830ContextPtr i830 = I830_CONTEXT(ctx);
222 int test = 0;
223 GLubyte refByte;
224 GLuint refInt;
225
226 UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);
227 refInt = (GLuint)refByte;
228
229 switch(func) {
230 case GL_NEVER:
231 test = COMPAREFUNC_NEVER;
232 break;
233 case GL_LESS:
234 test = COMPAREFUNC_LESS;
235 break;
236 case GL_LEQUAL:
237 test = COMPAREFUNC_LEQUAL;
238 break;
239 case GL_GREATER:
240 test = COMPAREFUNC_GREATER;
241 break;
242 case GL_GEQUAL:
243 test = COMPAREFUNC_GEQUAL;
244 break;
245 case GL_NOTEQUAL:
246 test = COMPAREFUNC_NOTEQUAL;
247 break;
248 case GL_EQUAL:
249 test = COMPAREFUNC_EQUAL;
250 break;
251 case GL_ALWAYS:
252 test = COMPAREFUNC_ALWAYS;
253 break;
254 default:
255 return;
256 }
257
258 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
259 i830->state.Ctx[I830_CTXREG_STATE2] &= ~ALPHA_TEST_REF_MASK;
260 i830->state.Ctx[I830_CTXREG_STATE2] |= (ENABLE_ALPHA_TEST_FUNC |
261 ENABLE_ALPHA_REF_VALUE |
262 ALPHA_TEST_FUNC(test) |
263 ALPHA_REF_VALUE(refInt));
264 }
265
266 /**
267 * Makes sure that the proper enables are set for LogicOp, Independant Alpha
268 * Blend, and Blending. It needs to be called from numerous places where we
269 * could change the LogicOp or Independant Alpha Blend without subsequent
270 * calls to glEnable.
271 *
272 * \todo
273 * This function is substantially different from the old i830-specific driver.
274 * I'm not sure which is correct.
275 */
276 static void i830EvalLogicOpBlendState(GLcontext *ctx)
277 {
278 i830ContextPtr i830 = I830_CONTEXT(ctx);
279
280 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
281
282 if (ctx->Color._LogicOpEnabled) {
283 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
284 ENABLE_LOGIC_OP_MASK);
285 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
286 ENABLE_LOGIC_OP);
287 } else if (ctx->Color.BlendEnabled) {
288 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
289 ENABLE_LOGIC_OP_MASK);
290 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (ENABLE_COLOR_BLEND |
291 DISABLE_LOGIC_OP);
292 } else {
293 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~(ENABLE_COLOR_BLEND |
294 ENABLE_LOGIC_OP_MASK);
295 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= (DISABLE_COLOR_BLEND |
296 DISABLE_LOGIC_OP);
297 }
298 }
299
300 static void i830BlendColor(GLcontext *ctx, const GLfloat color[4])
301 {
302 i830ContextPtr i830 = I830_CONTEXT(ctx);
303 GLubyte r, g, b, a;
304
305 if (INTEL_DEBUG&DEBUG_DRI)
306 fprintf(stderr, "%s\n", __FUNCTION__);
307
308 UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]);
309 UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]);
310 UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);
311 UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);
312
313 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
314 i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = (a<<24) | (r<<16) | (g<<8) | b;
315 }
316
317
318 /**
319 * Calculate the hardware blend factor setting. This same function is used
320 * for source and destination of both alpha and RGB.
321 *
322 * \returns
323 * The hardware register value for the specified blend factor. This value
324 * will need to be shifted into the correct position for either source or
325 * destination factor.
326 */
327 static int translate_blend_factor( GLenum factor )
328 {
329 switch(factor) {
330 case GL_ZERO:
331 return BLENDFACT_ZERO;
332 case GL_SRC_ALPHA:
333 return BLENDFACT_SRC_ALPHA;
334 case GL_ONE:
335 return BLENDFACT_ONE;
336 case GL_SRC_COLOR:
337 return BLENDFACT_SRC_COLR;
338 case GL_ONE_MINUS_SRC_COLOR:
339 return BLENDFACT_INV_SRC_COLR;
340 case GL_DST_COLOR:
341 return BLENDFACT_DST_COLR;
342 case GL_ONE_MINUS_DST_COLOR:
343 return BLENDFACT_INV_DST_COLR;
344 case GL_ONE_MINUS_SRC_ALPHA:
345 return BLENDFACT_INV_SRC_ALPHA;
346 case GL_DST_ALPHA:
347 return BLENDFACT_DST_ALPHA;
348 case GL_ONE_MINUS_DST_ALPHA:
349 return BLENDFACT_INV_DST_ALPHA;
350 case GL_SRC_ALPHA_SATURATE:
351 return BLENDFACT_SRC_ALPHA_SATURATE;
352 case GL_CONSTANT_COLOR:
353 return BLENDFACT_CONST_COLOR;
354 case GL_ONE_MINUS_CONSTANT_COLOR:
355 return BLENDFACT_INV_CONST_COLOR;
356 case GL_CONSTANT_ALPHA:
357 return BLENDFACT_CONST_ALPHA;
358 case GL_ONE_MINUS_CONSTANT_ALPHA:
359 return BLENDFACT_INV_CONST_ALPHA;
360 default:
361 return BLENDFACT_ZERO;
362 }
363 }
364
365
366 /**
367 * Sets both the blend equation (called "function" in i830 docs) and the
368 * blend function (called "factor" in i830 docs). This is done in a single
369 * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
370 * change the interpretation of the blend function.
371 */
372 static void i830_set_blend_state( GLcontext * ctx )
373 {
374 i830ContextPtr i830 = I830_CONTEXT(ctx);
375 int funcA;
376 int funcRGB;
377 int eqnA;
378 int eqnRGB;
379 int iab;
380 int s1;
381
382
383 funcRGB = SRC_BLND_FACT( translate_blend_factor( ctx->Color.BlendSrcRGB ) )
384 | DST_BLND_FACT( translate_blend_factor( ctx->Color.BlendDstRGB ) );
385
386 switch(ctx->Color.BlendEquationRGB) {
387 case GL_FUNC_ADD:
388 eqnRGB = BLENDFUNC_ADD;
389 break;
390 case GL_MIN:
391 eqnRGB = BLENDFUNC_MIN;
392 funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
393 break;
394 case GL_MAX:
395 eqnRGB = BLENDFUNC_MAX;
396 funcRGB = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
397 break;
398 case GL_FUNC_SUBTRACT:
399 eqnRGB = BLENDFUNC_SUB;
400 break;
401 case GL_FUNC_REVERSE_SUBTRACT:
402 eqnRGB = BLENDFUNC_RVRSE_SUB;
403 break;
404 default:
405 fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
406 __func__, __LINE__, ctx->Color.BlendEquationRGB );
407 return;
408 }
409
410
411 funcA = SRC_ABLEND_FACT( translate_blend_factor( ctx->Color.BlendSrcA ) )
412 | DST_ABLEND_FACT( translate_blend_factor( ctx->Color.BlendDstA ) );
413
414 switch(ctx->Color.BlendEquationA) {
415 case GL_FUNC_ADD:
416 eqnA = BLENDFUNC_ADD;
417 break;
418 case GL_MIN:
419 eqnA = BLENDFUNC_MIN;
420 funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
421 break;
422 case GL_MAX:
423 eqnA = BLENDFUNC_MAX;
424 funcA = SRC_BLND_FACT(BLENDFACT_ONE) | DST_BLND_FACT(BLENDFACT_ONE);
425 break;
426 case GL_FUNC_SUBTRACT:
427 eqnA = BLENDFUNC_SUB;
428 break;
429 case GL_FUNC_REVERSE_SUBTRACT:
430 eqnA = BLENDFUNC_RVRSE_SUB;
431 break;
432 default:
433 fprintf( stderr, "[%s:%u] Invalid alpha blend equation (0x%04x).\n",
434 __func__, __LINE__, ctx->Color.BlendEquationA );
435 return;
436 }
437
438 iab = eqnA | funcA
439 | _3DSTATE_INDPT_ALPHA_BLEND_CMD
440 | ENABLE_SRC_ABLEND_FACTOR | ENABLE_DST_ABLEND_FACTOR
441 | ENABLE_ALPHA_BLENDFUNC;
442 s1 = eqnRGB | funcRGB
443 | _3DSTATE_MODES_1_CMD
444 | ENABLE_SRC_BLND_FACTOR | ENABLE_DST_BLND_FACTOR
445 | ENABLE_COLR_BLND_FUNC;
446
447 if ( (eqnA | funcA) != (eqnRGB | funcRGB) )
448 iab |= ENABLE_INDPT_ALPHA_BLEND;
449 else
450 iab |= DISABLE_INDPT_ALPHA_BLEND;
451
452 if (iab != i830->state.Ctx[I830_CTXREG_IALPHAB] ||
453 s1 != i830->state.Ctx[I830_CTXREG_STATE1]) {
454 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
455 i830->state.Ctx[I830_CTXREG_IALPHAB] = iab;
456 i830->state.Ctx[I830_CTXREG_STATE1] = s1;
457 }
458
459 /* This will catch a logicop blend equation. It will also ensure
460 * independant alpha blend is really in the correct state (either enabled
461 * or disabled) if blending is already enabled.
462 */
463
464 i830EvalLogicOpBlendState(ctx);
465
466 if (0) {
467 fprintf(stderr, "[%s:%u] STATE1: 0x%08x IALPHAB: 0x%08x blend is %sabled\n",
468 __func__, __LINE__,
469 i830->state.Ctx[I830_CTXREG_STATE1],
470 i830->state.Ctx[I830_CTXREG_IALPHAB],
471 (ctx->Color.BlendEnabled) ? "en" : "dis");
472 }
473 }
474
475
476 static void i830BlendEquationSeparate(GLcontext *ctx, GLenum modeRGB,
477 GLenum modeA)
478 {
479 if (INTEL_DEBUG&DEBUG_DRI)
480 fprintf(stderr, "%s -> %s, %s\n", __FUNCTION__,
481 _mesa_lookup_enum_by_nr(modeRGB),
482 _mesa_lookup_enum_by_nr(modeA));
483
484 (void) modeRGB;
485 (void) modeA;
486 i830_set_blend_state( ctx );
487 }
488
489
490 static void i830BlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB,
491 GLenum dfactorRGB, GLenum sfactorA,
492 GLenum dfactorA )
493 {
494 if (INTEL_DEBUG&DEBUG_DRI)
495 fprintf(stderr, "%s -> RGB(%s, %s) A(%s, %s)\n", __FUNCTION__,
496 _mesa_lookup_enum_by_nr(sfactorRGB),
497 _mesa_lookup_enum_by_nr(dfactorRGB),
498 _mesa_lookup_enum_by_nr(sfactorA),
499 _mesa_lookup_enum_by_nr(dfactorA));
500
501 (void) sfactorRGB;
502 (void) dfactorRGB;
503 (void) sfactorA;
504 (void) dfactorA;
505 i830_set_blend_state( ctx );
506 }
507
508
509
510 static void i830DepthFunc(GLcontext *ctx, GLenum func)
511 {
512 i830ContextPtr i830 = I830_CONTEXT(ctx);
513 int test = 0;
514
515 if (INTEL_DEBUG&DEBUG_DRI)
516 fprintf(stderr, "%s\n", __FUNCTION__);
517
518 switch(func) {
519 case GL_NEVER:
520 test = COMPAREFUNC_NEVER;
521 break;
522 case GL_LESS:
523 test = COMPAREFUNC_LESS;
524 break;
525 case GL_LEQUAL:
526 test = COMPAREFUNC_LEQUAL;
527 break;
528 case GL_GREATER:
529 test = COMPAREFUNC_GREATER;
530 break;
531 case GL_GEQUAL:
532 test = COMPAREFUNC_GEQUAL;
533 break;
534 case GL_NOTEQUAL:
535 test = COMPAREFUNC_NOTEQUAL;
536 break;
537 case GL_EQUAL:
538 test = COMPAREFUNC_EQUAL;
539 break;
540 case GL_ALWAYS:
541 test = COMPAREFUNC_ALWAYS;
542 break;
543 default: return;
544 }
545
546 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
547 i830->state.Ctx[I830_CTXREG_STATE3] &= ~DEPTH_TEST_FUNC_MASK;
548 i830->state.Ctx[I830_CTXREG_STATE3] |= (ENABLE_DEPTH_TEST_FUNC |
549 DEPTH_TEST_FUNC(test));
550 }
551
552 static void i830DepthMask(GLcontext *ctx, GLboolean flag)
553 {
554 i830ContextPtr i830 = I830_CONTEXT(ctx);
555
556 if (INTEL_DEBUG&DEBUG_DRI)
557 fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
558
559 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
560
561 i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DIS_DEPTH_WRITE_MASK;
562
563 if (flag && ctx->Depth.Test)
564 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DEPTH_WRITE;
565 else
566 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DEPTH_WRITE;
567 }
568
569 /* =============================================================
570 * Polygon stipple
571 *
572 * The i830 supports a 4x4 stipple natively, GL wants 32x32.
573 * Fortunately stipple is usually a repeating pattern.
574 */
575 static void i830PolygonStipple( GLcontext *ctx, const GLubyte *mask )
576 {
577 i830ContextPtr i830 = I830_CONTEXT(ctx);
578 const GLubyte *m = mask;
579 GLubyte p[4];
580 int i,j,k;
581 int active = (ctx->Polygon.StippleFlag &&
582 i830->intel.reduced_primitive == GL_TRIANGLES);
583 GLuint newMask;
584
585 if (active) {
586 I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
587 i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE;
588 }
589
590 p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
591 p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
592 p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
593 p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
594
595 for (k = 0 ; k < 8 ; k++)
596 for (j = 3 ; j >= 0; j--)
597 for (i = 0 ; i < 4 ; i++, m++)
598 if (*m != p[j]) {
599 i830->intel.hw_stipple = 0;
600 return;
601 }
602
603 newMask = (((p[0] & 0xf) << 0) |
604 ((p[1] & 0xf) << 4) |
605 ((p[2] & 0xf) << 8) |
606 ((p[3] & 0xf) << 12));
607
608
609 if (newMask == 0xffff || newMask == 0x0) {
610 /* this is needed to make conform pass */
611 i830->intel.hw_stipple = 0;
612 return;
613 }
614
615 i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff;
616 i830->state.Stipple[I830_STPREG_ST1] |= newMask;
617 i830->intel.hw_stipple = 1;
618
619 if (active)
620 i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE;
621 }
622
623
624 /* =============================================================
625 * Hardware clipping
626 */
627 static void i830Scissor(GLcontext *ctx, GLint x, GLint y,
628 GLsizei w, GLsizei h)
629 {
630 i830ContextPtr i830 = I830_CONTEXT(ctx);
631 intelScreenPrivate *screen = i830->intel.intelScreen;
632 int x1, y1, x2, y2;
633
634 if (!i830->intel.driDrawable)
635 return;
636
637 x1 = x;
638 y1 = i830->intel.driDrawable->h - (y + h);
639 x2 = x + w - 1;
640 y2 = y1 + h - 1;
641
642 if (INTEL_DEBUG&DEBUG_DRI)
643 fprintf(stderr, "[%s] x(%d) y(%d) w(%d) h(%d)\n", __FUNCTION__,
644 x, y, w, h);
645
646 if (x1 < 0) x1 = 0;
647 if (y1 < 0) y1 = 0;
648 if (x2 < 0) x2 = 0;
649 if (y2 < 0) y2 = 0;
650
651 if (x2 >= screen->width) x2 = screen->width-1;
652 if (y2 >= screen->height) y2 = screen->height-1;
653 if (x1 >= screen->width) x1 = screen->width-1;
654 if (y1 >= screen->height) y1 = screen->height-1;
655
656
657 I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
658 i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);
659 i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);
660 }
661
662 static void i830LogicOp(GLcontext *ctx, GLenum opcode)
663 {
664 i830ContextPtr i830 = I830_CONTEXT(ctx);
665 int tmp = 0;
666
667 if (INTEL_DEBUG&DEBUG_DRI)
668 fprintf(stderr, "%s\n", __FUNCTION__);
669
670 /* FIXME: This should be a look-up table, like the r200 driver. */
671 switch(opcode) {
672 case GL_CLEAR:
673 tmp = LOGICOP_CLEAR;
674 break;
675 case GL_AND:
676 tmp = LOGICOP_AND;
677 break;
678 case GL_AND_REVERSE:
679 tmp = LOGICOP_AND_RVRSE;
680 break;
681 case GL_COPY:
682 tmp = LOGICOP_COPY;
683 break;
684 case GL_COPY_INVERTED:
685 tmp = LOGICOP_COPY_INV;
686 break;
687 case GL_AND_INVERTED:
688 tmp = LOGICOP_AND_INV;
689 break;
690 case GL_NOOP:
691 tmp = LOGICOP_NOOP;
692 break;
693 case GL_XOR:
694 tmp = LOGICOP_XOR;
695 break;
696 case GL_OR:
697 tmp = LOGICOP_OR;
698 break;
699 case GL_OR_INVERTED:
700 tmp = LOGICOP_OR_INV;
701 break;
702 case GL_NOR:
703 tmp = LOGICOP_NOR;
704 break;
705 case GL_EQUIV:
706 tmp = LOGICOP_EQUIV;
707 break;
708 case GL_INVERT:
709 tmp = LOGICOP_INV;
710 break;
711 case GL_OR_REVERSE:
712 tmp = LOGICOP_OR_RVRSE;
713 break;
714 case GL_NAND:
715 tmp = LOGICOP_NAND;
716 break;
717 case GL_SET:
718 tmp = LOGICOP_SET;
719 break;
720 default:
721 return;
722 }
723
724 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
725 i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK;
726 i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);
727 }
728
729
730
731 static void i830CullFaceFrontFace(GLcontext *ctx, GLenum unused)
732 {
733 i830ContextPtr i830 = I830_CONTEXT(ctx);
734 GLuint mode;
735
736 if (INTEL_DEBUG&DEBUG_DRI)
737 fprintf(stderr, "%s\n", __FUNCTION__);
738
739 if (!ctx->Polygon.CullFlag) {
740 mode = CULLMODE_NONE;
741 }
742 else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
743 mode = CULLMODE_CW;
744
745 if (ctx->Polygon.CullFaceMode == GL_FRONT)
746 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
747 if (ctx->Polygon.FrontFace != GL_CCW)
748 mode ^= (CULLMODE_CW ^ CULLMODE_CCW);
749 }
750 else {
751 mode = CULLMODE_BOTH;
752 }
753
754 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
755 i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK;
756 i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode;
757 }
758
759 static void i830LineWidth( GLcontext *ctx, GLfloat widthf )
760 {
761 i830ContextPtr i830 = I830_CONTEXT( ctx );
762 int width;
763 int state5;
764
765 if (INTEL_DEBUG&DEBUG_DRI)
766 fprintf(stderr, "%s\n", __FUNCTION__);
767
768 width = (int)(widthf * 2);
769 CLAMP_SELF(width, 1, 15);
770
771 state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK;
772 state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width));
773
774 if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) {
775 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
776 i830->state.Ctx[I830_CTXREG_STATE5] = state5;
777 }
778 }
779
780 static void i830PointSize(GLcontext *ctx, GLfloat size)
781 {
782 i830ContextPtr i830 = I830_CONTEXT(ctx);
783 GLint point_size = (int)size;
784
785 if (INTEL_DEBUG&DEBUG_DRI)
786 fprintf(stderr, "%s\n", __FUNCTION__);
787
788 CLAMP_SELF(point_size, 1, 256);
789 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
790 i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK;
791 i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH |
792 FIXED_POINT_WIDTH(point_size));
793 }
794
795
796 /* =============================================================
797 * Color masks
798 */
799
800 static void i830ColorMask(GLcontext *ctx,
801 GLboolean r, GLboolean g,
802 GLboolean b, GLboolean a)
803 {
804 i830ContextPtr i830 = I830_CONTEXT( ctx );
805 GLuint tmp = 0;
806
807 if (INTEL_DEBUG&DEBUG_DRI)
808 fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
809
810 tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) |
811 ENABLE_COLOR_MASK |
812 ENABLE_COLOR_WRITE |
813 ((!r) << WRITEMASK_RED_SHIFT) |
814 ((!g) << WRITEMASK_GREEN_SHIFT) |
815 ((!b) << WRITEMASK_BLUE_SHIFT) |
816 ((!a) << WRITEMASK_ALPHA_SHIFT));
817
818 if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) {
819 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
820 i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp;
821 }
822 }
823
824 static void update_specular( GLcontext *ctx )
825 {
826 i830ContextPtr i830 = I830_CONTEXT( ctx );
827
828 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
829 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK;
830
831 if (NEED_SECONDARY_COLOR(ctx))
832 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD;
833 else
834 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD;
835 }
836
837 static void i830LightModelfv(GLcontext *ctx, GLenum pname,
838 const GLfloat *param)
839 {
840 if (INTEL_DEBUG&DEBUG_DRI)
841 fprintf(stderr, "%s\n", __FUNCTION__);
842
843 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
844 update_specular( ctx );
845 }
846 }
847
848 /* In Mesa 3.5 we can reliably do native flatshading.
849 */
850 static void i830ShadeModel(GLcontext *ctx, GLenum mode)
851 {
852 i830ContextPtr i830 = I830_CONTEXT(ctx);
853 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
854
855
856 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4))
857
858 i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK;
859
860 if (mode == GL_FLAT) {
861 i830->state.Ctx[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) |
862 FOG_SHADE_MODE(SHADE_MODE_FLAT) |
863 SPEC_SHADE_MODE(SHADE_MODE_FLAT) |
864 COLOR_SHADE_MODE(SHADE_MODE_FLAT));
865 } else {
866 i830->state.Ctx[I830_CTXREG_STATE3] |= (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
867 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
868 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
869 COLOR_SHADE_MODE(SHADE_MODE_LINEAR));
870 }
871 }
872
873 /* =============================================================
874 * Fog
875 */
876 static void i830Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
877 {
878 i830ContextPtr i830 = I830_CONTEXT(ctx);
879
880 if (INTEL_DEBUG&DEBUG_DRI)
881 fprintf(stderr, "%s\n", __FUNCTION__);
882
883 if (pname == GL_FOG_COLOR) {
884 GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
885 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
886 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
887
888 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
889 i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | color);
890 }
891 }
892
893 /* =============================================================
894 */
895
896 static void i830Enable(GLcontext *ctx, GLenum cap, GLboolean state)
897 {
898 i830ContextPtr i830 = I830_CONTEXT(ctx);
899
900 switch(cap) {
901 case GL_LIGHTING:
902 case GL_COLOR_SUM:
903 update_specular( ctx );
904 break;
905
906 case GL_ALPHA_TEST:
907 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
908 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK;
909 if (state)
910 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST;
911 else
912 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST;
913
914 break;
915
916 case GL_BLEND:
917 i830EvalLogicOpBlendState(ctx);
918 break;
919
920 case GL_COLOR_LOGIC_OP:
921 i830EvalLogicOpBlendState(ctx);
922
923 /* Logicop doesn't seem to work at 16bpp:
924 */
925 if (i830->intel.intelScreen->cpp == 2)
926 FALLBACK( &i830->intel, I830_FALLBACK_LOGICOP, state );
927 break;
928
929 case GL_DITHER:
930 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
931 i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER;
932
933 if (state)
934 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER;
935 else
936 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER;
937 break;
938
939 case GL_DEPTH_TEST:
940 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
941 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK;
942
943 if (state)
944 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST;
945 else
946 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST;
947
948 /* Also turn off depth writes when GL_DEPTH_TEST is disabled:
949 */
950 i830DepthMask( ctx, ctx->Depth.Mask );
951 break;
952
953 case GL_SCISSOR_TEST:
954 I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);
955
956 if (state)
957 i830->state.Buffer[I830_DESTREG_SENABLE] =
958 (_3DSTATE_SCISSOR_ENABLE_CMD |
959 ENABLE_SCISSOR_RECT);
960 else
961 i830->state.Buffer[I830_DESTREG_SENABLE] =
962 (_3DSTATE_SCISSOR_ENABLE_CMD |
963 DISABLE_SCISSOR_RECT);
964
965 break;
966
967 case GL_LINE_SMOOTH:
968 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
969
970 i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE;
971 if (state)
972 i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE;
973 else
974 i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE;
975 break;
976
977 case GL_FOG:
978 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
979 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK;
980 if (state)
981 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG;
982 else
983 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG;
984 break;
985
986 case GL_CULL_FACE:
987 i830CullFaceFrontFace(ctx, 0);
988 break;
989
990 case GL_TEXTURE_2D:
991 break;
992
993 case GL_STENCIL_TEST:
994 if (i830->intel.hw_stencil) {
995 I830_STATECHANGE(i830, I830_UPLOAD_CTX);
996
997 if (state) {
998 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST;
999 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE;
1000 } else {
1001 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST;
1002 i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_STENCIL_WRITE;
1003 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST;
1004 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_STENCIL_WRITE;
1005 }
1006 } else {
1007 FALLBACK( &i830->intel, I830_FALLBACK_STENCIL, state );
1008 }
1009 break;
1010
1011 case GL_POLYGON_STIPPLE:
1012 /* The stipple command worked on my 855GM box, but not my 845G.
1013 * I'll do more testing later to find out exactly which hardware
1014 * supports it. Disabled for now.
1015 */
1016 if (i830->intel.hw_stipple &&
1017 i830->intel.reduced_primitive == GL_TRIANGLES)
1018 {
1019 I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE);
1020 i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE;
1021 if (state)
1022 i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE;
1023 }
1024 break;
1025
1026 default:
1027 ;
1028 }
1029 }
1030
1031
1032 static void i830_init_packets( i830ContextPtr i830 )
1033 {
1034 intelScreenPrivate *screen = i830->intel.intelScreen;
1035
1036 /* Zero all state */
1037 memset(&i830->state, 0, sizeof(i830->state));
1038
1039 /* Set default blend state */
1040 i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
1041 TEXPIPE_COLOR |
1042 ENABLE_TEXOUTPUT_WRT_SEL |
1043 TEXOP_OUTPUT_CURRENT |
1044 DISABLE_TEX_CNTRL_STAGE |
1045 TEXOP_SCALE_1X |
1046 TEXOP_MODIFY_PARMS |
1047 TEXOP_LAST_STAGE |
1048 TEXBLENDOP_ARG1);
1049 i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) |
1050 TEXPIPE_ALPHA |
1051 ENABLE_TEXOUTPUT_WRT_SEL |
1052 TEXOP_OUTPUT_CURRENT |
1053 TEXOP_SCALE_1X |
1054 TEXOP_MODIFY_PARMS |
1055 TEXBLENDOP_ARG1);
1056 i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
1057 TEXPIPE_COLOR |
1058 TEXBLEND_ARG1 |
1059 TEXBLENDARG_MODIFY_PARMS |
1060 TEXBLENDARG_DIFFUSE);
1061 i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) |
1062 TEXPIPE_ALPHA |
1063 TEXBLEND_ARG1 |
1064 TEXBLENDARG_MODIFY_PARMS |
1065 TEXBLENDARG_DIFFUSE);
1066
1067 i830->state.TexBlendWordsUsed[0] = 4;
1068
1069
1070 i830->state.Ctx[I830_CTXREG_VF] = 0;
1071 i830->state.Ctx[I830_CTXREG_VF2] = 0;
1072
1073 i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD |
1074 AA_LINE_ECAAR_WIDTH_ENABLE |
1075 AA_LINE_ECAAR_WIDTH_1_0 |
1076 AA_LINE_REGION_WIDTH_ENABLE |
1077 AA_LINE_REGION_WIDTH_1_0 |
1078 AA_LINE_DISABLE);
1079
1080 i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD |
1081 DISABLE_LOGIC_OP |
1082 DISABLE_STENCIL_TEST |
1083 DISABLE_DEPTH_BIAS |
1084 DISABLE_SPEC_ADD |
1085 DISABLE_FOG |
1086 DISABLE_ALPHA_TEST |
1087 DISABLE_COLOR_BLEND |
1088 DISABLE_DEPTH_TEST);
1089
1090 if (i830->intel.hw_stencil) {
1091 i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD |
1092 ENABLE_STENCIL_WRITE |
1093 ENABLE_TEX_CACHE |
1094 ENABLE_DITHER |
1095 ENABLE_COLOR_MASK |
1096 /* set no color comps disabled */
1097 ENABLE_COLOR_WRITE |
1098 ENABLE_DEPTH_WRITE);
1099 } else {
1100 i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD |
1101 DISABLE_STENCIL_WRITE |
1102 ENABLE_TEX_CACHE |
1103 ENABLE_DITHER |
1104 ENABLE_COLOR_MASK |
1105 /* set no color comps disabled */
1106 ENABLE_COLOR_WRITE |
1107 ENABLE_DEPTH_WRITE);
1108 }
1109
1110 i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD |
1111 ENABLE_COLR_BLND_FUNC |
1112 BLENDFUNC_ADD |
1113 ENABLE_SRC_BLND_FACTOR |
1114 SRC_BLND_FACT(BLENDFACT_ONE) |
1115 ENABLE_DST_BLND_FACTOR |
1116 DST_BLND_FACT(BLENDFACT_ZERO) );
1117
1118 i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD |
1119 ENABLE_GLOBAL_DEPTH_BIAS |
1120 GLOBAL_DEPTH_BIAS(0) |
1121 ENABLE_ALPHA_TEST_FUNC |
1122 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1123 ALPHA_REF_VALUE(0) );
1124
1125 i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD |
1126 ENABLE_DEPTH_TEST_FUNC |
1127 DEPTH_TEST_FUNC(COMPAREFUNC_LESS) |
1128 ENABLE_ALPHA_SHADE_MODE |
1129 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) |
1130 ENABLE_FOG_SHADE_MODE |
1131 FOG_SHADE_MODE(SHADE_MODE_LINEAR) |
1132 ENABLE_SPEC_SHADE_MODE |
1133 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) |
1134 ENABLE_COLOR_SHADE_MODE |
1135 COLOR_SHADE_MODE(SHADE_MODE_LINEAR) |
1136 ENABLE_CULL_MODE |
1137 CULLMODE_NONE);
1138
1139 i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD |
1140 ENABLE_LOGIC_OP_FUNC |
1141 LOGIC_OP_FUNC(LOGICOP_COPY) |
1142 ENABLE_STENCIL_TEST_MASK |
1143 STENCIL_TEST_MASK(0xff) |
1144 ENABLE_STENCIL_WRITE_MASK |
1145 STENCIL_WRITE_MASK(0xff));
1146
1147 i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD |
1148 ENABLE_STENCIL_PARMS |
1149 STENCIL_FAIL_OP(STENCILOP_KEEP) |
1150 STENCIL_PASS_DEPTH_FAIL_OP(STENCILOP_KEEP) |
1151 STENCIL_PASS_DEPTH_PASS_OP(STENCILOP_KEEP) |
1152 ENABLE_STENCIL_TEST_FUNC |
1153 STENCIL_TEST_FUNC(COMPAREFUNC_ALWAYS) |
1154 ENABLE_STENCIL_REF_VALUE |
1155 STENCIL_REF_VALUE(0) );
1156
1157 i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD |
1158 FLUSH_TEXTURE_CACHE |
1159 ENABLE_SPRITE_POINT_TEX |
1160 SPRITE_POINT_TEX_OFF |
1161 ENABLE_FIXED_LINE_WIDTH |
1162 FIXED_LINE_WIDTH(0x2) | /* 1.0 */
1163 ENABLE_FIXED_POINT_WIDTH |
1164 FIXED_POINT_WIDTH(1) );
1165
1166 i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD |
1167 DISABLE_INDPT_ALPHA_BLEND |
1168 ENABLE_ALPHA_BLENDFUNC |
1169 ABLENDFUNC_ADD);
1170
1171 i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD |
1172 FOG_COLOR_RED(0) |
1173 FOG_COLOR_GREEN(0) |
1174 FOG_COLOR_BLUE(0));
1175
1176 i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
1177 i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0;
1178
1179 i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD;
1180 i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) |
1181 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) |
1182 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
1183 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
1184
1185
1186 i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE;
1187
1188 i830->state.Buffer[I830_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
1189 i830->state.Buffer[I830_DESTREG_CBUFADDR1] =
1190 (BUF_3D_ID_COLOR_BACK |
1191 BUF_3D_PITCH(screen->frontPitch * screen->cpp) |
1192 BUF_3D_USE_FENCE);
1193
1194
1195 i830->state.Buffer[I830_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
1196 i830->state.Buffer[I830_DESTREG_DBUFADDR1] =
1197 (BUF_3D_ID_DEPTH |
1198 BUF_3D_PITCH(screen->depthPitch * screen->cpp) |
1199 BUF_3D_USE_FENCE);
1200 i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depthOffset;
1201
1202
1203 i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
1204
1205 switch (screen->fbFormat) {
1206 case DV_PF_555:
1207 case DV_PF_565:
1208 i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1209 DSTORG_VERT_BIAS(0x8) | /* .5 */
1210 screen->fbFormat |
1211 DEPTH_IS_Z |
1212 DEPTH_FRMT_16_FIXED);
1213 break;
1214 case DV_PF_8888:
1215 i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
1216 DSTORG_VERT_BIAS(0x8) | /* .5 */
1217 screen->fbFormat |
1218 DEPTH_IS_Z |
1219 DEPTH_FRMT_24_FIXED_8_OTHER);
1220 break;
1221 }
1222
1223 i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD |
1224 DISABLE_SCISSOR_RECT);
1225 i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD;
1226 i830->state.Buffer[I830_DESTREG_SR1] = 0;
1227 i830->state.Buffer[I830_DESTREG_SR2] = 0;
1228 }
1229
1230
1231 void i830InitStateFuncs( struct dd_function_table *functions )
1232 {
1233 functions->AlphaFunc = i830AlphaFunc;
1234 functions->BlendColor = i830BlendColor;
1235 functions->BlendEquationSeparate = i830BlendEquationSeparate;
1236 functions->BlendFuncSeparate = i830BlendFuncSeparate;
1237 functions->ColorMask = i830ColorMask;
1238 functions->CullFace = i830CullFaceFrontFace;
1239 functions->DepthFunc = i830DepthFunc;
1240 functions->DepthMask = i830DepthMask;
1241 functions->Enable = i830Enable;
1242 functions->Fogfv = i830Fogfv;
1243 functions->FrontFace = i830CullFaceFrontFace;
1244 functions->LightModelfv = i830LightModelfv;
1245 functions->LineWidth = i830LineWidth;
1246 functions->LogicOpcode = i830LogicOp;
1247 functions->PointSize = i830PointSize;
1248 functions->PolygonStipple = i830PolygonStipple;
1249 functions->Scissor = i830Scissor;
1250 functions->ShadeModel = i830ShadeModel;
1251 functions->StencilFunc = i830StencilFunc;
1252 functions->StencilMask = i830StencilMask;
1253 functions->StencilOp = i830StencilOp;
1254 }
1255
1256 void i830InitState( i830ContextPtr i830 )
1257 {
1258 GLcontext *ctx = &i830->intel.ctx;
1259
1260 i830_init_packets( i830 );
1261
1262 intelInitState( ctx );
1263
1264 memcpy( &i830->initial, &i830->state, sizeof(i830->state) );
1265
1266 i830->current = &i830->state;
1267 i830->state.emitted = 0;
1268 i830->state.active = (I830_UPLOAD_TEXBLEND(0) |
1269 I830_UPLOAD_STIPPLE |
1270 I830_UPLOAD_CTX |
1271 I830_UPLOAD_BUFFERS);
1272 }
1273
1274
1275
1276
1277