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