i915_state.c revision 8cf9085bc7b96819d2bec1e749e15af58eefb2f3
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#include "tnl/tnl.h" 35#include "tnl/t_context.h" 36 37#include "texmem.h" 38 39#include "drivers/common/driverfuncs.h" 40 41#include "intel_fbo.h" 42#include "intel_screen.h" 43#include "intel_batchbuffer.h" 44 45#include "i915_context.h" 46#include "i915_reg.h" 47 48#define FILE_DEBUG_FLAG DEBUG_STATE 49 50static void 51i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, 52 GLuint mask) 53{ 54 struct i915_context *i915 = I915_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 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 64 i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; 65 i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | 66 STENCIL_TEST_MASK(mask)); 67 68 i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | 69 S5_STENCIL_TEST_FUNC_MASK); 70 71 i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | 72 (test << 73 S5_STENCIL_TEST_FUNC_SHIFT)); 74} 75 76static void 77i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) 78{ 79 struct i915_context *i915 = I915_CONTEXT(ctx); 80 81 DBG("%s : mask 0x%x\n", __FUNCTION__, mask); 82 83 mask = mask & 0xff; 84 85 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 86 i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; 87 i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | 88 STENCIL_WRITE_MASK(mask)); 89} 90 91 92static void 93i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, 94 GLenum zpass) 95{ 96 struct i915_context *i915 = I915_CONTEXT(ctx); 97 int fop = intel_translate_stencil_op(fail); 98 int dfop = intel_translate_stencil_op(zfail); 99 int dpop = intel_translate_stencil_op(zpass); 100 101 102 DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, 103 _mesa_lookup_enum_by_nr(fail), 104 _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); 105 106 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 107 108 i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | 109 S5_STENCIL_PASS_Z_FAIL_MASK | 110 S5_STENCIL_PASS_Z_PASS_MASK); 111 112 i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | 113 (dfop << 114 S5_STENCIL_PASS_Z_FAIL_SHIFT) | 115 (dpop << 116 S5_STENCIL_PASS_Z_PASS_SHIFT)); 117} 118 119static void 120i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) 121{ 122 struct i915_context *i915 = I915_CONTEXT(ctx); 123 int test = intel_translate_compare_func(func); 124 GLubyte refByte; 125 126 UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); 127 128 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 129 i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | 130 S6_ALPHA_REF_MASK); 131 i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | 132 (((GLuint) refByte) << 133 S6_ALPHA_REF_SHIFT)); 134} 135 136/* This function makes sure that the proper enables are 137 * set for LogicOp, Independant Alpha Blend, and Blending. 138 * It needs to be called from numerous places where we 139 * could change the LogicOp or Independant Alpha Blend without subsequent 140 * calls to glEnable. 141 */ 142static void 143i915EvalLogicOpBlendState(GLcontext * ctx) 144{ 145 struct i915_context *i915 = I915_CONTEXT(ctx); 146 147 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 148 149 if (RGBA_LOGICOP_ENABLED(ctx)) { 150 i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; 151 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; 152 } 153 else { 154 i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; 155 156 if (ctx->Color.BlendEnabled) { 157 i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; 158 } 159 else { 160 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; 161 } 162 } 163} 164 165static void 166i915BlendColor(GLcontext * ctx, const GLfloat color[4]) 167{ 168 struct i915_context *i915 = I915_CONTEXT(ctx); 169 GLubyte r, g, b, a; 170 171 DBG("%s\n", __FUNCTION__); 172 173 UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); 174 UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); 175 UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); 176 UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); 177 178 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 179 i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 180 (a << 24) | (r << 16) | (g << 8) | b; 181} 182 183 184#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT) 185#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT) 186#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT) 187#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT) 188 189 190 191static GLuint 192translate_blend_equation(GLenum mode) 193{ 194 switch (mode) { 195 case GL_FUNC_ADD: 196 return BLENDFUNC_ADD; 197 case GL_MIN: 198 return BLENDFUNC_MIN; 199 case GL_MAX: 200 return BLENDFUNC_MAX; 201 case GL_FUNC_SUBTRACT: 202 return BLENDFUNC_SUBTRACT; 203 case GL_FUNC_REVERSE_SUBTRACT: 204 return BLENDFUNC_REVERSE_SUBTRACT; 205 default: 206 return 0; 207 } 208} 209 210static void 211i915UpdateBlendState(GLcontext * ctx) 212{ 213 struct i915_context *i915 = I915_CONTEXT(ctx); 214 GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] & 215 ~(IAB_SRC_FACTOR_MASK | 216 IAB_DST_FACTOR_MASK | 217 (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); 218 219 GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & 220 ~(S6_CBUF_SRC_BLEND_FACT_MASK | 221 S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); 222 223 GLuint eqRGB = ctx->Color.BlendEquationRGB; 224 GLuint eqA = ctx->Color.BlendEquationA; 225 GLuint srcRGB = ctx->Color.BlendSrcRGB; 226 GLuint dstRGB = ctx->Color.BlendDstRGB; 227 GLuint srcA = ctx->Color.BlendSrcA; 228 GLuint dstA = ctx->Color.BlendDstA; 229 230 if (eqRGB == GL_MIN || eqRGB == GL_MAX) { 231 srcRGB = dstRGB = GL_ONE; 232 } 233 234 if (eqA == GL_MIN || eqA == GL_MAX) { 235 srcA = dstA = GL_ONE; 236 } 237 238 lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); 239 lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); 240 lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; 241 242 iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); 243 iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); 244 iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; 245 246 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) 247 iab |= IAB_ENABLE; 248 249 if (iab != i915->state.Ctx[I915_CTXREG_IAB] || 250 lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { 251 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 252 i915->state.Ctx[I915_CTXREG_IAB] = iab; 253 i915->state.Ctx[I915_CTXREG_LIS6] = lis6; 254 } 255 256 /* This will catch a logicop blend equation */ 257 i915EvalLogicOpBlendState(ctx); 258} 259 260 261static void 262i915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB, 263 GLenum dstRGB, GLenum srcA, GLenum dstA) 264{ 265 i915UpdateBlendState(ctx); 266} 267 268 269static void 270i915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA) 271{ 272 i915UpdateBlendState(ctx); 273} 274 275 276static void 277i915DepthFunc(GLcontext * ctx, GLenum func) 278{ 279 struct i915_context *i915 = I915_CONTEXT(ctx); 280 int test = intel_translate_compare_func(func); 281 282 DBG("%s\n", __FUNCTION__); 283 284 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 285 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; 286 i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; 287} 288 289static void 290i915DepthMask(GLcontext * ctx, GLboolean flag) 291{ 292 struct i915_context *i915 = I915_CONTEXT(ctx); 293 294 DBG("%s flag (%d)\n", __FUNCTION__, flag); 295 296 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 297 298 if (flag && ctx->Depth.Test) 299 i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; 300 else 301 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; 302} 303 304/* ============================================================= 305 * Polygon stipple 306 * 307 * The i915 supports a 4x4 stipple natively, GL wants 32x32. 308 * Fortunately stipple is usually a repeating pattern. 309 */ 310static void 311i915PolygonStipple(GLcontext * ctx, const GLubyte * mask) 312{ 313 struct i915_context *i915 = I915_CONTEXT(ctx); 314 const GLubyte *m = mask; 315 GLubyte p[4]; 316 int i, j, k; 317 int active = (ctx->Polygon.StippleFlag && 318 i915->intel.reduced_primitive == GL_TRIANGLES); 319 GLuint newMask; 320 321 if (active) { 322 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 323 i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; 324 } 325 326 p[0] = mask[12] & 0xf; 327 p[0] |= p[0] << 4; 328 p[1] = mask[8] & 0xf; 329 p[1] |= p[1] << 4; 330 p[2] = mask[4] & 0xf; 331 p[2] |= p[2] << 4; 332 p[3] = mask[0] & 0xf; 333 p[3] |= p[3] << 4; 334 335 for (k = 0; k < 8; k++) 336 for (j = 3; j >= 0; j--) 337 for (i = 0; i < 4; i++, m++) 338 if (*m != p[j]) { 339 i915->intel.hw_stipple = 0; 340 return; 341 } 342 343 newMask = (((p[0] & 0xf) << 0) | 344 ((p[1] & 0xf) << 4) | 345 ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); 346 347 348 if (newMask == 0xffff || newMask == 0x0) { 349 /* this is needed to make conform pass */ 350 i915->intel.hw_stipple = 0; 351 return; 352 } 353 354 i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; 355 i915->state.Stipple[I915_STPREG_ST1] |= newMask; 356 i915->intel.hw_stipple = 1; 357 358 if (active) 359 i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; 360} 361 362 363/* ============================================================= 364 * Hardware clipping 365 */ 366static void 367i915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h) 368{ 369 struct i915_context *i915 = I915_CONTEXT(ctx); 370 int x1, y1, x2, y2; 371 372 if (!ctx->DrawBuffer) 373 return; 374 375 DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); 376 377 if (ctx->DrawBuffer->Name == 0) { 378 x1 = x; 379 y1 = ctx->DrawBuffer->Height - (y + h); 380 x2 = x + w - 1; 381 y2 = y1 + h - 1; 382 DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); 383 } 384 else { 385 /* FBO - not inverted 386 */ 387 x1 = x; 388 y1 = y; 389 x2 = x + w - 1; 390 y2 = y + h - 1; 391 DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); 392 } 393 394 x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); 395 y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); 396 x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); 397 y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); 398 399 DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); 400 401 I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); 402 i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); 403 i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); 404} 405 406static void 407i915LogicOp(GLcontext * ctx, GLenum opcode) 408{ 409 struct i915_context *i915 = I915_CONTEXT(ctx); 410 int tmp = intel_translate_logic_op(opcode); 411 412 DBG("%s\n", __FUNCTION__); 413 414 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 415 i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; 416 i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); 417} 418 419 420 421static void 422i915CullFaceFrontFace(GLcontext * ctx, GLenum unused) 423{ 424 struct i915_context *i915 = I915_CONTEXT(ctx); 425 GLuint mode; 426 427 DBG("%s %d\n", __FUNCTION__, 428 ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); 429 430 if (!ctx->Polygon.CullFlag) { 431 mode = S4_CULLMODE_NONE; 432 } 433 else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { 434 mode = S4_CULLMODE_CW; 435 436 if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) 437 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 438 if (ctx->Polygon.CullFaceMode == GL_FRONT) 439 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 440 if (ctx->Polygon.FrontFace != GL_CCW) 441 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 442 } 443 else { 444 mode = S4_CULLMODE_BOTH; 445 } 446 447 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 448 i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK; 449 i915->state.Ctx[I915_CTXREG_LIS4] |= mode; 450} 451 452static void 453i915LineWidth(GLcontext * ctx, GLfloat widthf) 454{ 455 struct i915_context *i915 = I915_CONTEXT(ctx); 456 int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; 457 int width; 458 459 DBG("%s\n", __FUNCTION__); 460 461 width = (int) (widthf * 2); 462 CLAMP_SELF(width, 1, 0xf); 463 lis4 |= width << S4_LINE_WIDTH_SHIFT; 464 465 if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { 466 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 467 i915->state.Ctx[I915_CTXREG_LIS4] = lis4; 468 } 469} 470 471static void 472i915PointSize(GLcontext * ctx, GLfloat size) 473{ 474 struct i915_context *i915 = I915_CONTEXT(ctx); 475 int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; 476 GLint point_size = (int) size; 477 478 DBG("%s\n", __FUNCTION__); 479 480 CLAMP_SELF(point_size, 1, 255); 481 lis4 |= point_size << S4_POINT_WIDTH_SHIFT; 482 483 if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { 484 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 485 i915->state.Ctx[I915_CTXREG_LIS4] = lis4; 486 } 487} 488 489 490/* ============================================================= 491 * Color masks 492 */ 493 494static void 495i915ColorMask(GLcontext * ctx, 496 GLboolean r, GLboolean g, GLboolean b, GLboolean a) 497{ 498 struct i915_context *i915 = I915_CONTEXT(ctx); 499 GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; 500 501 DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, 502 a); 503 504 if (!r) 505 tmp |= S5_WRITEDISABLE_RED; 506 if (!g) 507 tmp |= S5_WRITEDISABLE_GREEN; 508 if (!b) 509 tmp |= S5_WRITEDISABLE_BLUE; 510 if (!a) 511 tmp |= S5_WRITEDISABLE_ALPHA; 512 513 if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { 514 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 515 i915->state.Ctx[I915_CTXREG_LIS5] = tmp; 516 } 517} 518 519static void 520update_specular(GLcontext * ctx) 521{ 522 /* A hack to trigger the rebuild of the fragment program. 523 */ 524 intel_context(ctx)->NewGLState |= _NEW_TEXTURE; 525} 526 527static void 528i915LightModelfv(GLcontext * ctx, GLenum pname, const GLfloat * param) 529{ 530 DBG("%s\n", __FUNCTION__); 531 532 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { 533 update_specular(ctx); 534 } 535} 536 537static void 538i915ShadeModel(GLcontext * ctx, GLenum mode) 539{ 540 struct i915_context *i915 = I915_CONTEXT(ctx); 541 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 542 543 if (mode == GL_SMOOTH) { 544 i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | 545 S4_FLATSHADE_COLOR | 546 S4_FLATSHADE_SPECULAR); 547 } 548 else { 549 i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | 550 S4_FLATSHADE_COLOR | 551 S4_FLATSHADE_SPECULAR); 552 } 553} 554 555/* ============================================================= 556 * Fog 557 */ 558void 559i915_update_fog(GLcontext * ctx) 560{ 561 struct i915_context *i915 = I915_CONTEXT(ctx); 562 GLenum mode; 563 GLboolean enabled; 564 GLboolean try_pixel_fog; 565 566 if (ctx->FragmentProgram._Active) { 567 /* Pull in static fog state from program */ 568 mode = ctx->FragmentProgram._Current->FogOption; 569 enabled = (mode != GL_NONE); 570 try_pixel_fog = 0; 571 } 572 else { 573 enabled = ctx->Fog.Enabled; 574 mode = ctx->Fog.Mode; 575#if 0 576 /* XXX - DISABLED -- Need ortho fallback */ 577 try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT 578 && ctx->Hint.Fog == GL_NICEST); 579#else 580 try_pixel_fog = 0; 581#endif 582 } 583 584 if (!enabled) { 585 i915->vertex_fog = I915_FOG_NONE; 586 } 587 else if (try_pixel_fog) { 588 I915_STATECHANGE(i915, I915_UPLOAD_FOG); 589 i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; 590 i915->vertex_fog = I915_FOG_PIXEL; 591 592 switch (mode) { 593 case GL_LINEAR: 594 if (ctx->Fog.End <= ctx->Fog.Start) { 595 /* XXX - this won't work with fragment programs. Need to 596 * either fallback or append fog instructions to end of 597 * program in the case of linear fog. 598 */ 599 printf("vertex fog!\n"); 600 i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; 601 i915->vertex_fog = I915_FOG_VERTEX; 602 } 603 else { 604 GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); 605 GLfloat c1 = ctx->Fog.End * c2; 606 607 i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; 608 i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; 609 i915->state.Fog[I915_FOGREG_MODE1] |= 610 ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; 611 612 if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { 613 i915->state.Fog[I915_FOGREG_MODE2] 614 = (GLuint) (c2 * FMC2_C2_ONE); 615 } 616 else { 617 fi_type fi; 618 fi.f = c2; 619 i915->state.Fog[I915_FOGREG_MODE2] = fi.i; 620 } 621 } 622 break; 623 case GL_EXP: 624 i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; 625 break; 626 case GL_EXP2: 627 i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; 628 break; 629 default: 630 break; 631 } 632 } 633 else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ 634 I915_STATECHANGE(i915, I915_UPLOAD_FOG); 635 i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; 636 i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; 637 i915->vertex_fog = I915_FOG_VERTEX; 638 } 639 640 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 641 I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); 642 if (enabled) 643 i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; 644 else 645 i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; 646 647 /* Always enable pixel fog. Vertex fog using fog coord will conflict 648 * with fog code appended onto fragment program. 649 */ 650 _tnl_allow_vertex_fog( ctx, 0 ); 651 _tnl_allow_pixel_fog( ctx, 1 ); 652} 653 654static void 655i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) 656{ 657 struct i915_context *i915 = I915_CONTEXT(ctx); 658 659 switch (pname) { 660 case GL_FOG_COORDINATE_SOURCE_EXT: 661 case GL_FOG_MODE: 662 case GL_FOG_START: 663 case GL_FOG_END: 664 break; 665 666 case GL_FOG_DENSITY: 667 I915_STATECHANGE(i915, I915_UPLOAD_FOG); 668 669 if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { 670 i915->state.Fog[I915_FOGREG_MODE3] = 671 (GLuint) (ctx->Fog.Density * FMC3_D_ONE); 672 } 673 else { 674 fi_type fi; 675 fi.f = ctx->Fog.Density; 676 i915->state.Fog[I915_FOGREG_MODE3] = fi.i; 677 } 678 break; 679 680 case GL_FOG_COLOR: 681 I915_STATECHANGE(i915, I915_UPLOAD_FOG); 682 i915->state.Fog[I915_FOGREG_COLOR] = 683 (_3DSTATE_FOG_COLOR_CMD | 684 ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | 685 ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | 686 ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); 687 break; 688 689 default: 690 break; 691 } 692} 693 694static void 695i915Hint(GLcontext * ctx, GLenum target, GLenum state) 696{ 697 switch (target) { 698 case GL_FOG_HINT: 699 break; 700 default: 701 break; 702 } 703} 704 705/* ============================================================= 706 */ 707 708static void 709i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) 710{ 711 struct i915_context *i915 = I915_CONTEXT(ctx); 712 713 switch (cap) { 714 case GL_TEXTURE_2D: 715 break; 716 717 case GL_LIGHTING: 718 case GL_COLOR_SUM: 719 update_specular(ctx); 720 break; 721 722 case GL_ALPHA_TEST: 723 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 724 if (state) 725 i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; 726 else 727 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; 728 break; 729 730 case GL_BLEND: 731 i915EvalLogicOpBlendState(ctx); 732 break; 733 734 case GL_COLOR_LOGIC_OP: 735 i915EvalLogicOpBlendState(ctx); 736 737 /* Logicop doesn't seem to work at 16bpp: 738 */ 739 if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ 740 FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); 741 break; 742 743 case GL_FRAGMENT_PROGRAM_ARB: 744 break; 745 746 case GL_DITHER: 747 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 748 if (state) 749 i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; 750 else 751 i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; 752 break; 753 754 case GL_DEPTH_TEST: 755 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 756 if (state) 757 i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; 758 else 759 i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; 760 761 i915DepthMask(ctx, ctx->Depth.Mask); 762 break; 763 764 case GL_SCISSOR_TEST: 765 I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); 766 if (state) 767 i915->state.Buffer[I915_DESTREG_SENABLE] = 768 (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); 769 else 770 i915->state.Buffer[I915_DESTREG_SENABLE] = 771 (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 772 break; 773 774 case GL_LINE_SMOOTH: 775 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 776 if (state) 777 i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; 778 else 779 i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; 780 break; 781 782 case GL_FOG: 783 break; 784 785 case GL_CULL_FACE: 786 i915CullFaceFrontFace(ctx, 0); 787 break; 788 789 case GL_STENCIL_TEST: 790 { 791 GLboolean hw_stencil = GL_FALSE; 792 if (ctx->DrawBuffer) { 793 struct intel_renderbuffer *irbStencil 794 = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); 795 hw_stencil = (irbStencil && irbStencil->region); 796 } 797 if (hw_stencil) { 798 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 799 if (state) 800 i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | 801 S5_STENCIL_WRITE_ENABLE); 802 else 803 i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | 804 S5_STENCIL_WRITE_ENABLE); 805 } 806 else { 807 FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); 808 } 809 } 810 break; 811 812 case GL_POLYGON_STIPPLE: 813 /* The stipple command worked on my 855GM box, but not my 845G. 814 * I'll do more testing later to find out exactly which hardware 815 * supports it. Disabled for now. 816 */ 817 if (i915->intel.hw_stipple && 818 i915->intel.reduced_primitive == GL_TRIANGLES) { 819 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 820 if (state) 821 i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; 822 else 823 i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; 824 } 825 break; 826 827 case GL_POLYGON_SMOOTH: 828 break; 829 830 case GL_POINT_SMOOTH: 831 break; 832 833 default: 834 ; 835 } 836} 837 838 839static void 840i915_init_packets(struct i915_context *i915) 841{ 842 intelScreenPrivate *screen = i915->intel.intelScreen; 843 844 /* Zero all state */ 845 memset(&i915->state, 0, sizeof(i915->state)); 846 847 848 { 849 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 850 /* Probably don't want to upload all this stuff every time one 851 * piece changes. 852 */ 853 i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 854 I1_LOAD_S(2) | 855 I1_LOAD_S(4) | 856 I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); 857 i915->state.Ctx[I915_CTXREG_LIS2] = 0; 858 i915->state.Ctx[I915_CTXREG_LIS4] = 0; 859 i915->state.Ctx[I915_CTXREG_LIS5] = 0; 860 861 if (screen->cpp == 2) /* XXX FBO fix */ 862 i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; 863 864 865 i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | 866 (2 << S6_TRISTRIP_PV_SHIFT)); 867 868 i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | 869 ENABLE_LOGIC_OP_FUNC | 870 LOGIC_OP_FUNC(LOGICOP_COPY) | 871 ENABLE_STENCIL_TEST_MASK | 872 STENCIL_TEST_MASK(0xff) | 873 ENABLE_STENCIL_WRITE_MASK | 874 STENCIL_WRITE_MASK(0xff)); 875 876 i915->state.Ctx[I915_CTXREG_IAB] = 877 (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 878 IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); 879 880 i915->state.Ctx[I915_CTXREG_BLENDCOLOR0] = 881 _3DSTATE_CONST_BLEND_COLOR_CMD; 882 i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0; 883 884 } 885 886 { 887 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 888 i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; 889 } 890 891 892 { 893 I915_STATECHANGE(i915, I915_UPLOAD_FOG); 894 i915->state.Fog[I915_FOGREG_MODE0] = _3DSTATE_FOG_MODE_CMD; 895 i915->state.Fog[I915_FOGREG_MODE1] = (FMC1_FOGFUNC_MODIFY_ENABLE | 896 FMC1_FOGFUNC_VERTEX | 897 FMC1_FOGINDEX_MODIFY_ENABLE | 898 FMC1_FOGINDEX_W | 899 FMC1_C1_C2_MODIFY_ENABLE | 900 FMC1_DENSITY_MODIFY_ENABLE); 901 i915->state.Fog[I915_FOGREG_COLOR] = _3DSTATE_FOG_COLOR_CMD; 902 } 903 904 905 { 906 I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); 907 /* color buffer offset/stride */ 908 i915->state.Buffer[I915_DESTREG_CBUFADDR0] = _3DSTATE_BUF_INFO_CMD; 909 /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ 910 i915->state.Buffer[I915_DESTREG_CBUFADDR1] = (BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(screen->front.pitch) | /* pitch in bytes */ 911 BUF_3D_USE_FENCE); 912 913 i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD; 914 /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ 915 i915->state.Buffer[I915_DESTREG_DBUFADDR1] = (BUF_3D_ID_DEPTH | BUF_3D_PITCH(screen->depth.pitch) | /* pitch in bytes */ 916 BUF_3D_USE_FENCE); 917 918 i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; 919 920 /* XXX FBO: remove this? Also get set in i915_set_draw_region() */ 921#if 0 /* seems we don't need this */ 922 switch (screen->fbFormat) { 923 case DV_PF_565: 924 i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ 925 DSTORG_VERT_BIAS(0x8) | /* .5 */ 926 LOD_PRECLAMP_OGL | 927 TEX_DEFAULT_COLOR_OGL | 928 DITHER_FULL_ALWAYS | 929 screen->fbFormat | 930 DEPTH_FRMT_16_FIXED); 931 break; 932 case DV_PF_8888: 933 i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */ 934 DSTORG_VERT_BIAS(0x8) | /* .5 */ 935 LOD_PRECLAMP_OGL | 936 TEX_DEFAULT_COLOR_OGL | 937 screen->fbFormat | 938 DEPTH_FRMT_24_FIXED_8_OTHER); 939 break; 940 } 941#endif 942 943 944 /* scissor */ 945 i915->state.Buffer[I915_DESTREG_SENABLE] = 946 (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 947 i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; 948 i915->state.Buffer[I915_DESTREG_SR1] = 0; 949 i915->state.Buffer[I915_DESTREG_SR2] = 0; 950 } 951 952 953#if 0 954 { 955 I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); 956 i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; 957 i915->state.Default[I915_DEFREG_C1] = 0; 958 i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; 959 i915->state.Default[I915_DEFREG_S1] = 0; 960 i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; 961 i915->state.Default[I915_DEFREG_Z1] = 0; 962 } 963#endif 964 965 966 /* These will be emitted every at the head of every buffer, unless 967 * we get hardware contexts working. 968 */ 969 i915->state.active = (I915_UPLOAD_PROGRAM | 970 I915_UPLOAD_STIPPLE | 971 I915_UPLOAD_CTX | 972 I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT); 973} 974 975void 976i915InitStateFunctions(struct dd_function_table *functions) 977{ 978 functions->AlphaFunc = i915AlphaFunc; 979 functions->BlendColor = i915BlendColor; 980 functions->BlendEquationSeparate = i915BlendEquationSeparate; 981 functions->BlendFuncSeparate = i915BlendFuncSeparate; 982 functions->ColorMask = i915ColorMask; 983 functions->CullFace = i915CullFaceFrontFace; 984 functions->DepthFunc = i915DepthFunc; 985 functions->DepthMask = i915DepthMask; 986 functions->Enable = i915Enable; 987 functions->Fogfv = i915Fogfv; 988 functions->FrontFace = i915CullFaceFrontFace; 989 functions->Hint = i915Hint; 990 functions->LightModelfv = i915LightModelfv; 991 functions->LineWidth = i915LineWidth; 992 functions->LogicOpcode = i915LogicOp; 993 functions->PointSize = i915PointSize; 994 functions->PolygonStipple = i915PolygonStipple; 995 functions->Scissor = i915Scissor; 996 functions->ShadeModel = i915ShadeModel; 997 functions->StencilFuncSeparate = i915StencilFuncSeparate; 998 functions->StencilMaskSeparate = i915StencilMaskSeparate; 999 functions->StencilOpSeparate = i915StencilOpSeparate; 1000} 1001 1002 1003void 1004i915InitState(struct i915_context *i915) 1005{ 1006 GLcontext *ctx = &i915->intel.ctx; 1007 1008 i915_init_packets(i915); 1009 1010 _mesa_init_driver_state(ctx); 1011 1012 memcpy(&i915->initial, &i915->state, sizeof(i915->state)); 1013 i915->current = &i915->state; 1014} 1015