static void i915LineWidth(struct gl_context * ctx, GLfloat widthf) { struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK; int width; DBG("%s\n", __FUNCTION__); width = (int) (widthf * 2); width = CLAMP(width, 1, 0xf); lis4 |= width << S4_LINE_WIDTH_SHIFT; if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS4] = lis4; } }
static void i915AlphaFunc(struct gl_context * ctx, GLenum func, GLfloat ref) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; GLuint dw; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); dw = i915->state.Ctx[I915_CTXREG_LIS6]; dw &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); dw |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } }
static void i915TexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { i915ContextPtr i915 = I915_CONTEXT( ctx ); GLuint unit = ctx->Texture.CurrentUnit; switch (pname) { case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */ case GL_TEXTURE_ENV_MODE: case GL_COMBINE_RGB: case GL_COMBINE_ALPHA: case GL_SOURCE0_RGB: case GL_SOURCE1_RGB: case GL_SOURCE2_RGB: case GL_SOURCE0_ALPHA: case GL_SOURCE1_ALPHA: case GL_SOURCE2_ALPHA: case GL_OPERAND0_RGB: case GL_OPERAND1_RGB: case GL_OPERAND2_RGB: case GL_OPERAND0_ALPHA: case GL_OPERAND1_ALPHA: case GL_OPERAND2_ALPHA: case GL_RGB_SCALE: case GL_ALPHA_SCALE: i915->tex_program.translated = 0; break; case GL_TEXTURE_LOD_BIAS: { int b = (int) ((*param) * 16.0); if (b > 255) b = 255; if (b < -256) b = -256; I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK; i915->state.Tex[unit][I915_TEXREG_SS2] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); break; } default: break; } }
static void i915BlendColor(struct gl_context * ctx, const GLfloat color[4]) { struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; GLuint dw; DBG("%s\n", __FUNCTION__); UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]); UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]); dw = (a << 24) | (r << 16) | (g << 8) | b; if (dw != i915->state.Blend[I915_BLENDREG_BLENDCOLOR1]) { i915->state.Blend[I915_BLENDREG_BLENDCOLOR1] = dw; I915_STATECHANGE(i915, I915_UPLOAD_BLEND); } }
static void i915BindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *texObj ) { i915TextureObjectPtr tex; if (!texObj->DriverData) i915AllocTexObj( texObj ); tex = (i915TextureObjectPtr)texObj->DriverData; if (tex->lastTarget != texObj->Target) { tex->intel.dirty = I915_UPLOAD_TEX_ALL; tex->lastTarget = texObj->Target; } /* Need this if image format changes between bound textures. * Could try and shortcircuit by checking for differences in * state between incoming and outgoing textures: */ I915_CONTEXT(ctx)->tex_program.translated = 0; }
static void i915DepthMask(struct gl_context * ctx, GLboolean flag) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint dw; DBG("%s flag (%d)\n", __FUNCTION__, flag); if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits) flag = false; dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (flag && ctx->Depth.Test) dw |= S6_DEPTH_WRITE_ENABLE; else dw &= ~S6_DEPTH_WRITE_ENABLE; if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] = dw; } }
static void i915Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) { struct i915_context *i915 = I915_CONTEXT(ctx); switch (pname) { case GL_FOG_COORDINATE_SOURCE_EXT: case GL_FOG_MODE: case GL_FOG_START: case GL_FOG_END: break; case GL_FOG_DENSITY: I915_STATECHANGE(i915, I915_UPLOAD_FOG); if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { i915->state.Fog[I915_FOGREG_MODE3] = (GLuint) (ctx->Fog.Density * FMC3_D_ONE); } else { fi_type fi; fi.f = ctx->Fog.Density; i915->state.Fog[I915_FOGREG_MODE3] = fi.i; } break; case GL_FOG_COLOR: I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_COLOR] = (_3DSTATE_FOG_COLOR_CMD | ((GLubyte) (ctx->Fog.Color[0] * 255.0F) << 16) | ((GLubyte) (ctx->Fog.Color[1] * 255.0F) << 8) | ((GLubyte) (ctx->Fog.Color[2] * 255.0F) << 0)); break; default: break; } }
/* This function makes sure that the proper enables are * set for LogicOp, Independant Alpha Blend, and Blending. * It needs to be called from numerous places where we * could change the LogicOp or Independant Alpha Blend without subsequent * calls to glEnable. */ static void i915EvalLogicOpBlendState(GLcontext * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (RGBA_LOGICOP_ENABLED(ctx)) { i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE; i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; } else { i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE; if (ctx->Color.BlendEnabled) { i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE; } else { i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE; } } }
static void i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) { if (target == GL_FRAGMENT_PROGRAM_ARB) { struct i915_context *i915 = I915_CONTEXT(ctx); struct i915_fragment_program *p = (struct i915_fragment_program *) prog; if (i915->current_program == p) return; if (i915->current_program) { i915->current_program->on_hardware = 0; i915->current_program->params_uptodate = 0; } i915->current_program = p; assert(p->on_hardware == 0); assert(p->params_uptodate == 0); } }
/* ============================================================= * Hardware clipping */ static void i915Scissor(struct gl_context * ctx, GLint x, GLint y, GLsizei w, GLsizei h) { struct i915_context *i915 = I915_CONTEXT(ctx); int x1, y1, x2, y2; if (!ctx->DrawBuffer) return; DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h); if (ctx->DrawBuffer->Name == 0) { x1 = x; y1 = ctx->DrawBuffer->Height - (y + h); x2 = x + w - 1; y2 = y1 + h - 1; DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2); } else { /* FBO - not inverted */ x1 = x; y1 = y; x2 = x + w - 1; y2 = y + h - 1; DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2); } x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1); y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1); x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1); y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1); DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2); I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff); i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff); }
void i915_update_provoking_vertex(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK); I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES); i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK | TRI_FAN_PROVOKE_VRTX_MASK); /* _NEW_LIGHT */ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) { i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) | TRI_FAN_PROVOKE_VRTX(2)); i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT); } else { i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) | TRI_FAN_PROVOKE_VRTX(1)); i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT); } }
static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) { i915ContextPtr i915 = I915_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *tObj = texUnit->_Current; i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; GLuint face; ss3 |= SS3_NORMALIZED_COORDS; if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; } /* Upload teximages (not pipelined) */ if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { i915SetTexImages( i915, tObj ); } /* upload (per face) */ for (face = 0; face < 6; face++) { if (t->intel.base.dirty_images[face]) { if (!intelUploadTexImages( &i915->intel, &t->intel, face )) { return GL_FALSE; } } } return GL_TRUE; }
static void i915ColorMask(struct gl_context * ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK; DBG("%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a); if (!r) tmp |= S5_WRITEDISABLE_RED; if (!g) tmp |= S5_WRITEDISABLE_GREEN; if (!b) tmp |= S5_WRITEDISABLE_BLUE; if (!a) tmp |= S5_WRITEDISABLE_ALPHA; if (tmp != i915->state.Ctx[I915_CTXREG_LIS5]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS5] = tmp; } }
static void i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint dw; switch (cap) { case GL_TEXTURE_2D: break; case GL_LIGHTING: case GL_COLOR_SUM: update_specular(ctx); break; case GL_ALPHA_TEST: dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (state) dw |= S6_ALPHA_TEST_ENABLE; else dw &= ~S6_ALPHA_TEST_ENABLE; if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } break; case GL_BLEND: i915EvalLogicOpBlendState(ctx); break; case GL_COLOR_LOGIC_OP: i915EvalLogicOpBlendState(ctx); /* Logicop doesn't seem to work at 16bpp: */ if (ctx->Visual.rgbBits == 16) FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); break; case GL_FRAGMENT_PROGRAM_ARB: break; case GL_DITHER: dw = i915->state.Ctx[I915_CTXREG_LIS5]; if (state) dw |= S5_COLOR_DITHER_ENABLE; else dw &= ~S5_COLOR_DITHER_ENABLE; if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { i915->state.Ctx[I915_CTXREG_LIS5] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } break; case GL_DEPTH_TEST: dw = i915->state.Ctx[I915_CTXREG_LIS6]; if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.depthBits) state = false; if (state) dw |= S6_DEPTH_TEST_ENABLE; else dw &= ~S6_DEPTH_TEST_ENABLE; if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } i915DepthMask(ctx, ctx->Depth.Mask); break; case GL_SCISSOR_TEST: I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); if (state) i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); else i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); break; case GL_LINE_SMOOTH: dw = i915->state.Ctx[I915_CTXREG_LIS4]; if (state) dw |= S4_LINE_ANTIALIAS_ENABLE; else dw &= ~S4_LINE_ANTIALIAS_ENABLE; if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { i915->state.Ctx[I915_CTXREG_LIS4] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } break; case GL_CULL_FACE: i915CullFaceFrontFace(ctx, 0); break; case GL_STENCIL_TEST: if (!ctx->DrawBuffer || !ctx->DrawBuffer->Visual.stencilBits) state = false; dw = i915->state.Ctx[I915_CTXREG_LIS5]; if (state) dw |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); else dw &= ~(S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); if (dw != i915->state.Ctx[I915_CTXREG_LIS5]) { i915->state.Ctx[I915_CTXREG_LIS5] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } break; case GL_POLYGON_STIPPLE: /* The stipple command worked on my 855GM box, but not my 845G. * I'll do more testing later to find out exactly which hardware * supports it. Disabled for now. */ if (i915->intel.hw_stipple && i915->intel.reduced_primitive == GL_TRIANGLES) { I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); if (state) i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; else i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; } break; case GL_POLYGON_SMOOTH: break; case GL_POINT_SPRITE: /* Handle it at i915_update_sprite_point_enable () */ break; case GL_POINT_SMOOTH: break; default: ; } }
void i915_update_stencil(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint front_ref, front_writemask, front_mask; GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass; GLuint back_ref, back_writemask, back_mask; GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass; GLuint dirty = 0; /* The 915 considers CW to be "front" for two-sided stencil, so choose * appropriately. */ /* _NEW_POLYGON | _NEW_STENCIL */ if (ctx->Polygon.FrontFace == GL_CW) { front_ref = ctx->Stencil.Ref[0]; front_mask = ctx->Stencil.ValueMask[0]; front_writemask = ctx->Stencil.WriteMask[0]; front_func = ctx->Stencil.Function[0]; front_fail = ctx->Stencil.FailFunc[0]; front_pass_z_fail = ctx->Stencil.ZFailFunc[0]; front_pass_z_pass = ctx->Stencil.ZPassFunc[0]; back_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; back_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; back_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; back_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; back_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; back_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; back_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; } else { front_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace]; front_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace]; front_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace]; front_func = ctx->Stencil.Function[ctx->Stencil._BackFace]; front_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace]; front_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace]; front_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace]; back_ref = ctx->Stencil.Ref[0]; back_mask = ctx->Stencil.ValueMask[0]; back_writemask = ctx->Stencil.WriteMask[0]; back_func = ctx->Stencil.Function[0]; back_fail = ctx->Stencil.FailFunc[0]; back_pass_z_fail = ctx->Stencil.ZFailFunc[0]; back_pass_z_pass = ctx->Stencil.ZPassFunc[0]; } #define set_ctx_bits(reg, mask, set) do{ \ GLuint dw = i915->state.Ctx[reg]; \ dw &= ~(mask); \ dw |= (set); \ dirty |= dw != i915->state.Ctx[reg]; \ i915->state.Ctx[reg] = dw; \ } while(0) /* Set front state. */ set_ctx_bits(I915_CTXREG_STATE4, MODE4_ENABLE_STENCIL_TEST_MASK | MODE4_ENABLE_STENCIL_WRITE_MASK, ENABLE_STENCIL_TEST_MASK | ENABLE_STENCIL_WRITE_MASK | STENCIL_TEST_MASK(front_mask) | STENCIL_WRITE_MASK(front_writemask)); set_ctx_bits(I915_CTXREG_LIS5, S5_STENCIL_REF_MASK | S5_STENCIL_TEST_FUNC_MASK | S5_STENCIL_FAIL_MASK | S5_STENCIL_PASS_Z_FAIL_MASK | S5_STENCIL_PASS_Z_PASS_MASK, (front_ref << S5_STENCIL_REF_SHIFT) | (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) | (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) | (intel_translate_stencil_op(front_pass_z_fail) << S5_STENCIL_PASS_Z_FAIL_SHIFT) | (intel_translate_stencil_op(front_pass_z_pass) << S5_STENCIL_PASS_Z_PASS_SHIFT)); /* Set back state if different from front. */ if (ctx->Stencil._TestTwoSide) { set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, BFO_STENCIL_REF_MASK | BFO_STENCIL_TEST_MASK | BFO_STENCIL_FAIL_MASK | BFO_STENCIL_PASS_Z_FAIL_MASK | BFO_STENCIL_PASS_Z_PASS_MASK, BFO_STENCIL_TWO_SIDE | (back_ref << BFO_STENCIL_REF_SHIFT) | (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) | (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) | (intel_translate_stencil_op(back_pass_z_fail) << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | (intel_translate_stencil_op(back_pass_z_pass) << BFO_STENCIL_PASS_Z_PASS_SHIFT)); set_ctx_bits(I915_CTXREG_BF_STENCIL_MASKS, BFM_STENCIL_TEST_MASK_MASK | BFM_STENCIL_WRITE_MASK_MASK, BFM_STENCIL_TEST_MASK(back_mask) | BFM_STENCIL_WRITE_MASK(back_writemask)); } else { set_ctx_bits(I915_CTXREG_BF_STENCIL_OPS, BFO_STENCIL_TWO_SIDE, 0); } #undef set_ctx_bits if (dirty) I915_STATECHANGE(i915, I915_UPLOAD_CTX); }
void i915ClearWithTris(intelContextPtr intel, GLbitfield buffers, GLboolean allFoo, GLint cxFoo, GLint cyFoo, GLint cwFoo, GLint chFoo) { i915ContextPtr i915 = I915_CONTEXT( intel ); __DRIdrawablePrivate *dPriv = intel->driDrawable; intelScreenPrivate *screen = intel->intelScreen; int x0, y0, x1, y1; GLint cx, cy, cw, ch; GLboolean all; SET_STATE( i915, meta ); set_initial_state( i915 ); set_no_texture( i915 ); set_vertex_format( i915 ); LOCK_HARDWARE(intel); /* get clear bounds after locking */ cx = intel->ctx.DrawBuffer->_Xmin; cy = intel->ctx.DrawBuffer->_Ymin; cw = intel->ctx.DrawBuffer->_Xmax - cx; ch = intel->ctx.DrawBuffer->_Ymax - cy; all = (cw == intel->ctx.DrawBuffer->Width && ch == intel->ctx.DrawBuffer->Height); if (!all) { x0 = cx; y0 = cy; x1 = x0 + cw; y1 = y0 + ch; } else { x0 = 0; y0 = 0; x1 = x0 + dPriv->w; y1 = y0 + dPriv->h; } /* Don't do any clipping to screen - these are window coordinates. * The active cliprects will be applied as for any other geometry. */ if (buffers & BUFFER_BIT_FRONT_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->front ); draw_quad(i915, x0, x1, y0, y1, intel->clear_red, intel->clear_green, intel->clear_blue, intel->clear_alpha, 0, 0, 0, 0); } if (buffers & BUFFER_BIT_BACK_LEFT) { set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); set_draw_region( i915, &screen->back ); draw_quad(i915, x0, x1, y0, y1, intel->clear_red, intel->clear_green, intel->clear_blue, intel->clear_alpha, 0, 0, 0, 0); } if (buffers & BUFFER_BIT_STENCIL) { set_stencil_replace( i915, intel->ctx.Stencil.WriteMask[0], intel->ctx.Stencil.Clear); set_color_mask( i915, GL_FALSE ); set_draw_region( i915, &screen->front ); /* could be either? */ draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 ); } UNLOCK_HARDWARE(intel); SET_STATE( i915, state ); }
/** * Copy the window contents named by dPriv to the rotated (or reflected) * color buffer. * srcBuf is BUFFER_BIT_FRONT_LEFT or BUFFER_BIT_BACK_LEFT to indicate the source. */ void i915RotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv, GLuint srcBuf) { i915ContextPtr i915 = I915_CONTEXT( intel ); intelScreenPrivate *screen = intel->intelScreen; const GLuint cpp = screen->cpp; drm_clip_rect_t fullRect; GLuint textureFormat, srcOffset, srcPitch; const drm_clip_rect_t *clipRects; int numClipRects; int i; int xOrig, yOrig; int origNumClipRects; drm_clip_rect_t *origRects; /* * set up hardware state */ intelFlush( &intel->ctx ); SET_STATE( i915, meta ); set_initial_state( i915 ); set_no_texture( i915 ); set_vertex_format( i915 ); set_no_depth_stencil_write( i915 ); set_color_mask( i915, GL_TRUE ); LOCK_HARDWARE(intel); /* save current drawing origin and cliprects (restored at end) */ xOrig = intel->drawX; yOrig = intel->drawY; origNumClipRects = intel->numClipRects; origRects = intel->pClipRects; if (!intel->numClipRects) goto done; /* * set drawing origin, cliprects for full-screen access to rotated screen */ fullRect.x1 = 0; fullRect.y1 = 0; fullRect.x2 = screen->rotatedWidth; fullRect.y2 = screen->rotatedHeight; intel->drawX = 0; intel->drawY = 0; intel->numClipRects = 1; intel->pClipRects = &fullRect; set_draw_region( i915, &screen->rotated ); if (cpp == 4) textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; else textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; if (srcBuf == BUFFER_BIT_FRONT_LEFT) { srcPitch = screen->front.pitch; /* in bytes */ srcOffset = screen->front.offset; /* bytes */ clipRects = dPriv->pClipRects; numClipRects = dPriv->numClipRects; } else { srcPitch = screen->back.pitch; /* in bytes */ srcOffset = screen->back.offset; /* bytes */ clipRects = dPriv->pBackClipRects; numClipRects = dPriv->numBackClipRects; } /* set the whole screen up as a texture to avoid alignment issues */ set_tex_rect_source(i915, srcOffset, screen->width, screen->height, srcPitch, textureFormat); enable_texture_blend_replace(i915); /* * loop over the source window's cliprects */ for (i = 0; i < numClipRects; i++) { int srcX0 = clipRects[i].x1; int srcY0 = clipRects[i].y1; int srcX1 = clipRects[i].x2; int srcY1 = clipRects[i].y2; GLfloat verts[4][2], tex[4][2]; int j; /* build vertices for four corners of clip rect */ verts[0][0] = srcX0; verts[0][1] = srcY0; verts[1][0] = srcX1; verts[1][1] = srcY0; verts[2][0] = srcX1; verts[2][1] = srcY1; verts[3][0] = srcX0; verts[3][1] = srcY1; /* .. and texcoords */ tex[0][0] = srcX0; tex[0][1] = srcY0; tex[1][0] = srcX1; tex[1][1] = srcY0; tex[2][0] = srcX1; tex[2][1] = srcY1; tex[3][0] = srcX0; tex[3][1] = srcY1; /* transform coords to rotated screen coords */ for (j = 0; j < 4; j++) { matrix23TransformCoordf(&screen->rotMatrix, &verts[j][0], &verts[j][1]); } /* draw polygon to map source image to dest region */ draw_poly(i915, 255, 255, 255, 255, 4, verts, tex); } /* cliprect loop */ intelFlushBatchLocked( intel, GL_FALSE, GL_FALSE, GL_FALSE ); done: /* restore original drawing origin and cliprects */ intel->drawX = xOrig; intel->drawY = yOrig; intel->numClipRects = origNumClipRects; intel->pClipRects = origRects; UNLOCK_HARDWARE(intel); SET_STATE( i915, state ); }
/* ============================================================= * Fog */ void i915_update_fog(GLcontext * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); GLenum mode; GLboolean enabled; GLboolean try_pixel_fog; if (ctx->FragmentProgram._Active) { /* Pull in static fog state from program */ mode = ctx->FragmentProgram._Current->FogOption; enabled = (mode != GL_NONE); try_pixel_fog = 0; } else { enabled = ctx->Fog.Enabled; mode = ctx->Fog.Mode; #if 0 /* XXX - DISABLED -- Need ortho fallback */ try_pixel_fog = (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT && ctx->Hint.Fog == GL_NICEST); #else try_pixel_fog = 0; #endif } if (!enabled) { i915->vertex_fog = I915_FOG_NONE; } else if (try_pixel_fog) { I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; i915->vertex_fog = I915_FOG_PIXEL; switch (mode) { case GL_LINEAR: if (ctx->Fog.End <= ctx->Fog.Start) { /* XXX - this won't work with fragment programs. Need to * either fallback or append fog instructions to end of * program in the case of linear fog. */ printf("vertex fog!\n"); i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; i915->vertex_fog = I915_FOG_VERTEX; } else { GLfloat c2 = 1.0 / (ctx->Fog.End - ctx->Fog.Start); GLfloat c1 = ctx->Fog.End * c2; i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_C1_MASK; i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_LINEAR; i915->state.Fog[I915_FOGREG_MODE1] |= ((GLuint) (c1 * FMC1_C1_ONE)) & FMC1_C1_MASK; if (i915->state.Fog[I915_FOGREG_MODE1] & FMC1_FOGINDEX_Z) { i915->state.Fog[I915_FOGREG_MODE2] = (GLuint) (c2 * FMC2_C2_ONE); } else { fi_type fi; fi.f = c2; i915->state.Fog[I915_FOGREG_MODE2] = fi.i; } } break; case GL_EXP: i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP; break; case GL_EXP2: i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_PIXEL_EXP2; break; default: break; } } else { /* if (i915->vertex_fog != I915_FOG_VERTEX) */ I915_STATECHANGE(i915, I915_UPLOAD_FOG); i915->state.Fog[I915_FOGREG_MODE1] &= ~FMC1_FOGFUNC_MASK; i915->state.Fog[I915_FOGREG_MODE1] |= FMC1_FOGFUNC_VERTEX; i915->vertex_fog = I915_FOG_VERTEX; } I915_STATECHANGE(i915, I915_UPLOAD_CTX); I915_ACTIVESTATE(i915, I915_UPLOAD_FOG, enabled); if (enabled) i915->state.Ctx[I915_CTXREG_LIS5] |= S5_FOG_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_FOG_ENABLE; /* Always enable pixel fog. Vertex fog using fog coord will conflict * with fog code appended onto fragment program. */ _tnl_allow_vertex_fog( ctx, 0 ); _tnl_allow_pixel_fog( ctx, 1 ); }
static void i915Enable(GLcontext * ctx, GLenum cap, GLboolean state) { struct i915_context *i915 = I915_CONTEXT(ctx); switch (cap) { case GL_TEXTURE_2D: break; case GL_LIGHTING: case GL_COLOR_SUM: update_specular(ctx); break; case GL_ALPHA_TEST: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) i915->state.Ctx[I915_CTXREG_LIS6] |= S6_ALPHA_TEST_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_ALPHA_TEST_ENABLE; break; case GL_BLEND: i915EvalLogicOpBlendState(ctx); break; case GL_COLOR_LOGIC_OP: i915EvalLogicOpBlendState(ctx); /* Logicop doesn't seem to work at 16bpp: */ if (i915->intel.intelScreen->cpp == 2) /* XXX FBO fix */ FALLBACK(&i915->intel, I915_FALLBACK_LOGICOP, state); break; case GL_FRAGMENT_PROGRAM_ARB: break; case GL_DITHER: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) i915->state.Ctx[I915_CTXREG_LIS5] |= S5_COLOR_DITHER_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_COLOR_DITHER_ENABLE; break; case GL_DEPTH_TEST: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_TEST_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_ENABLE; i915DepthMask(ctx, ctx->Depth.Mask); break; case GL_SCISSOR_TEST: I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS); if (state) i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT); else i915->state.Buffer[I915_DESTREG_SENABLE] = (_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); break; case GL_LINE_SMOOTH: I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) i915->state.Ctx[I915_CTXREG_LIS4] |= S4_LINE_ANTIALIAS_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_LINE_ANTIALIAS_ENABLE; break; case GL_FOG: break; case GL_CULL_FACE: i915CullFaceFrontFace(ctx, 0); break; case GL_STENCIL_TEST: { GLboolean hw_stencil = GL_FALSE; if (ctx->DrawBuffer) { struct intel_renderbuffer *irbStencil = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); hw_stencil = (irbStencil && irbStencil->region); } if (hw_stencil) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (state) i915->state.Ctx[I915_CTXREG_LIS5] |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); else i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE); } else { FALLBACK(&i915->intel, I915_FALLBACK_STENCIL, state); } } break; case GL_POLYGON_STIPPLE: /* The stipple command worked on my 855GM box, but not my 845G. * I'll do more testing later to find out exactly which hardware * supports it. Disabled for now. */ if (i915->intel.hw_stipple && i915->intel.reduced_primitive == GL_TRIANGLES) { I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); if (state) i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; else i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; } break; case GL_POLYGON_SMOOTH: break; case GL_POINT_SMOOTH: break; default: ; } }