void i915_upload_program(struct i915_context *i915, struct i915_fragment_program *p) { GLuint program_size = p->csr - p->program; GLuint decl_size = p->decl - p->declarations; if (p->error) return; /* Could just go straight to the batchbuffer from here: */ if (i915->state.ProgramSize != (program_size + decl_size) || memcmp(i915->state.Program + decl_size, p->program, program_size * sizeof(int)) != 0) { I915_STATECHANGE(i915, I915_UPLOAD_PROGRAM); memcpy(i915->state.Program, p->declarations, decl_size * sizeof(int)); memcpy(i915->state.Program + decl_size, p->program, program_size * sizeof(int)); i915->state.ProgramSize = decl_size + program_size; } /* Always seemed to get a failure if I used memcmp() to * shortcircuit this state upload. Needs further investigation? */ if (p->nr_constants) { GLuint nr = p->nr_constants; I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 1); I915_STATECHANGE(i915, I915_UPLOAD_CONSTANTS); i915->state.Constant[0] = _3DSTATE_PIXEL_SHADER_CONSTANTS | ((nr) * 4); i915->state.Constant[1] = (1 << (nr - 1)) | ((1 << (nr - 1)) - 1); memcpy(&i915->state.Constant[2], p->constant, 4 * sizeof(int) * (nr)); i915->state.ConstantSize = 2 + (nr) * 4; if (0) { GLuint i; for (i = 0; i < nr; i++) { fprintf(stderr, "const[%d]: %f %f %f %f\n", i, p->constant[i][0], p->constant[i][1], p->constant[i][2], p->constant[i][3]); } } } else { I915_ACTIVESTATE(i915, I915_UPLOAD_CONSTANTS, 0); } p->on_hardware = 1; }
static void i915UpdateBlendState(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint iab = (i915->state.Blend[I915_BLENDREG_IAB] & ~(IAB_SRC_FACTOR_MASK | IAB_DST_FACTOR_MASK | (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE)); GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] & ~(S6_CBUF_SRC_BLEND_FACT_MASK | S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK)); GLuint eqRGB = ctx->Color.Blend[0].EquationRGB; GLuint eqA = ctx->Color.Blend[0].EquationA; GLuint srcRGB = ctx->Color.Blend[0].SrcRGB; GLuint dstRGB = ctx->Color.Blend[0].DstRGB; GLuint srcA = ctx->Color.Blend[0].SrcA; GLuint dstA = ctx->Color.Blend[0].DstA; if (eqRGB == GL_MIN || eqRGB == GL_MAX) { srcRGB = dstRGB = GL_ONE; } if (eqA == GL_MIN || eqA == GL_MAX) { srcA = dstA = GL_ONE; } lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB)); lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB)); lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT; iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA)); iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA)); iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT; if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) iab |= IAB_ENABLE; if (iab != i915->state.Blend[I915_BLENDREG_IAB]) { i915->state.Blend[I915_BLENDREG_IAB] = iab; I915_STATECHANGE(i915, I915_UPLOAD_BLEND); } if (lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS6] = lis6; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } /* This will catch a logicop blend equation */ i915EvalLogicOpBlendState(ctx); }
static void i915_reduced_primitive_state(struct intel_context *intel, GLenum rprim) { struct i915_context *i915 = i915_context(&intel->ctx); GLuint st1 = i915->state.Stipple[I915_STPREG_ST1]; st1 &= ~ST1_ENABLE; switch (rprim) { case GL_QUADS: /* from RASTERIZE(GL_QUADS) in t_dd_tritemp.h */ case GL_TRIANGLES: if (intel->ctx.Polygon.StippleFlag && intel->hw_stipple) st1 |= ST1_ENABLE; break; case GL_LINES: case GL_POINTS: default: break; } i915->intel.reduced_primitive = rprim; if (st1 != i915->state.Stipple[I915_STPREG_ST1]) { INTEL_FIREVERTICES(intel); I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); i915->state.Stipple[I915_STPREG_ST1] = st1; } }
static void i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { struct i915_context *i915 = I915_CONTEXT(ctx); int fop = intel_translate_stencil_op(fail); int dfop = intel_translate_stencil_op(zfail); int dpop = intel_translate_stencil_op(zpass); DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(fail), _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass)); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK | S5_STENCIL_PASS_Z_FAIL_MASK | S5_STENCIL_PASS_Z_PASS_MASK); i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) | (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | (dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); }
static GLboolean enable_tex_2d( 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]; 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]) { i915SetTexImages( i915, tObj ); if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) { return GL_FALSE; } } return GL_TRUE; }
static void i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); mask = mask & 0xff; DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(func), ref, mask); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK | STENCIL_TEST_MASK(mask)); i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK | S5_STENCIL_TEST_FUNC_MASK); i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) | (test << S5_STENCIL_TEST_FUNC_SHIFT)); }
/* 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(struct gl_context * ctx) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint dw0, dw1; dw0 = i915->state.Ctx[I915_CTXREG_LIS5]; dw1 = i915->state.Ctx[I915_CTXREG_LIS6]; if (ctx->Color.ColorLogicOpEnabled) { dw0 |= S5_LOGICOP_ENABLE; dw1 &= ~S6_CBUF_BLEND_ENABLE; } else { dw0 &= ~S5_LOGICOP_ENABLE; if (ctx->Color.BlendEnabled) { dw1 |= S6_CBUF_BLEND_ENABLE; } else { dw1 &= ~S6_CBUF_BLEND_ENABLE; } } if (dw0 != i915->state.Ctx[I915_CTXREG_LIS5] || dw1 != i915->state.Ctx[I915_CTXREG_LIS6]) { i915->state.Ctx[I915_CTXREG_LIS5] = dw0; i915->state.Ctx[I915_CTXREG_LIS6] = dw1; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } }
static void i915CullFaceFrontFace(struct gl_context * ctx, GLenum unused) { struct i915_context *i915 = I915_CONTEXT(ctx); GLuint mode, dw; DBG("%s %d\n", __FUNCTION__, ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0); if (!ctx->Polygon.CullFlag) { mode = S4_CULLMODE_NONE; } else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { mode = S4_CULLMODE_CW; if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); if (ctx->Polygon.CullFaceMode == GL_FRONT) mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); if (ctx->Polygon.FrontFace != GL_CCW) mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW); } else { mode = S4_CULLMODE_BOTH; } dw = i915->state.Ctx[I915_CTXREG_LIS4]; dw &= ~S4_CULLMODE_MASK; dw |= mode; if (dw != i915->state.Ctx[I915_CTXREG_LIS4]) { i915->state.Ctx[I915_CTXREG_LIS4] = dw; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } }
/* ============================================================= * Polygon stipple * * The i915 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */ static void i915PolygonStipple(struct gl_context * ctx, const GLubyte * mask) { struct i915_context *i915 = I915_CONTEXT(ctx); const GLubyte *m; GLubyte p[4]; int i, j, k; int active = (ctx->Polygon.StippleFlag && i915->intel.reduced_primitive == GL_TRIANGLES); GLuint newMask; if (active) { I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE); i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE; } /* Use the already unpacked stipple data from the context rather than the * uninterpreted mask passed in. */ mask = (const GLubyte *)ctx->PolygonStipple; m = mask; p[0] = mask[12] & 0xf; p[0] |= p[0] << 4; p[1] = mask[8] & 0xf; p[1] |= p[1] << 4; p[2] = mask[4] & 0xf; p[2] |= p[2] << 4; p[3] = mask[0] & 0xf; p[3] |= p[3] << 4; for (k = 0; k < 8; k++) for (j = 3; j >= 0; j--) for (i = 0; i < 4; i++, m++) if (*m != p[j]) { i915->intel.hw_stipple = 0; return; } newMask = (((p[0] & 0xf) << 0) | ((p[1] & 0xf) << 4) | ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12)); if (newMask == 0xffff || newMask == 0x0) { /* this is needed to make conform pass */ i915->intel.hw_stipple = 0; return; } i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff; i915->state.Stipple[I915_STPREG_ST1] |= newMask; i915->intel.hw_stipple = 1; if (active) i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE; }
static void i915DepthFunc(GLcontext * ctx, GLenum func) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); DBG("%s\n", __FUNCTION__); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK; i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT; }
static void i915LogicOp(struct gl_context * ctx, GLenum opcode) { struct i915_context *i915 = I915_CONTEXT(ctx); int tmp = intel_translate_logic_op(opcode); DBG("%s\n", __FUNCTION__); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp); }
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; } }
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 void i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) { struct i915_context *i915 = I915_CONTEXT(ctx); DBG("%s : mask 0x%x\n", __FUNCTION__, mask); mask = mask & 0xff; I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK; i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK | STENCIL_WRITE_MASK(mask)); }
static void i915DepthMask(GLcontext * ctx, GLboolean flag) { struct i915_context *i915 = I915_CONTEXT(ctx); DBG("%s flag (%d)\n", __FUNCTION__, flag); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (flag && ctx->Depth.Test) i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE; else i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE; }
static void i915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLubyte refByte; UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK | S6_ALPHA_REF_MASK); i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) | (((GLuint) refByte) << S6_ALPHA_REF_SHIFT)); }
static void i915DepthFunc(struct gl_context * ctx, GLenum func) { struct i915_context *i915 = I915_CONTEXT(ctx); int test = intel_translate_compare_func(func); GLuint dw; DBG("%s\n", __FUNCTION__); dw = i915->state.Ctx[I915_CTXREG_LIS6]; dw &= ~S6_DEPTH_TEST_FUNC_MASK; dw |= test << S6_DEPTH_TEST_FUNC_SHIFT; if (dw != i915->state.Ctx[I915_CTXREG_LIS6]) { I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_LIS6] = dw; } }
static void i915BlendColor(GLcontext * ctx, const GLfloat color[4]) { struct i915_context *i915 = I915_CONTEXT(ctx); GLubyte r, g, b, a; 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]); I915_STATECHANGE(i915, I915_UPLOAD_CTX); i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = (a << 24) | (r << 16) | (g << 8) | b; }
static void i915PointSize(struct gl_context * ctx, GLfloat size) { struct i915_context *i915 = I915_CONTEXT(ctx); int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK; GLint point_size = (int) round(size); DBG("%s\n", __FUNCTION__); point_size = CLAMP(point_size, 1, 255); lis4 |= point_size << S4_POINT_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 i915ShadeModel(struct gl_context * ctx, GLenum mode) { struct i915_context *i915 = I915_CONTEXT(ctx); I915_STATECHANGE(i915, I915_UPLOAD_CTX); if (mode == GL_SMOOTH) { i915->state.Ctx[I915_CTXREG_LIS4] &= ~(S4_FLATSHADE_ALPHA | S4_FLATSHADE_COLOR | S4_FLATSHADE_SPECULAR); } else { i915->state.Ctx[I915_CTXREG_LIS4] |= (S4_FLATSHADE_ALPHA | S4_FLATSHADE_COLOR | S4_FLATSHADE_SPECULAR); } }
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 i915_import_tex_unit( i915ContextPtr i915, i915TextureObjectPtr t, GLuint unit ) { GLuint state[I915_TEX_SETUP_SIZE]; if(INTEL_DEBUG&DEBUG_TEXTURE) fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); if (i915->intel.CurrentTexObj[unit]) i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit); i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; t->intel.base.bound |= (1 << unit); if (t->intel.dirty & I915_UPLOAD_TEX(unit)) { i915ImportTexObjState( t->intel.base.tObj ); t->intel.dirty &= ~I915_UPLOAD_TEX(unit); } state[I915_TEXREG_MS2] = t->intel.TextureOffset; state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3]; state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4]; state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] & SS2_LOD_BIAS_MASK); state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK); state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] & SS3_NORMALIZED_COORDS); state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] & ~(SS3_NORMALIZED_COORDS| SS3_TEXTUREMAP_INDEX_MASK)); state[I915_TEXREG_SS3] |= (unit<<SS3_TEXTUREMAP_INDEX_SHIFT); state[I915_TEXREG_SS4] = t->Setup[I915_TEXREG_SS4]; if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) { I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) ); memcpy(i915->state.Tex[unit], state, sizeof(state)); } }
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); } }
void i915_update_sprite_point_enable(struct gl_context *ctx) { struct intel_context *intel = intel_context(ctx); /* _NEW_PROGRAM */ struct i915_fragment_program *p = (struct i915_fragment_program *) ctx->FragmentProgram._Current; const GLbitfield64 inputsRead = p->FragProg.Base.InputsRead; struct i915_context *i915 = i915_context(ctx); GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; int i; GLuint coord_replace_bits = 0x0; GLuint tex_coord_unit_bits = 0x0; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { /* _NEW_POINT */ if (ctx->Point.CoordReplace[i] && ctx->Point.PointSprite) coord_replace_bits |= (1 << i); if (inputsRead & FRAG_BIT_TEX(i)) tex_coord_unit_bits |= (1 << i); } /* * Here we can't enable the SPRITE_POINT_ENABLE bit when the mis-match * of tex_coord_unit_bits and coord_replace_bits, or this will make all * the other non-point-sprite coords(like varying inputs, as we now use * tex coord to implement varying inputs) be replaced to value (0, 0)-(1, 1). * * Thus, do fallback when needed. */ FALLBACK(intel, I915_FALLBACK_COORD_REPLACE, coord_replace_bits && coord_replace_bits != tex_coord_unit_bits); s4 &= ~S4_SPRITE_POINT_ENABLE; s4 |= (coord_replace_bits && coord_replace_bits == tex_coord_unit_bits) ? S4_SPRITE_POINT_ENABLE : 0; if (s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { i915->state.Ctx[I915_CTXREG_LIS4] = s4; I915_STATECHANGE(i915, I915_UPLOAD_CTX); } }
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; } }
/* ============================================================= * 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); }
/* 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 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; } }
void i915ValidateFragmentProgram(struct i915_context *i915) { GLcontext *ctx = &i915->intel.ctx; struct intel_context *intel = intel_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; struct i915_fragment_program *p = (struct i915_fragment_program *) ctx->FragmentProgram._Current; const GLuint inputsRead = p->FragProg.Base.InputsRead; GLuint s4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_VFMT_MASK; GLuint s2 = S2_TEXCOORD_NONE; int i, offset = 0; if (i915->current_program != p) { if (i915->current_program) { i915->current_program->on_hardware = 0; i915->current_program->params_uptodate = 0; } i915->current_program = p; } /* Important: */ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; if (!p->translated) translate_program(p); intel->vertex_attr_count = 0; intel->wpos_offset = 0; intel->wpos_size = 0; intel->coloroffset = 0; intel->specoffset = 0; if (inputsRead & FRAG_BITS_TEX_ANY) { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, S4_VFMT_XYZW, 16); } else { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, S4_VFMT_XYZ, 12); } if (inputsRead & FRAG_BIT_COL0) { intel->coloroffset = offset / 4; EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, S4_VFMT_COLOR, 4); } if ((inputsRead & (FRAG_BIT_COL1 | FRAG_BIT_FOGC)) || i915->vertex_fog != I915_FOG_NONE) { if (inputsRead & FRAG_BIT_COL1) { intel->specoffset = offset / 4; EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, S4_VFMT_SPEC_FOG, 3); } else EMIT_PAD(3); if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, S4_VFMT_SPEC_FOG, 1); else EMIT_PAD(1); } /* XXX this was disabled, but enabling this code helped fix the Glean * tfragprog1 fog tests. */ #if 1 if ((inputsRead & FRAG_BIT_FOGC) || i915->vertex_fog != I915_FOG_NONE) { EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1F, S4_VFMT_FOG_PARAM, 4); } #endif for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) { if (inputsRead & FRAG_BIT_TEX(i)) { int sz = VB->TexCoordPtr[i]->size; s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz)); EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4); } else if (i == p->wpos_tex) { /* If WPOS is required, duplicate the XYZ position data in an * unused texture coordinate: */ s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK); s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(3)); intel->wpos_offset = offset; intel->wpos_size = 3 * sizeof(GLuint); EMIT_PAD(intel->wpos_size); } } if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] || s4 != i915->state.Ctx[I915_CTXREG_LIS4]) { int k; I915_STATECHANGE(i915, I915_UPLOAD_CTX); /* Must do this *after* statechange, so as not to affect * buffered vertices reliant on the old state: */ intel->vertex_size = _tnl_install_attrs(&intel->ctx, intel->vertex_attrs, intel->vertex_attr_count, intel->ViewportMatrix.m, 0); intel->vertex_size >>= 2; i915->state.Ctx[I915_CTXREG_LIS2] = s2; i915->state.Ctx[I915_CTXREG_LIS4] = s4; k = intel->vtbl.check_vertex_size(intel, intel->vertex_size); assert(k); }