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 #include "tnl/tnl.h" 37 #include "tnl/t_context.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 #include "intel_buffers.h" 45 46 #include "i915_context.h" 47 #include "i915_reg.h" 48 49 #define FILE_DEBUG_FLAG DEBUG_STATE 50 51 void 52 i915_update_stencil(struct gl_context * ctx) 53 { 54 struct i915_context *i915 = I915_CONTEXT(ctx); 55 GLuint front_ref, front_writemask, front_mask; 56 GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass; 57 GLuint back_ref, back_writemask, back_mask; 58 GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass; 59 GLuint dirty = 0; 60 61 /* The 915 considers CW to be "front" for two-sided stencil, so choose 62 * appropriately. 63 */ 64 /* _NEW_POLYGON | _NEW_STENCIL */ 65 if (ctx->Polygon.FrontFace == GL_CW) { 66 front_ref = ctx->Stencil.Ref[0]; 67 front_mask = ctx->Stencil.ValueMask[0]; 68 front_writemask = ctx->Stencil.WriteMask[0]; 69 front_func = ctx->Stencil.Function[0]; 70 front_fail = ctx->Stencil.FailFunc[0]; 71 front_pass_z_fail = ctx->Stencil.ZFailFunc[0]; 72 front_pass_z_pass = ctx->Stencil.ZPassFunc[0]; 73 back_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; 74 back_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; 75 back_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; 76 back_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; 77 back_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; 78 back_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; 79 back_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; 80 } else { 81 front_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; 82 front_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; 83 front_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; 84 front_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; 85 front_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; 86 front_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; 87 front_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; 88 back_ref = ctx->Stencil.Ref[0]; 89 back_mask = ctx->Stencil.ValueMask[0]; 90 back_writemask = ctx->Stencil.WriteMask[0]; 91 back_func = ctx->Stencil.Function[0]; 92 back_fail = ctx->Stencil.FailFunc[0]; 93 back_pass_z_fail = ctx->Stencil.ZFailFunc[0]; 94 back_pass_z_pass = ctx->Stencil.ZPassFunc[0]; 95 } 96 #define set_ctx_bits(reg, mask, set) do{ \ 97 GLuint dw = i915->state.Ctx[reg]; \ 98 dw &= ~(mask); \ 99 dw |= (set); \ 100 dirty |= dw != i915->state.Ctx[reg]; \ 101 i915->state.Ctx[reg] = dw; \ 102 } while(0) 103 104 /* Set front state. */ 105 set_ctx_bits(I915_CTXREG_STATE4, 106 MODE4_ENABLE_STENCIL_TEST_MASK | 107 MODE4_ENABLE_STENCIL_WRITE_MASK, 108 ENABLE_STENCIL_TEST_MASK | 109 ENABLE_STENCIL_WRITE_MASK | 110 STENCIL_TEST_MASK(front_mask) | 111 STENCIL_WRITE_MASK(front_writemask)); 112 113 set_ctx_bits(I915_CTXREG_LIS5, 114 S5_STENCIL_REF_MASK | 115 S5_STENCIL_TEST_FUNC_MASK | 116 S5_STENCIL_FAIL_MASK | 117 S5_STENCIL_PASS_Z_FAIL_MASK | 118 S5_STENCIL_PASS_Z_PASS_MASK, 119 (front_ref << S5_STENCIL_REF_SHIFT) | 120 (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) | 121 (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) | 122 (intel_translate_stencil_op(front_pass_z_fail) << 123 S5_STENCIL_PASS_Z_FAIL_SHIFT) | 124 (intel_translate_stencil_op(front_pass_z_pass) << 125 S5_STENCIL_PASS_Z_PASS_SHIFT)); 126 127 /* Set back state if different from front. */ 128 if (ctx->Stencil._TestTwoSide) { 129 set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, 130 BFO_STENCIL_REF_MASK | 131 BFO_STENCIL_TEST_MASK | 132 BFO_STENCIL_FAIL_MASK | 133 BFO_STENCIL_PASS_Z_FAIL_MASK | 134 BFO_STENCIL_PASS_Z_PASS_MASK, 135 BFO_STENCIL_TWO_SIDE | 136 (back_ref << BFO_STENCIL_REF_SHIFT) | 137 (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) | 138 (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) | 139 (intel_translate_stencil_op(back_pass_z_fail) << 140 BFO_STENCIL_PASS_Z_FAIL_SHIFT) | 141 (intel_translate_stencil_op(back_pass_z_pass) << 142 BFO_STENCIL_PASS_Z_PASS_SHIFT)); 143 144 set_ctx_bits(I915_CTXREG_BF_STENCIL_MASKS, 145 BFM_STENCIL_TEST_MASK_MASK | 146 BFM_STENCIL_WRITE_MASK_MASK, 147 BFM_STENCIL_TEST_MASK(back_mask) | 148 BFM_STENCIL_WRITE_MASK(back_writemask)); 149 } else { 150 set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, 151 BFO_STENCIL_TWO_SIDE, 0); 152 } 153 154 #undef set_ctx_bits 155 156 if (dirty) 157 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 158 } 159 160 static void 161 i915StencilFuncSeparate(struct gl_context * ctx, GLenum face, GLenum func, GLint ref, 162 GLuint mask) 163 { 164 } 165 166 static void 167 i915StencilMaskSeparate(struct gl_context * ctx, GLenum face, GLuint mask) 168 { 169 } 170 171 static void 172 i915StencilOpSeparate(struct gl_context * ctx, GLenum face, GLenum fail, GLenum zfail, 173 GLenum zpass) 174 { 175 } 176 177 static void 178 i915AlphaFunc(struct gl_context * ctx, GLenum func, GLfloat ref) 179 { 180 struct i915_context *i915 = I915_CONTEXT(ctx); 181 int test = intel_translate_compare_func(func); 182 GLubyte refByte; 183 GLuint dw; 184 185 UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); 186 187 dw = i915->state.Ctx[I915_CTXREG_LIS6]; 188 dw &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); 189 dw |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | 190 (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); 191 if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { 192 i915->state.Ctx[I915_CTXREG_LIS6] = dw; 193 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 194 } 195 } 196 197 /* This function makes sure that the proper enables are 198 * set for LogicOp, Independant Alpha Blend, and Blending. 199 * It needs to be called from numerous places where we 200 * could change the LogicOp or Independant Alpha Blend without subsequent 201 * calls to glEnable. 202 */ 203 static void 204 i915EvalLogicOpBlendState(struct gl_context * ctx) 205 { 206 struct i915_context *i915 = I915_CONTEXT(ctx); 207 GLuint dw0, dw1; 208 209 dw0 = i915->state.Ctx[I915_CTXREG_LIS5]; 210 dw1 = i915->state.Ctx[I915_CTXREG_LIS6]; 211 212 if (ctx->Color.ColorLogicOpEnabled) { 213 dw0 |= S5_LOGICOP_ENABLE; 214 dw1 &= ~S6_CBUF_BLEND_ENABLE; 215 } 216 else { 217 dw0 &= ~S5_LOGICOP_ENABLE; 218 219 if (ctx->Color.BlendEnabled) { 220 dw1 |= S6_CBUF_BLEND_ENABLE; 221 } 222 else { 223 dw1 &= ~S6_CBUF_BLEND_ENABLE; 224 } 225 } 226 if (dw0 != i915->state.Ctx[I915_CTXREG_LIS5] || 227 dw1 != i915->state.Ctx[I915_CTXREG_LIS6]) { 228 i915->state.Ctx[I915_CTXREG_LIS5] = dw0; 229 i915->state.Ctx[I915_CTXREG_LIS6] = dw1; 230 231 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 232 } 233 } 234 235 static void 236 i915BlendColor(struct gl_context * ctx, const GLfloat color[4]) 237 { 238 struct i915_context *i915 = I915_CONTEXT(ctx); 239 GLubyte r, g, b, a; 240 GLuint dw; 241 242 DBG("%s\n", __FUNCTION__); 243 244 UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); 245 UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); 246 UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); 247 UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); 248 249 dw = (a << 24) | (r << 16) | (g << 8) | b; 250 if (dw != i915->state.Blend[I915_BLENDREG_BLENDCOLOR1]) { 251 i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = dw; 252 I915_STATECHANGE(i915, I915_UPLOAD_BLEND); 253 } 254 } 255 256 257 #define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT) 258 #define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT) 259 #define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT) 260 #define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT) 261 262 263 264 static GLuint 265 translate_blend_equation(GLenum mode) 266 { 267 switch (mode) { 268 case GL_FUNC_ADD: 269 return BLENDFUNC_ADD; 270 case GL_MIN: 271 return BLENDFUNC_MIN; 272 case GL_MAX: 273 return BLENDFUNC_MAX; 274 case GL_FUNC_SUBTRACT: 275 return BLENDFUNC_SUBTRACT; 276 case GL_FUNC_REVERSE_SUBTRACT: 277 return BLENDFUNC_REVERSE_SUBTRACT; 278 default: 279 return 0; 280 } 281 } 282 283 static void 284 i915UpdateBlendState(struct gl_context * ctx) 285 { 286 struct i915_context *i915 = I915_CONTEXT(ctx); 287 GLuint iab = (i915->state.Blend[I915_BLENDREG_IAB] & 288 ~(IAB_SRC_FACTOR_MASK | 289 IAB_DST_FACTOR_MASK | 290 (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); 291 292 GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & 293 ~(S6_CBUF_SRC_BLEND_FACT_MASK | 294 S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); 295 296 GLuint eqRGB = ctx->Color.Blend[0].EquationRGB; 297 GLuint eqA = ctx->Color.Blend[0].EquationA; 298 GLuint srcRGB = ctx->Color.Blend[0].SrcRGB; 299 GLuint dstRGB = ctx->Color.Blend[0].DstRGB; 300 GLuint srcA = ctx->Color.Blend[0].SrcA; 301 GLuint dstA = ctx->Color.Blend[0].DstA; 302 303 if (eqRGB == GL_MIN || eqRGB == GL_MAX) { 304 srcRGB = dstRGB = GL_ONE; 305 } 306 307 if (eqA == GL_MIN || eqA == GL_MAX) { 308 srcA = dstA = GL_ONE; 309 } 310 311 lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); 312 lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); 313 lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; 314 315 iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); 316 iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); 317 iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; 318 319 if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) 320 iab |= IAB_ENABLE; 321 322 if (iab != i915->state.Blend[I915_BLENDREG_IAB]) { 323 i915->state.Blend[I915_BLENDREG_IAB] = iab; 324 I915_STATECHANGE(i915, I915_UPLOAD_BLEND); 325 } 326 if (lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { 327 i915->state.Ctx[I915_CTXREG_LIS6] = lis6; 328 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 329 } 330 331 /* This will catch a logicop blend equation */ 332 i915EvalLogicOpBlendState(ctx); 333 } 334 335 336 static void 337 i915BlendFuncSeparate(struct gl_context * ctx, GLenum srcRGB, 338 GLenum dstRGB, GLenum srcA, GLenum dstA) 339 { 340 i915UpdateBlendState(ctx); 341 } 342 343 344 static void 345 i915BlendEquationSeparate(struct gl_context * ctx, GLenum eqRGB, GLenum eqA) 346 { 347 i915UpdateBlendState(ctx); 348 } 349 350 351 static void 352 i915DepthFunc(struct gl_context * ctx, GLenum func) 353 { 354 struct i915_context *i915 = I915_CONTEXT(ctx); 355 int test = intel_translate_compare_func(func); 356 GLuint dw; 357 358 DBG("%s\n", __FUNCTION__); 359 360 dw = i915->state.Ctx[I915_CTXREG_LIS6]; 361 dw &= ~S6_DEPTH_TEST_FUNC_MASK; 362 dw |= test << S6_DEPTH_TEST_FUNC_SHIFT; 363 if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { 364 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 365 i915->state.Ctx[I915_CTXREG_LIS6] = dw; 366 } 367 } 368 369 static void 370 i915DepthMask(struct gl_context * ctx, GLboolean flag) 371 { 372 struct i915_context *i915 = I915_CONTEXT(ctx); 373 GLuint dw; 374 375 DBG("%s flag (%d)\n", __FUNCTION__, flag); 376 377 if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits) 378 flag = false; 379 380 dw = i915->state.Ctx[I915_CTXREG_LIS6]; 381 if (flag && ctx->Depth.Test) 382 dw |= S6_DEPTH_WRITE_ENABLE; 383 else 384 dw &= ~S6_DEPTH_WRITE_ENABLE; 385 if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { 386 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 387 i915->state.Ctx[I915_CTXREG_LIS6] = dw; 388 } 389 } 390 391 392 393 /** 394 * Update the viewport transformation matrix. Depends on: 395 * - viewport pos/size 396 * - depthrange 397 * - window pos/size or FBO size 398 */ 399 void 400 intelCalcViewport(struct gl_context * ctx) 401 { 402 struct intel_context *intel = intel_context(ctx); 403 404 if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { 405 _math_matrix_viewport(&intel->ViewportMatrix, 406 ctx->Viewport.X, 407 ctx->DrawBuffer->Height - ctx->Viewport.Y, 408 ctx->Viewport.Width, 409 -ctx->Viewport.Height, 410 ctx->Viewport.Near, 411 ctx->Viewport.Far, 412 1.0); 413 } else { 414 _math_matrix_viewport(&intel->ViewportMatrix, 415 ctx->Viewport.X, 416 ctx->Viewport.Y, 417 ctx->Viewport.Width, 418 ctx->Viewport.Height, 419 ctx->Viewport.Near, 420 ctx->Viewport.Far, 421 1.0); 422 } 423 } 424 425 426 /** Called from ctx->Driver.Viewport() */ 427 static void 428 i915Viewport(struct gl_context * ctx, 429 GLint x, GLint y, GLsizei width, GLsizei height) 430 { 431 intelCalcViewport(ctx); 432 } 433 434 435 /** Called from ctx->Driver.DepthRange() */ 436 static void 437 i915DepthRange(struct gl_context * ctx, GLclampd nearval, GLclampd farval) 438 { 439 intelCalcViewport(ctx); 440 } 441 442 443 /* ============================================================= 444 * Polygon stipple 445 * 446 * The i915 supports a 4x4 stipple natively, GL wants 32x32. 447 * Fortunately stipple is usually a repeating pattern. 448 */ 449 static void 450 i915PolygonStipple(struct gl_context * ctx, const GLubyte * mask) 451 { 452 struct i915_context *i915 = I915_CONTEXT(ctx); 453 const GLubyte *m; 454 GLubyte p[4]; 455 int i, j, k; 456 int active = (ctx->Polygon.StippleFlag && 457 i915->intel.reduced_primitive == GL_TRIANGLES); 458 GLuint newMask; 459 460 if (active) { 461 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 462 i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; 463 } 464 465 /* Use the already unpacked stipple data from the context rather than the 466 * uninterpreted mask passed in. 467 */ 468 mask = (const GLubyte *)ctx->PolygonStipple; 469 m = mask; 470 471 p[0] = mask[12] & 0xf; 472 p[0] |= p[0] << 4; 473 p[1] = mask[8] & 0xf; 474 p[1] |= p[1] << 4; 475 p[2] = mask[4] & 0xf; 476 p[2] |= p[2] << 4; 477 p[3] = mask[0] & 0xf; 478 p[3] |= p[3] << 4; 479 480 for (k = 0; k < 8; k++) 481 for (j = 3; j >= 0; j--) 482 for (i = 0; i < 4; i++, m++) 483 if (*m != p[j]) { 484 i915->intel.hw_stipple = 0; 485 return; 486 } 487 488 newMask = (((p[0] & 0xf) << 0) | 489 ((p[1] & 0xf) << 4) | 490 ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); 491 492 493 if (newMask == 0xffff || newMask == 0x0) { 494 /* this is needed to make conform pass */ 495 i915->intel.hw_stipple = 0; 496 return; 497 } 498 499 i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; 500 i915->state.Stipple[I915_STPREG_ST1] |= newMask; 501 i915->intel.hw_stipple = 1; 502 503 if (active) 504 i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; 505 } 506 507 508 /* ============================================================= 509 * Hardware clipping 510 */ 511 static void 512 i915Scissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h) 513 { 514 struct i915_context *i915 = I915_CONTEXT(ctx); 515 int x1, y1, x2, y2; 516 517 if (!ctx->DrawBuffer) 518 return; 519 520 DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); 521 522 if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { 523 x1 = x; 524 y1 = ctx->DrawBuffer->Height - (y + h); 525 x2 = x + w - 1; 526 y2 = y1 + h - 1; 527 DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); 528 } 529 else { 530 /* FBO - not inverted 531 */ 532 x1 = x; 533 y1 = y; 534 x2 = x + w - 1; 535 y2 = y + h - 1; 536 DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); 537 } 538 539 x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); 540 y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); 541 x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); 542 y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); 543 544 DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); 545 546 I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); 547 i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); 548 i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); 549 } 550 551 static void 552 i915LogicOp(struct gl_context * ctx, GLenum opcode) 553 { 554 struct i915_context *i915 = I915_CONTEXT(ctx); 555 int tmp = intel_translate_logic_op(opcode); 556 557 DBG("%s\n", __FUNCTION__); 558 559 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 560 i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; 561 i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); 562 } 563 564 565 566 static void 567 i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused) 568 { 569 struct i915_context *i915 = I915_CONTEXT(ctx); 570 GLuint mode, dw; 571 572 DBG("%s %d\n", __FUNCTION__, 573 ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); 574 575 if (!ctx->Polygon.CullFlag) { 576 mode = S4_CULLMODE_NONE; 577 } 578 else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { 579 mode = S4_CULLMODE_CW; 580 581 if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer)) 582 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 583 if (ctx->Polygon.CullFaceMode == GL_FRONT) 584 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 585 if (ctx->Polygon.FrontFace != GL_CCW) 586 mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); 587 } 588 else { 589 mode = S4_CULLMODE_BOTH; 590 } 591 592 dw = i915->state.Ctx[I915_CTXREG_LIS4]; 593 dw &= ~S4_CULLMODE_MASK; 594 dw |= mode; 595 if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { 596 i915->state.Ctx[I915_CTXREG_LIS4] = dw; 597 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 598 } 599 } 600 601 static void 602 i915LineWidth(struct gl_context * ctx, GLfloat widthf) 603 { 604 struct i915_context *i915 = I915_CONTEXT(ctx); 605 int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; 606 int width; 607 608 DBG("%s\n", __FUNCTION__); 609 610 width = (int) (widthf * 2); 611 width = CLAMP(width, 1, 0xf); 612 lis4 |= width << S4_LINE_WIDTH_SHIFT; 613 614 if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { 615 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 616 i915->state.Ctx[I915_CTXREG_LIS4] = lis4; 617 } 618 } 619 620 static void 621 i915PointSize(struct gl_context * ctx, GLfloat size) 622 { 623 struct i915_context *i915 = I915_CONTEXT(ctx); 624 int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; 625 GLint point_size = (int) round(size); 626 627 DBG("%s\n", __FUNCTION__); 628 629 point_size = CLAMP(point_size, 1, 255); 630 lis4 |= point_size << S4_POINT_WIDTH_SHIFT; 631 632 if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { 633 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 634 i915->state.Ctx[I915_CTXREG_LIS4] = lis4; 635 } 636 } 637 638 639 static void 640 i915PointParameterfv(struct gl_context * ctx, GLenum pname, const GLfloat *params) 641 { 642 struct i915_context *i915 = I915_CONTEXT(ctx); 643 644 switch (pname) { 645 case GL_POINT_SPRITE_COORD_ORIGIN: 646 /* This could be supported, but it would require modifying the fragment 647 * program to invert the y component of the texture coordinate by 648 * inserting a 'SUB tc.y, {1.0}.xxxx, tc' instruction. 649 */ 650 FALLBACK(&i915->intel, I915_FALLBACK_POINT_SPRITE_COORD_ORIGIN, 651 (params[0] != GL_UPPER_LEFT)); 652 break; 653 } 654 } 655 656 void 657 i915_update_sprite_point_enable(struct gl_context *ctx) 658 { 659 struct intel_context *intel = intel_context(ctx); 660 /* _NEW_PROGRAM */ 661 struct i915_fragment_program *p = 662 (struct i915_fragment_program *) ctx->FragmentProgram._Current; 663 const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead; 664 struct i915_context *i915 = i915_context(ctx); 665 GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; 666 int i; 667 GLuint coord_replace_bits = 0x0; 668 GLuint tex_coord_unit_bits = 0x0; 669 670 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { 671 /* _NEW_POINT */ 672 if (ctx->Point.CoordReplace[i] && ctx->Point.PointSprite) 673 coord_replace_bits |= (1 << i); 674 if (inputsRead & FRAG_BIT_TEX(i)) 675 tex_coord_unit_bits |= (1 << i); 676 } 677 678 /* 679 * Here we can't enable the SPRITE_POINT_ENABLE bit when the mis-match 680 * of tex_coord_unit_bits and coord_replace_bits, or this will make all 681 * the other non-point-sprite coords(like varying inputs, as we now use 682 * tex coord to implement varying inputs) be replaced to value (0, 0)-(1, 1). 683 * 684 * Thus, do fallback when needed. 685 */ 686 FALLBACK(intel, I915_FALLBACK_COORD_REPLACE, 687 coord_replace_bits && coord_replace_bits != tex_coord_unit_bits); 688 689 s4 &= ~S4_SPRITE_POINT_ENABLE; 690 s4 |= (coord_replace_bits && coord_replace_bits == tex_coord_unit_bits) ? 691 S4_SPRITE_POINT_ENABLE : 0; 692 if (s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { 693 i915->state.Ctx[I915_CTXREG_LIS4] = s4; 694 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 695 } 696 } 697 698 699 /* ============================================================= 700 * Color masks 701 */ 702 703 static void 704 i915ColorMask(struct gl_context * ctx, 705 GLboolean r, GLboolean g, GLboolean b, GLboolean a) 706 { 707 struct i915_context *i915 = I915_CONTEXT(ctx); 708 GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; 709 710 DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, 711 a); 712 713 if (!r) 714 tmp |= S5_WRITEDISABLE_RED; 715 if (!g) 716 tmp |= S5_WRITEDISABLE_GREEN; 717 if (!b) 718 tmp |= S5_WRITEDISABLE_BLUE; 719 if (!a) 720 tmp |= S5_WRITEDISABLE_ALPHA; 721 722 if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { 723 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 724 i915->state.Ctx[I915_CTXREG_LIS5] = tmp; 725 } 726 } 727 728 static void 729 update_specular(struct gl_context * ctx) 730 { 731 /* A hack to trigger the rebuild of the fragment program. 732 */ 733 intel_context(ctx)->NewGLState |= _NEW_TEXTURE; 734 } 735 736 static void 737 i915LightModelfv(struct gl_context * ctx, GLenum pname, const GLfloat * param) 738 { 739 DBG("%s\n", __FUNCTION__); 740 741 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { 742 update_specular(ctx); 743 } 744 } 745 746 static void 747 i915ShadeModel(struct gl_context * ctx, GLenum mode) 748 { 749 struct i915_context *i915 = I915_CONTEXT(ctx); 750 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 751 752 if (mode == GL_SMOOTH) { 753 i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | 754 S4_FLATSHADE_COLOR | 755 S4_FLATSHADE_SPECULAR); 756 } 757 else { 758 i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | 759 S4_FLATSHADE_COLOR | 760 S4_FLATSHADE_SPECULAR); 761 } 762 } 763 764 /* ============================================================= 765 * Fog 766 * 767 * This empty function remains because _mesa_init_driver_state calls 768 * dd_function_table::Fogfv unconditionally. We have to have some function 769 * there so that it doesn't try to call a NULL pointer. 770 */ 771 static void 772 i915Fogfv(struct gl_context * ctx, GLenum pname, const GLfloat * param) 773 { 774 (void) ctx; 775 (void) pname; 776 (void) param; 777 } 778 779 /* ============================================================= 780 */ 781 782 static void 783 i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) 784 { 785 struct i915_context *i915 = I915_CONTEXT(ctx); 786 GLuint dw; 787 788 switch (cap) { 789 case GL_TEXTURE_2D: 790 break; 791 792 case GL_LIGHTING: 793 case GL_COLOR_SUM: 794 update_specular(ctx); 795 break; 796 797 case GL_ALPHA_TEST: 798 dw = i915->state.Ctx[I915_CTXREG_LIS6]; 799 if (state) 800 dw |= S6_ALPHA_TEST_ENABLE; 801 else 802 dw &= ~S6_ALPHA_TEST_ENABLE; 803 if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { 804 i915->state.Ctx[I915_CTXREG_LIS6] = dw; 805 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 806 } 807 break; 808 809 case GL_BLEND: 810 i915EvalLogicOpBlendState(ctx); 811 break; 812 813 case GL_COLOR_LOGIC_OP: 814 i915EvalLogicOpBlendState(ctx); 815 816 /* Logicop doesn't seem to work at 16bpp: 817 */ 818 if (ctx->Visual.rgbBits == 16) 819 FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); 820 break; 821 822 case GL_FRAGMENT_PROGRAM_ARB: 823 break; 824 825 case GL_DITHER: 826 dw = i915->state.Ctx[I915_CTXREG_LIS5]; 827 if (state) 828 dw |= S5_COLOR_DITHER_ENABLE; 829 else 830 dw &= ~S5_COLOR_DITHER_ENABLE; 831 if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { 832 i915->state.Ctx[I915_CTXREG_LIS5] = dw; 833 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 834 } 835 break; 836 837 case GL_DEPTH_TEST: 838 dw = i915->state.Ctx[I915_CTXREG_LIS6]; 839 840 if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits) 841 state = false; 842 843 if (state) 844 dw |= S6_DEPTH_TEST_ENABLE; 845 else 846 dw &= ~S6_DEPTH_TEST_ENABLE; 847 if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { 848 i915->state.Ctx[I915_CTXREG_LIS6] = dw; 849 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 850 } 851 852 i915DepthMask(ctx, ctx->Depth.Mask); 853 break; 854 855 case GL_SCISSOR_TEST: 856 I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); 857 if (state) 858 i915->state.Buffer[I915_DESTREG_SENABLE] = 859 (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); 860 else 861 i915->state.Buffer[I915_DESTREG_SENABLE] = 862 (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 863 break; 864 865 case GL_LINE_SMOOTH: 866 dw = i915->state.Ctx[I915_CTXREG_LIS4]; 867 if (state) 868 dw |= S4_LINE_ANTIALIAS_ENABLE; 869 else 870 dw &= ~S4_LINE_ANTIALIAS_ENABLE; 871 if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { 872 i915->state.Ctx[I915_CTXREG_LIS4] = dw; 873 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 874 } 875 break; 876 877 case GL_CULL_FACE: 878 i915CullFaceFrontFace(ctx, 0); 879 break; 880 881 case GL_STENCIL_TEST: 882 if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.stencilBits) 883 state = false; 884 885 dw = i915->state.Ctx[I915_CTXREG_LIS5]; 886 if (state) 887 dw |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); 888 else 889 dw &= ~(S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); 890 if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { 891 i915->state.Ctx[I915_CTXREG_LIS5] = dw; 892 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 893 } 894 break; 895 896 case GL_POLYGON_STIPPLE: 897 /* The stipple command worked on my 855GM box, but not my 845G. 898 * I'll do more testing later to find out exactly which hardware 899 * supports it. Disabled for now. 900 */ 901 if (i915->intel.hw_stipple && 902 i915->intel.reduced_primitive == GL_TRIANGLES) { 903 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 904 if (state) 905 i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; 906 else 907 i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; 908 } 909 break; 910 911 case GL_POLYGON_SMOOTH: 912 break; 913 914 case GL_POINT_SPRITE: 915 /* Handle it at i915_update_sprite_point_enable () */ 916 break; 917 918 case GL_POINT_SMOOTH: 919 break; 920 921 default: 922 ; 923 } 924 } 925 926 927 static void 928 i915_init_packets(struct i915_context *i915) 929 { 930 /* Zero all state */ 931 memset(&i915->state, 0, sizeof(i915->state)); 932 933 934 { 935 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 936 I915_STATECHANGE(i915, I915_UPLOAD_BLEND); 937 /* Probably don't want to upload all this stuff every time one 938 * piece changes. 939 */ 940 i915->state.Ctx[I915_CTXREG_LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_1 | 941 I1_LOAD_S(2) | 942 I1_LOAD_S(4) | 943 I1_LOAD_S(5) | I1_LOAD_S(6) | (3)); 944 i915->state.Ctx[I915_CTXREG_LIS2] = 0; 945 i915->state.Ctx[I915_CTXREG_LIS4] = 0; 946 i915->state.Ctx[I915_CTXREG_LIS5] = 0; 947 948 if (i915->intel.ctx.Visual.rgbBits == 16) 949 i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; 950 951 952 i915->state.Ctx[I915_CTXREG_LIS6] = (S6_COLOR_WRITE_ENABLE | 953 (2 << S6_TRISTRIP_PV_SHIFT)); 954 955 i915->state.Ctx[I915_CTXREG_STATE4] = (_3DSTATE_MODES_4_CMD | 956 ENABLE_LOGIC_OP_FUNC | 957 LOGIC_OP_FUNC(LOGICOP_COPY) | 958 ENABLE_STENCIL_TEST_MASK | 959 STENCIL_TEST_MASK(0xff) | 960 ENABLE_STENCIL_WRITE_MASK | 961 STENCIL_WRITE_MASK(0xff)); 962 963 i915->state.Blend[I915_BLENDREG_IAB] = 964 (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | IAB_MODIFY_ENABLE | 965 IAB_MODIFY_FUNC | IAB_MODIFY_SRC_FACTOR | IAB_MODIFY_DST_FACTOR); 966 967 i915->state.Blend[I915_BLENDREG_BLENDCOLOR0] = 968 _3DSTATE_CONST_BLEND_COLOR_CMD; 969 i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = 0; 970 971 i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] = 972 _3DSTATE_BACKFACE_STENCIL_MASKS | 973 BFM_ENABLE_STENCIL_TEST_MASK | 974 BFM_ENABLE_STENCIL_WRITE_MASK | 975 (0xff << BFM_STENCIL_WRITE_MASK_SHIFT) | 976 (0xff << BFM_STENCIL_TEST_MASK_SHIFT); 977 i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] = 978 _3DSTATE_BACKFACE_STENCIL_OPS | 979 BFO_ENABLE_STENCIL_REF | 980 BFO_ENABLE_STENCIL_FUNCS | 981 BFO_ENABLE_STENCIL_TWO_SIDE; 982 } 983 984 { 985 I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); 986 i915->state.Stipple[I915_STPREG_ST0] = _3DSTATE_STIPPLE; 987 } 988 989 { 990 i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD; 991 992 /* scissor */ 993 i915->state.Buffer[I915_DESTREG_SENABLE] = 994 (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); 995 i915->state.Buffer[I915_DESTREG_SR0] = _3DSTATE_SCISSOR_RECT_0_CMD; 996 i915->state.Buffer[I915_DESTREG_SR1] = 0; 997 i915->state.Buffer[I915_DESTREG_SR2] = 0; 998 } 999 1000 i915->state.RasterRules[I915_RASTER_RULES] = _3DSTATE_RASTER_RULES_CMD | 1001 ENABLE_POINT_RASTER_RULE | 1002 OGL_POINT_RASTER_RULE | 1003 ENABLE_LINE_STRIP_PROVOKE_VRTX | 1004 ENABLE_TRI_FAN_PROVOKE_VRTX | 1005 LINE_STRIP_PROVOKE_VRTX(1) | 1006 TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D; 1007 1008 #if 0 1009 { 1010 I915_STATECHANGE(i915, I915_UPLOAD_DEFAULTS); 1011 i915->state.Default[I915_DEFREG_C0] = _3DSTATE_DEFAULT_DIFFUSE; 1012 i915->state.Default[I915_DEFREG_C1] = 0; 1013 i915->state.Default[I915_DEFREG_S0] = _3DSTATE_DEFAULT_SPECULAR; 1014 i915->state.Default[I915_DEFREG_S1] = 0; 1015 i915->state.Default[I915_DEFREG_Z0] = _3DSTATE_DEFAULT_Z; 1016 i915->state.Default[I915_DEFREG_Z1] = 0; 1017 } 1018 #endif 1019 1020 1021 /* These will be emitted every at the head of every buffer, unless 1022 * we get hardware contexts working. 1023 */ 1024 i915->state.active = (I915_UPLOAD_PROGRAM | 1025 I915_UPLOAD_STIPPLE | 1026 I915_UPLOAD_CTX | 1027 I915_UPLOAD_BLEND | 1028 I915_UPLOAD_BUFFERS | 1029 I915_UPLOAD_INVARIENT | 1030 I915_UPLOAD_RASTER_RULES); 1031 } 1032 1033 void 1034 i915_update_provoking_vertex(struct gl_context * ctx) 1035 { 1036 struct i915_context *i915 = I915_CONTEXT(ctx); 1037 1038 I915_STATECHANGE(i915, I915_UPLOAD_CTX); 1039 i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK); 1040 1041 I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES); 1042 i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK | 1043 TRI_FAN_PROVOKE_VRTX_MASK); 1044 1045 /* _NEW_LIGHT */ 1046 if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) { 1047 i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) | 1048 TRI_FAN_PROVOKE_VRTX(2)); 1049 i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT); 1050 } else { 1051 i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) | 1052 TRI_FAN_PROVOKE_VRTX(1)); 1053 i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT); 1054 } 1055 } 1056 1057 /* Fallback to swrast for select and feedback. 1058 */ 1059 static void 1060 i915RenderMode(struct gl_context *ctx, GLenum mode) 1061 { 1062 struct intel_context *intel = intel_context(ctx); 1063 FALLBACK(intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER)); 1064 } 1065 1066 void 1067 i915InitStateFunctions(struct dd_function_table *functions) 1068 { 1069 functions->AlphaFunc = i915AlphaFunc; 1070 functions->BlendColor = i915BlendColor; 1071 functions->BlendEquationSeparate = i915BlendEquationSeparate; 1072 functions->BlendFuncSeparate = i915BlendFuncSeparate; 1073 functions->ColorMask = i915ColorMask; 1074 functions->CullFace = i915CullFaceFrontFace; 1075 functions->DepthFunc = i915DepthFunc; 1076 functions->DepthMask = i915DepthMask; 1077 functions->Enable = i915Enable; 1078 functions->Fogfv = i915Fogfv; 1079 functions->FrontFace = i915CullFaceFrontFace; 1080 functions->LightModelfv = i915LightModelfv; 1081 functions->LineWidth = i915LineWidth; 1082 functions->LogicOpcode = i915LogicOp; 1083 functions->PointSize = i915PointSize; 1084 functions->PointParameterfv = i915PointParameterfv; 1085 functions->PolygonStipple = i915PolygonStipple; 1086 functions->RenderMode = i915RenderMode; 1087 functions->Scissor = i915Scissor; 1088 functions->ShadeModel = i915ShadeModel; 1089 functions->StencilFuncSeparate = i915StencilFuncSeparate; 1090 functions->StencilMaskSeparate = i915StencilMaskSeparate; 1091 functions->StencilOpSeparate = i915StencilOpSeparate; 1092 functions->DepthRange = i915DepthRange; 1093 functions->Viewport = i915Viewport; 1094 } 1095 1096 1097 void 1098 i915InitState(struct i915_context *i915) 1099 { 1100 struct gl_context *ctx = &i915->intel.ctx; 1101 1102 i915_init_packets(i915); 1103 1104 _mesa_init_driver_state(ctx); 1105 } 1106