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