1 /************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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", __func__, 60 _mesa_enum_to_string(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", __func__, 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", __func__, 98 _mesa_enum_to_string(fail), 99 _mesa_enum_to_string(zfail), 100 _mesa_enum_to_string(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, Independent Alpha 223 * Blend, and Blending. It needs to be called from numerous places where we 224 * could change the LogicOp or Independent Alpha Blend without subsequent 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", __func__); 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 __func__, __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 __func__, __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 * independent 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 __func__, __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", __func__, 392 _mesa_enum_to_string(modeRGB), 393 _mesa_enum_to_string(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", __func__, 406 _mesa_enum_to_string(sfactorRGB), 407 _mesa_enum_to_string(dfactorRGB), 408 _mesa_enum_to_string(sfactorA), 409 _mesa_enum_to_string(dfactorA)); 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", __func__); 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", __func__, 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.DepthRange() */ 455 static void 456 i830DepthRange(struct gl_context *ctx) 457 { 458 intelCalcViewport(ctx); 459 } 460 461 /* ============================================================= 462 * Polygon stipple 463 * 464 * The i830 supports a 4x4 stipple natively, GL wants 32x32. 465 * Fortunately stipple is usually a repeating pattern. 466 */ 467 static void 468 i830PolygonStipple(struct gl_context * ctx, const GLubyte * mask) 469 { 470 struct i830_context *i830 = i830_context(ctx); 471 const GLubyte *m; 472 GLubyte p[4]; 473 int i, j, k; 474 int active = (ctx->Polygon.StippleFlag && 475 i830->intel.reduced_primitive == GL_TRIANGLES); 476 GLuint newMask; 477 478 if (active) { 479 I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); 480 i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; 481 } 482 483 /* Use the already unpacked stipple data from the context rather than the 484 * uninterpreted mask passed in. 485 */ 486 mask = (const GLubyte *)ctx->PolygonStipple; 487 m = mask; 488 489 p[0] = mask[12] & 0xf; 490 p[0] |= p[0] << 4; 491 p[1] = mask[8] & 0xf; 492 p[1] |= p[1] << 4; 493 p[2] = mask[4] & 0xf; 494 p[2] |= p[2] << 4; 495 p[3] = mask[0] & 0xf; 496 p[3] |= p[3] << 4; 497 498 for (k = 0; k < 8; k++) 499 for (j = 3; j >= 0; j--) 500 for (i = 0; i < 4; i++, m++) 501 if (*m != p[j]) { 502 i830->intel.hw_stipple = 0; 503 return; 504 } 505 506 newMask = (((p[0] & 0xf) << 0) | 507 ((p[1] & 0xf) << 4) | 508 ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); 509 510 511 if (newMask == 0xffff || newMask == 0x0) { 512 /* this is needed to make conform pass */ 513 i830->intel.hw_stipple = 0; 514 return; 515 } 516 517 i830->state.Stipple[I830_STPREG_ST1] &= ~0xffff; 518 i830->state.Stipple[I830_STPREG_ST1] |= newMask; 519 i830->intel.hw_stipple = 1; 520 521 if (active) 522 i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; 523 } 524 525 526 /* ============================================================= 527 * Hardware clipping 528 */ 529 static void 530 i830Scissor(struct gl_context * ctx) 531 { 532 struct i830_context *i830 = i830_context(ctx); 533 int x1, y1, x2, y2; 534 535 if (!ctx->DrawBuffer) 536 return; 537 538 DBG("%s %d,%d %dx%d\n", __func__, 539 ctx->Scissor.ScissorArray[0].X, ctx->Scissor.ScissorArray[0].Y, 540 ctx->Scissor.ScissorArray[0].Width, ctx->Scissor.ScissorArray[0].Height); 541 542 if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { 543 x1 = ctx->Scissor.ScissorArray[0].X; 544 y1 = ctx->DrawBuffer->Height - (ctx->Scissor.ScissorArray[0].Y 545 + ctx->Scissor.ScissorArray[0].Height); 546 x2 = ctx->Scissor.ScissorArray[0].X 547 + ctx->Scissor.ScissorArray[0].Width - 1; 548 y2 = y1 + ctx->Scissor.ScissorArray[0].Height - 1; 549 DBG("%s %d..%d,%d..%d (inverted)\n", __func__, x1, x2, y1, y2); 550 } 551 else { 552 /* FBO - not inverted 553 */ 554 x1 = ctx->Scissor.ScissorArray[0].X; 555 y1 = ctx->Scissor.ScissorArray[0].Y; 556 x2 = ctx->Scissor.ScissorArray[0].X 557 + ctx->Scissor.ScissorArray[0].Width - 1; 558 y2 = ctx->Scissor.ScissorArray[0].Y 559 + ctx->Scissor.ScissorArray[0].Height - 1; 560 DBG("%s %d..%d,%d..%d (not inverted)\n", __func__, x1, x2, y1, y2); 561 } 562 563 x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); 564 y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); 565 x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); 566 y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); 567 568 DBG("%s %d..%d,%d..%d (clamped)\n", __func__, x1, x2, y1, y2); 569 570 I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); 571 i830->state.Buffer[I830_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); 572 i830->state.Buffer[I830_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); 573 } 574 575 static void 576 i830LogicOp(struct gl_context * ctx, GLenum opcode) 577 { 578 struct i830_context *i830 = i830_context(ctx); 579 int tmp = intel_translate_logic_op(opcode); 580 581 DBG("%s\n", __func__); 582 583 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 584 i830->state.Ctx[I830_CTXREG_STATE4] &= ~LOGICOP_MASK; 585 i830->state.Ctx[I830_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); 586 } 587 588 589 590 static void 591 i830CullFaceFrontFace(struct gl_context * ctx, GLenum unused) 592 { 593 struct i830_context *i830 = i830_context(ctx); 594 GLuint mode; 595 596 DBG("%s\n", __func__); 597 598 if (!ctx->Polygon.CullFlag) { 599 mode = CULLMODE_NONE; 600 } 601 else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { 602 mode = CULLMODE_CW; 603 604 if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer)) 605 mode ^= (CULLMODE_CW ^ CULLMODE_CCW); 606 if (ctx->Polygon.CullFaceMode == GL_FRONT) 607 mode ^= (CULLMODE_CW ^ CULLMODE_CCW); 608 if (ctx->Polygon.FrontFace != GL_CCW) 609 mode ^= (CULLMODE_CW ^ CULLMODE_CCW); 610 } 611 else { 612 mode = CULLMODE_BOTH; 613 } 614 615 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 616 i830->state.Ctx[I830_CTXREG_STATE3] &= ~CULLMODE_MASK; 617 i830->state.Ctx[I830_CTXREG_STATE3] |= ENABLE_CULL_MODE | mode; 618 } 619 620 static void 621 i830LineWidth(struct gl_context * ctx, GLfloat widthf) 622 { 623 struct i830_context *i830 = i830_context(ctx); 624 int width; 625 int state5; 626 627 DBG("%s\n", __func__); 628 629 width = (int) (widthf * 2); 630 width = CLAMP(width, 1, 15); 631 632 state5 = i830->state.Ctx[I830_CTXREG_STATE5] & ~FIXED_LINE_WIDTH_MASK; 633 state5 |= (ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(width)); 634 635 if (state5 != i830->state.Ctx[I830_CTXREG_STATE5]) { 636 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 637 i830->state.Ctx[I830_CTXREG_STATE5] = state5; 638 } 639 } 640 641 static void 642 i830PointSize(struct gl_context * ctx, GLfloat size) 643 { 644 struct i830_context *i830 = i830_context(ctx); 645 GLint point_size = (int) size; 646 647 DBG("%s\n", __func__); 648 649 point_size = CLAMP(point_size, 1, 256); 650 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 651 i830->state.Ctx[I830_CTXREG_STATE5] &= ~FIXED_POINT_WIDTH_MASK; 652 i830->state.Ctx[I830_CTXREG_STATE5] |= (ENABLE_FIXED_POINT_WIDTH | 653 FIXED_POINT_WIDTH(point_size)); 654 } 655 656 657 /* ============================================================= 658 * Color masks 659 */ 660 661 static void 662 i830ColorMask(struct gl_context * ctx, 663 GLboolean r, GLboolean g, GLboolean b, GLboolean a) 664 { 665 struct i830_context *i830 = i830_context(ctx); 666 GLuint tmp = 0; 667 668 DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __func__, r, g, b, a); 669 670 tmp = ((i830->state.Ctx[I830_CTXREG_ENABLES_2] & ~WRITEMASK_MASK) | 671 ENABLE_COLOR_MASK | 672 ENABLE_COLOR_WRITE | 673 ((!r) << WRITEMASK_RED_SHIFT) | 674 ((!g) << WRITEMASK_GREEN_SHIFT) | 675 ((!b) << WRITEMASK_BLUE_SHIFT) | ((!a) << WRITEMASK_ALPHA_SHIFT)); 676 677 if (tmp != i830->state.Ctx[I830_CTXREG_ENABLES_2]) { 678 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 679 i830->state.Ctx[I830_CTXREG_ENABLES_2] = tmp; 680 } 681 } 682 683 static void 684 update_specular(struct gl_context * ctx) 685 { 686 struct i830_context *i830 = i830_context(ctx); 687 688 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 689 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_SPEC_ADD_MASK; 690 691 if (_mesa_need_secondary_color(ctx)) 692 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_SPEC_ADD; 693 else 694 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_SPEC_ADD; 695 } 696 697 static void 698 i830LightModelfv(struct gl_context * ctx, GLenum pname, const GLfloat * param) 699 { 700 DBG("%s\n", __func__); 701 702 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { 703 update_specular(ctx); 704 } 705 } 706 707 /* In Mesa 3.5 we can reliably do native flatshading. 708 */ 709 static void 710 i830ShadeModel(struct gl_context * ctx, GLenum mode) 711 { 712 struct i830_context *i830 = i830_context(ctx); 713 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 714 715 716 #define SHADE_MODE_MASK ((1<<10)|(1<<8)|(1<<6)|(1<<4)) 717 718 i830->state.Ctx[I830_CTXREG_STATE3] &= ~SHADE_MODE_MASK; 719 720 if (mode == GL_FLAT) { 721 i830->state.Ctx[I830_CTXREG_STATE3] |= 722 (ALPHA_SHADE_MODE(SHADE_MODE_FLAT) | FOG_SHADE_MODE(SHADE_MODE_FLAT) 723 | SPEC_SHADE_MODE(SHADE_MODE_FLAT) | 724 COLOR_SHADE_MODE(SHADE_MODE_FLAT)); 725 } 726 else { 727 i830->state.Ctx[I830_CTXREG_STATE3] |= 728 (ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) | 729 FOG_SHADE_MODE(SHADE_MODE_LINEAR) | 730 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | 731 COLOR_SHADE_MODE(SHADE_MODE_LINEAR)); 732 } 733 } 734 735 /* ============================================================= 736 * Fog 737 */ 738 static void 739 i830Fogfv(struct gl_context * ctx, GLenum pname, const GLfloat * param) 740 { 741 struct i830_context *i830 = i830_context(ctx); 742 743 DBG("%s\n", __func__); 744 745 if (pname == GL_FOG_COLOR) { 746 GLuint color = (((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | 747 ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | 748 ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); 749 750 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 751 i830->state.Ctx[I830_CTXREG_FOGCOLOR] = 752 (_3DSTATE_FOG_COLOR_CMD | color); 753 } 754 } 755 756 /* ============================================================= 757 */ 758 759 static void 760 i830Enable(struct gl_context * ctx, GLenum cap, GLboolean state) 761 { 762 struct i830_context *i830 = i830_context(ctx); 763 764 switch (cap) { 765 case GL_LIGHTING: 766 case GL_COLOR_SUM: 767 update_specular(ctx); 768 break; 769 770 case GL_ALPHA_TEST: 771 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 772 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_ALPHA_TEST_MASK; 773 if (state) 774 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_ALPHA_TEST; 775 else 776 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_ALPHA_TEST; 777 778 break; 779 780 case GL_BLEND: 781 i830EvalLogicOpBlendState(ctx); 782 break; 783 784 case GL_COLOR_LOGIC_OP: 785 i830EvalLogicOpBlendState(ctx); 786 787 /* Logicop doesn't seem to work at 16bpp: 788 */ 789 if (i830->intel.ctx.Visual.rgbBits == 16) 790 FALLBACK(&i830->intel, I830_FALLBACK_LOGICOP, state); 791 break; 792 793 case GL_DITHER: 794 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 795 i830->state.Ctx[I830_CTXREG_ENABLES_2] &= ~ENABLE_DITHER; 796 797 if (state) 798 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_DITHER; 799 else 800 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= DISABLE_DITHER; 801 break; 802 803 case GL_DEPTH_TEST: 804 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 805 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_DEPTH_TEST_MASK; 806 807 if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits) 808 state = false; 809 810 if (state) 811 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_DEPTH_TEST; 812 else 813 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_DEPTH_TEST; 814 815 /* Also turn off depth writes when GL_DEPTH_TEST is disabled: 816 */ 817 i830DepthMask(ctx, ctx->Depth.Mask); 818 break; 819 820 case GL_SCISSOR_TEST: 821 I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS); 822 823 if (state) 824 i830->state.Buffer[I830_DESTREG_SENABLE] = 825 (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); 826 else 827 i830->state.Buffer[I830_DESTREG_SENABLE] = 828 (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 829 830 break; 831 832 case GL_LINE_SMOOTH: 833 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 834 835 i830->state.Ctx[I830_CTXREG_AA] &= ~AA_LINE_ENABLE; 836 if (state) 837 i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_ENABLE; 838 else 839 i830->state.Ctx[I830_CTXREG_AA] |= AA_LINE_DISABLE; 840 break; 841 842 case GL_FOG: 843 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 844 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_DIS_FOG_MASK; 845 if (state) 846 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_FOG; 847 else 848 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_FOG; 849 break; 850 851 case GL_CULL_FACE: 852 i830CullFaceFrontFace(ctx, 0); 853 break; 854 855 case GL_TEXTURE_2D: 856 break; 857 858 case GL_STENCIL_TEST: 859 { 860 bool hw_stencil = false; 861 if (ctx->DrawBuffer) { 862 struct intel_renderbuffer *irbStencil 863 = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); 864 hw_stencil = (irbStencil && irbStencil->mt); 865 } 866 if (hw_stencil) { 867 I830_STATECHANGE(i830, I830_UPLOAD_CTX); 868 869 if (state) { 870 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= ENABLE_STENCIL_TEST; 871 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= ENABLE_STENCIL_WRITE; 872 } 873 else { 874 i830->state.Ctx[I830_CTXREG_ENABLES_1] &= ~ENABLE_STENCIL_TEST; 875 i830->state.Ctx[I830_CTXREG_ENABLES_2] &= 876 ~ENABLE_STENCIL_WRITE; 877 i830->state.Ctx[I830_CTXREG_ENABLES_1] |= DISABLE_STENCIL_TEST; 878 i830->state.Ctx[I830_CTXREG_ENABLES_2] |= 879 DISABLE_STENCIL_WRITE; 880 } 881 } 882 else { 883 FALLBACK(&i830->intel, I830_FALLBACK_STENCIL, state); 884 } 885 } 886 break; 887 888 case GL_POLYGON_STIPPLE: 889 /* The stipple command worked on my 855GM box, but not my 845G. 890 * I'll do more testing later to find out exactly which hardware 891 * supports it. Disabled for now. 892 */ 893 if (i830->intel.hw_stipple && 894 i830->intel.reduced_primitive == GL_TRIANGLES) { 895 I830_STATECHANGE(i830, I830_UPLOAD_STIPPLE); 896 i830->state.Stipple[I830_STPREG_ST1] &= ~ST1_ENABLE; 897 if (state) 898 i830->state.Stipple[I830_STPREG_ST1] |= ST1_ENABLE; 899 } 900 break; 901 902 default: 903 ; 904 } 905 } 906 907 908 static void 909 i830_init_packets(struct i830_context *i830) 910 { 911 /* Zero all state */ 912 memset(&i830->state, 0, sizeof(i830->state)); 913 914 /* Set default blend state */ 915 i830->state.TexBlend[0][0] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | 916 TEXPIPE_COLOR | 917 ENABLE_TEXOUTPUT_WRT_SEL | 918 TEXOP_OUTPUT_CURRENT | 919 DISABLE_TEX_CNTRL_STAGE | 920 TEXOP_SCALE_1X | 921 TEXOP_MODIFY_PARMS | 922 TEXOP_LAST_STAGE | TEXBLENDOP_ARG1); 923 i830->state.TexBlend[0][1] = (_3DSTATE_MAP_BLEND_OP_CMD(0) | 924 TEXPIPE_ALPHA | 925 ENABLE_TEXOUTPUT_WRT_SEL | 926 TEXOP_OUTPUT_CURRENT | 927 TEXOP_SCALE_1X | 928 TEXOP_MODIFY_PARMS | TEXBLENDOP_ARG1); 929 i830->state.TexBlend[0][2] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | 930 TEXPIPE_COLOR | 931 TEXBLEND_ARG1 | 932 TEXBLENDARG_MODIFY_PARMS | 933 TEXBLENDARG_DIFFUSE); 934 i830->state.TexBlend[0][3] = (_3DSTATE_MAP_BLEND_ARG_CMD(0) | 935 TEXPIPE_ALPHA | 936 TEXBLEND_ARG1 | 937 TEXBLENDARG_MODIFY_PARMS | 938 TEXBLENDARG_DIFFUSE); 939 940 i830->state.TexBlendWordsUsed[0] = 4; 941 942 943 i830->state.Ctx[I830_CTXREG_VF] = 0; 944 i830->state.Ctx[I830_CTXREG_VF2] = 0; 945 946 i830->state.Ctx[I830_CTXREG_AA] = (_3DSTATE_AA_CMD | 947 AA_LINE_ECAAR_WIDTH_ENABLE | 948 AA_LINE_ECAAR_WIDTH_1_0 | 949 AA_LINE_REGION_WIDTH_ENABLE | 950 AA_LINE_REGION_WIDTH_1_0 | 951 AA_LINE_DISABLE); 952 953 i830->state.Ctx[I830_CTXREG_ENABLES_1] = (_3DSTATE_ENABLES_1_CMD | 954 DISABLE_LOGIC_OP | 955 DISABLE_STENCIL_TEST | 956 DISABLE_DEPTH_BIAS | 957 DISABLE_SPEC_ADD | 958 DISABLE_FOG | 959 DISABLE_ALPHA_TEST | 960 DISABLE_COLOR_BLEND | 961 DISABLE_DEPTH_TEST); 962 963 #if 000 /* XXX all the stencil enable state is set in i830Enable(), right? */ 964 if (i830->intel.hw_stencil) { 965 i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | 966 ENABLE_STENCIL_WRITE | 967 ENABLE_TEX_CACHE | 968 ENABLE_DITHER | 969 ENABLE_COLOR_MASK | 970 /* set no color comps disabled */ 971 ENABLE_COLOR_WRITE | 972 ENABLE_DEPTH_WRITE); 973 } 974 else 975 #endif 976 { 977 i830->state.Ctx[I830_CTXREG_ENABLES_2] = (_3DSTATE_ENABLES_2_CMD | 978 DISABLE_STENCIL_WRITE | 979 ENABLE_TEX_CACHE | 980 ENABLE_DITHER | 981 ENABLE_COLOR_MASK | 982 /* set no color comps disabled */ 983 ENABLE_COLOR_WRITE | 984 ENABLE_DEPTH_WRITE); 985 } 986 987 i830->state.Ctx[I830_CTXREG_STATE1] = (_3DSTATE_MODES_1_CMD | 988 ENABLE_COLR_BLND_FUNC | 989 BLENDFUNC_ADD | 990 ENABLE_SRC_BLND_FACTOR | 991 SRC_BLND_FACT(BLENDFACT_ONE) | 992 ENABLE_DST_BLND_FACTOR | 993 DST_BLND_FACT(BLENDFACT_ZERO)); 994 995 i830->state.Ctx[I830_CTXREG_STATE2] = (_3DSTATE_MODES_2_CMD | 996 ENABLE_GLOBAL_DEPTH_BIAS | 997 GLOBAL_DEPTH_BIAS(0) | 998 ENABLE_ALPHA_TEST_FUNC | 999 ALPHA_TEST_FUNC(COMPAREFUNC_ALWAYS) 1000 | ALPHA_REF_VALUE(0)); 1001 1002 i830->state.Ctx[I830_CTXREG_STATE3] = (_3DSTATE_MODES_3_CMD | 1003 ENABLE_DEPTH_TEST_FUNC | 1004 DEPTH_TEST_FUNC(COMPAREFUNC_LESS) | 1005 ENABLE_ALPHA_SHADE_MODE | 1006 ALPHA_SHADE_MODE(SHADE_MODE_LINEAR) 1007 | ENABLE_FOG_SHADE_MODE | 1008 FOG_SHADE_MODE(SHADE_MODE_LINEAR) | 1009 ENABLE_SPEC_SHADE_MODE | 1010 SPEC_SHADE_MODE(SHADE_MODE_LINEAR) | 1011 ENABLE_COLOR_SHADE_MODE | 1012 COLOR_SHADE_MODE(SHADE_MODE_LINEAR) 1013 | ENABLE_CULL_MODE | CULLMODE_NONE); 1014 1015 i830->state.Ctx[I830_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | 1016 ENABLE_LOGIC_OP_FUNC | 1017 LOGIC_OP_FUNC(LOGICOP_COPY) | 1018 ENABLE_STENCIL_TEST_MASK | 1019 STENCIL_TEST_MASK(0xff) | 1020 ENABLE_STENCIL_WRITE_MASK | 1021 STENCIL_WRITE_MASK(0xff)); 1022 1023 i830->state.Ctx[I830_CTXREG_STENCILTST] = (_3DSTATE_STENCIL_TEST_CMD | 1024 ENABLE_STENCIL_PARMS | 1025 STENCIL_FAIL_OP(STENCILOP_KEEP) 1026 | 1027 STENCIL_PASS_DEPTH_FAIL_OP 1028 (STENCILOP_KEEP) | 1029 STENCIL_PASS_DEPTH_PASS_OP 1030 (STENCILOP_KEEP) | 1031 ENABLE_STENCIL_TEST_FUNC | 1032 STENCIL_TEST_FUNC 1033 (COMPAREFUNC_ALWAYS) | 1034 ENABLE_STENCIL_REF_VALUE | 1035 STENCIL_REF_VALUE(0)); 1036 1037 i830->state.Ctx[I830_CTXREG_STATE5] = (_3DSTATE_MODES_5_CMD | FLUSH_TEXTURE_CACHE | ENABLE_SPRITE_POINT_TEX | SPRITE_POINT_TEX_OFF | ENABLE_FIXED_LINE_WIDTH | FIXED_LINE_WIDTH(0x2) | /* 1.0 */ 1038 ENABLE_FIXED_POINT_WIDTH | 1039 FIXED_POINT_WIDTH(1)); 1040 1041 i830->state.Ctx[I830_CTXREG_IALPHAB] = (_3DSTATE_INDPT_ALPHA_BLEND_CMD | 1042 DISABLE_INDPT_ALPHA_BLEND | 1043 ENABLE_ALPHA_BLENDFUNC | 1044 ABLENDFUNC_ADD); 1045 1046 i830->state.Ctx[I830_CTXREG_FOGCOLOR] = (_3DSTATE_FOG_COLOR_CMD | 1047 FOG_COLOR_RED(0) | 1048 FOG_COLOR_GREEN(0) | 1049 FOG_COLOR_BLUE(0)); 1050 1051 i830->state.Ctx[I830_CTXREG_BLENDCOLOR0] = _3DSTATE_CONST_BLEND_COLOR_CMD; 1052 i830->state.Ctx[I830_CTXREG_BLENDCOLOR1] = 0; 1053 1054 i830->state.Ctx[I830_CTXREG_MCSB0] = _3DSTATE_MAP_COORD_SETBIND_CMD; 1055 i830->state.Ctx[I830_CTXREG_MCSB1] = (TEXBIND_SET3(TEXCOORDSRC_VTXSET_3) | 1056 TEXBIND_SET2(TEXCOORDSRC_VTXSET_2) | 1057 TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) | 1058 TEXBIND_SET0(TEXCOORDSRC_VTXSET_0)); 1059 1060 i830->state.RasterRules[I830_RASTER_RULES] = (_3DSTATE_RASTER_RULES_CMD | 1061 ENABLE_POINT_RASTER_RULE | 1062 OGL_POINT_RASTER_RULE | 1063 ENABLE_LINE_STRIP_PROVOKE_VRTX | 1064 ENABLE_TRI_FAN_PROVOKE_VRTX | 1065 ENABLE_TRI_STRIP_PROVOKE_VRTX | 1066 LINE_STRIP_PROVOKE_VRTX(1) | 1067 TRI_FAN_PROVOKE_VRTX(2) | 1068 TRI_STRIP_PROVOKE_VRTX(2)); 1069 1070 1071 i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE; 1072 1073 i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; 1074 i830->state.Buffer[I830_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; 1075 i830->state.Buffer[I830_DESTREG_SR1] = 0; 1076 i830->state.Buffer[I830_DESTREG_SR2] = 0; 1077 i830->state.Buffer[I830_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | 1078 DISABLE_SCISSOR_RECT); 1079 } 1080 1081 void 1082 i830_update_provoking_vertex(struct gl_context * ctx) 1083 { 1084 struct i830_context *i830 = i830_context(ctx); 1085 1086 I830_STATECHANGE(i830, I830_UPLOAD_RASTER_RULES); 1087 i830->state.RasterRules[I830_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK | 1088 TRI_FAN_PROVOKE_VRTX_MASK | 1089 TRI_STRIP_PROVOKE_VRTX_MASK); 1090 1091 /* _NEW_LIGHT */ 1092 if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) { 1093 i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) | 1094 TRI_FAN_PROVOKE_VRTX(2) | 1095 TRI_STRIP_PROVOKE_VRTX(2)); 1096 } else { 1097 i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) | 1098 TRI_FAN_PROVOKE_VRTX(1) | 1099 TRI_STRIP_PROVOKE_VRTX(0)); 1100 } 1101 } 1102 1103 /* Fallback to swrast for select and feedback. 1104 */ 1105 static void 1106 i830RenderMode(struct gl_context *ctx, GLenum mode) 1107 { 1108 struct intel_context *intel = intel_context(ctx); 1109 FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); 1110 } 1111 1112 void 1113 i830InitStateFuncs(struct dd_function_table *functions) 1114 { 1115 functions->AlphaFunc = i830AlphaFunc; 1116 functions->BlendColor = i830BlendColor; 1117 functions->BlendEquationSeparate = i830BlendEquationSeparate; 1118 functions->BlendFuncSeparate = i830BlendFuncSeparate; 1119 functions->ColorMask = i830ColorMask; 1120 functions->CullFace = i830CullFaceFrontFace; 1121 functions->DepthFunc = i830DepthFunc; 1122 functions->DepthMask = i830DepthMask; 1123 functions->Enable = i830Enable; 1124 functions->Fogfv = i830Fogfv; 1125 functions->FrontFace = i830CullFaceFrontFace; 1126 functions->LightModelfv = i830LightModelfv; 1127 functions->LineWidth = i830LineWidth; 1128 functions->LogicOpcode = i830LogicOp; 1129 functions->PointSize = i830PointSize; 1130 functions->PolygonStipple = i830PolygonStipple; 1131 functions->RenderMode = i830RenderMode; 1132 functions->Scissor = i830Scissor; 1133 functions->ShadeModel = i830ShadeModel; 1134 functions->StencilFuncSeparate = i830StencilFuncSeparate; 1135 functions->StencilMaskSeparate = i830StencilMaskSeparate; 1136 functions->StencilOpSeparate = i830StencilOpSeparate; 1137 functions->DepthRange = i830DepthRange; 1138 } 1139 1140 void 1141 i830InitState(struct i830_context *i830) 1142 { 1143 struct gl_context *ctx = &i830->intel.ctx; 1144 1145 i830_init_packets(i830); 1146 1147 _mesa_init_driver_state(ctx); 1148 1149 i830->state.emitted = 0; 1150 i830->state.active = (I830_UPLOAD_INVARIENT | 1151 I830_UPLOAD_RASTER_RULES | 1152 I830_UPLOAD_TEXBLEND(0) | 1153 I830_UPLOAD_STIPPLE | 1154 I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); 1155 } 1156