void i810InitTextureFuncs( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); ctx->Driver.TexEnv = i810TexEnv; ctx->Driver.ChooseTextureFormat = i810ChooseTextureFormat; ctx->Driver.TexImage1D = _mesa_store_teximage1d; ctx->Driver.TexImage2D = i810TexImage2D; ctx->Driver.TexImage3D = _mesa_store_teximage3d; ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; ctx->Driver.TexSubImage2D = i810TexSubImage2D; ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; ctx->Driver.BindTexture = i810BindTexture; ctx->Driver.DeleteTexture = i810DeleteTexture; ctx->Driver.TexParameter = i810TexParameter; ctx->Driver.UpdateTexturePalette = 0; ctx->Driver.IsTextureResident = driIsTextureResident; ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; driInitTextureObjects( ctx, &imesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D); }
/** * Update hardware state for a texture unit. * * \todo * 1D textures should be supported! Just use a 2D texture with the second * texture coordinate value fixed at 0.0. */ static void i810UpdateTexUnit( struct gl_context *ctx, GLuint unit, int * next_color_stage, int * next_alpha_stage ) { i810ContextPtr imesa = I810_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLboolean ret; switch(texUnit->_ReallyEnabled) { case TEXTURE_2D_BIT: ret = enable_tex_common( ctx, unit); ret &= enable_tex_2d(ctx, unit); if (ret == GL_FALSE) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); } break; case TEXTURE_RECT_BIT: ret = enable_tex_common( ctx, unit); ret &= enable_tex_rect(ctx, unit); if (ret == GL_FALSE) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); } break; case 0: disable_tex(ctx, unit); break; } if (!i810UpdateTexEnvCombine( ctx, unit, next_color_stage, next_alpha_stage )) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); } return; }
static void i810AlphaFunc(struct gl_context *ctx, GLenum func, GLfloat ref) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF); GLubyte refByte; CLAMPED_FLOAT_TO_UBYTE(refByte, ref); switch (ctx->Color.AlphaFunc) { case GL_NEVER: a |= ZA_ALPHA_NEVER; break; case GL_LESS: a |= ZA_ALPHA_LESS; break; case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break; case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break; case GL_GREATER: a |= ZA_ALPHA_GREATER; break; case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break; case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break; case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break; default: return; } a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK); imesa->Setup[I810_CTXREG_ZA] |= a; }
static void i810BlendEquationSeparate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA) { assert( modeRGB == modeA ); /* Can only do GL_ADD equation in hardware */ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ, modeRGB != GL_FUNC_ADD); /* BlendEquation sets ColorLogicOpEnabled in an unexpected * manner. */ FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP, (ctx->Color.ColorLogicOpEnabled && ctx->Color.LogicOp != GL_COPY)); }
/* Move locking out to get reasonable span performance. */ void i810SpanRenderStart( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); I810_FIREVERTICES(imesa); LOCK_HARDWARE(imesa); i810RegetLockQuiescent( imesa ); }
static void i810TexImage2D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { driTextureObject *t = (driTextureObject *) texObj->DriverData; if (t) { I810_FIREVERTICES( I810_CONTEXT(ctx) ); driSwapOutTextureObject( t ); } else { t = (driTextureObject *) i810AllocTexObj( ctx, texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } } _mesa_store_teximage2d( ctx, target, level, internalFormat, width, height, border, format, type, pixels, packing, texObj, texImage ); }
static void i810InvalidateState( struct gl_context *ctx, GLuint new_state ) { _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); I810_CONTEXT(ctx)->new_state |= new_state; }
void i810FreeVB( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); if (imesa->verts) { ALIGN_FREE(imesa->verts); imesa->verts = 0; } }
static void disable_tex( struct gl_context *ctx, GLuint unit ) { i810ContextPtr imesa = I810_CONTEXT(ctx); imesa->CurrentTexObj[unit] = 0; imesa->TexEnvImageFmt[unit] = 0; imesa->dirty &= ~(I810_UPLOAD_TEX0<<unit); }
/* In Mesa 3.5 we can reliably do native flatshading. */ static void i810ShadeModel(struct gl_context *ctx, GLenum mode) { i810ContextPtr imesa = I810_CONTEXT(ctx); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (mode == GL_FLAT) imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT; else imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT; }
static void copy_pv_rgba3( struct gl_context *ctx, GLuint edst, GLuint esrc ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); GLubyte *i810verts = (GLubyte *)imesa->verts; GLuint shift = imesa->vertex_stride_shift; i810Vertex *dst = (i810Vertex *)(i810verts + (edst << shift)); i810Vertex *src = (i810Vertex *)(i810verts + (esrc << shift)); dst->ui[3] = src->ui[3]; }
void *i810_emit_contiguous_verts( GLcontext *ctx, GLuint start, GLuint count, void *dest ) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint stride = imesa->vertex_size * 4; setup_tab[imesa->SetupIndex].emit( ctx, start, count, dest, stride ); return (void *)((char *)dest + stride * (count - start)); }
static void i810DepthMask(struct gl_context *ctx, GLboolean flag) { i810ContextPtr imesa = I810_CONTEXT(ctx); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (flag) imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE; else imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE; }
static void i810DeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { driTextureObject * t = (driTextureObject *) tObj->DriverData; if (t) { i810ContextPtr imesa = I810_CONTEXT( ctx ); if (imesa) I810_FIREVERTICES( imesa ); driDestroyTextureObject( t ); } }
static void i810ClearColor(struct gl_context *ctx, const GLfloat color[4] ) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLubyte c[4]; CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat, c[0], c[1], c[2], c[3] ); }
static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND; GLboolean fallback = GL_FALSE; switch (ctx->Color.BlendSrcRGB) { case GL_ZERO: a |= SDM_SRC_ZERO; break; case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break; case GL_ONE: a |= SDM_SRC_ONE; break; case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break; case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break; case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break; case GL_DST_ALPHA: a |= SDM_SRC_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break; case GL_SRC_ALPHA_SATURATE: /*a |= SDM_SRC_SRC_ALPHA; break;*/ case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; default: return; } switch (ctx->Color.BlendDstRGB) { case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break; case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break; case GL_ZERO: a |= SDM_DST_ZERO; break; case GL_ONE: a |= SDM_DST_ONE; break; case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break; case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break; case GL_DST_ALPHA: a |= SDM_DST_ONE; break; case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: fallback = GL_TRUE; break; default: return; } FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback); if (!fallback) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK); imesa->Setup[I810_CTXREG_SDM] |= a; } }
/* Seperate specular not fully implemented on the i810. */ static void i810LightModelfv(struct gl_context *ctx, GLenum pname, const GLfloat *param) { if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { i810ContextPtr imesa = I810_CONTEXT( ctx ); FALLBACK( imesa, I810_FALLBACK_SPECULAR, (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); } }
void i810InitStateFuncs(GLcontext *ctx) { /* Callbacks for internal Mesa events. */ ctx->Driver.UpdateState = i810InvalidateState; /* API callbacks */ ctx->Driver.AlphaFunc = i810AlphaFunc; ctx->Driver.BlendEquationSeparate = i810BlendEquationSeparate; ctx->Driver.BlendFuncSeparate = i810BlendFuncSeparate; ctx->Driver.ClearColor = i810ClearColor; ctx->Driver.ColorMask = i810ColorMask; ctx->Driver.CullFace = i810CullFaceFrontFace; ctx->Driver.DepthFunc = i810DepthFunc; ctx->Driver.DepthMask = i810DepthMask; ctx->Driver.Enable = i810Enable; ctx->Driver.Fogfv = i810Fogfv; ctx->Driver.FrontFace = i810CullFaceFrontFace; ctx->Driver.LineWidth = i810LineWidth; ctx->Driver.LogicOpcode = i810LogicOp; ctx->Driver.PolygonStipple = i810PolygonStipple; ctx->Driver.RenderMode = i810RenderMode; ctx->Driver.Scissor = i810Scissor; ctx->Driver.DrawBuffer = i810DrawBuffer; ctx->Driver.ReadBuffer = i810ReadBuffer; ctx->Driver.ShadeModel = i810ShadeModel; ctx->Driver.DepthRange = i810DepthRange; ctx->Driver.Viewport = i810Viewport; ctx->Driver.PointSize = i810PointSize; if (IS_I815(I810_CONTEXT(ctx))) { ctx->Driver.LightModelfv = i810LightModelfv_i815; } else { ctx->Driver.LightModelfv = i810LightModelfv; } /* Pixel path fallbacks. */ ctx->Driver.Accum = _swrast_Accum; ctx->Driver.Bitmap = _swrast_Bitmap; ctx->Driver.CopyPixels = _swrast_CopyPixels; ctx->Driver.DrawPixels = _swrast_DrawPixels; ctx->Driver.ReadPixels = _swrast_ReadPixels; /* Swrast hooks for imaging extensions: */ ctx->Driver.CopyColorTable = _swrast_CopyColorTable; ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; }
/* ============================================================= * Fog */ static void i810Fogfv(struct gl_context *ctx, GLenum pname, const GLfloat *param) { i810ContextPtr imesa = I810_CONTEXT(ctx); if (pname == GL_FOG_COLOR) { GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) | ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) | ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0)); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) & ~FOG_RESERVED_MASK); } }
/* But the 815 has it... */ static void i810LightModelfv_i815(struct gl_context *ctx, GLenum pname, const GLfloat *param) { if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { i810ContextPtr imesa = I810_CONTEXT( ctx ); I810_STATECHANGE(imesa, I810_UPLOAD_CTX); if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE; else imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE; } }
static void i810PointSize( GLcontext *ctx, GLfloat sz ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); int size = (int)ctx->Point._Size; imesa->LcsPointSize = 0; if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0; if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0; if (imesa->reduced_primitive == GL_POINTS) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize; } }
/* Determine the rasterized primitive when not drawing unfilled * polygons. * * Used only for the default render stage which always decomposes * primitives to trianges/lines/points. For the accelerated stage, * which renders strips as strips, the equivalent calculations are * performed in i810render.c. */ static void i810RenderPrimitive( GLcontext *ctx, GLenum prim ) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint rprim = reduced_prim[prim]; imesa->render_primitive = prim; if (rprim == GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) return; if (imesa->reduced_primitive != rprim || hw_prim[prim] != imesa->hw_primitive) { i810RasterPrimitive( ctx, rprim, hw_prim[prim] ); } }
void i810InitVB( GLcontext *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); GLuint size = TNL_CONTEXT(ctx)->vb.Size; imesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32); { static int firsttime = 1; if (firsttime) { init_setup_tab(); firsttime = 0; } } }
static void i810Scissor( struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { i810ContextPtr imesa = I810_CONTEXT(ctx); if (ctx->Scissor.Enabled) { I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */ imesa->upload_cliprects = GL_TRUE; } imesa->scissor_rect.x1 = x; imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h); imesa->scissor_rect.x2 = x + w; imesa->scissor_rect.y2 = imesa->driDrawable->h - y; }
static void i810LineWidth( GLcontext *ctx, GLfloat widthf ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); int width = (int)ctx->Line._Width; imesa->LcsLineWidth = 0; if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0; if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0; if (imesa->reduced_primitive == GL_LINES) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0; imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth; } }
static void i810CalcViewport( struct gl_context *ctx ) { i810ContextPtr imesa = I810_CONTEXT(ctx); const GLfloat *v = ctx->Viewport._WindowMap.m; GLfloat *m = imesa->ViewportMatrix.m; /* See also i810_translate_vertex. SUBPIXEL adjustments can be done * via state vars, too. */ m[MAT_SX] = v[MAT_SX]; m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; m[MAT_SY] = - v[MAT_SY]; m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y; m[MAT_SZ] = v[MAT_SZ] * (1.0 / 0xffff); m[MAT_TZ] = v[MAT_TZ] * (1.0 / 0xffff); }
static void i810FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); GLuint vertsize = imesa->vertex_size; GLuint *vb = i810AllocDmaLow( imesa, (n-2) * 3 * 4 * vertsize ); GLubyte *vertptr = (GLubyte *)imesa->verts; const GLuint *start = (const GLuint *)V(elts[0]); int i,j; for (i = 2 ; i < n ; i++) { COPY_DWORDS( j, vb, vertsize, V(elts[i-1]) ); COPY_DWORDS( j, vb, vertsize, V(elts[i]) ); COPY_DWORDS( j, vb, vertsize, start ); } }
void i810BuildVertices( GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); GLuint stride = imesa->vertex_size * sizeof(int); GLubyte *v = ((GLubyte *)imesa->verts + (start * stride)); if (0) fprintf(stderr, "%s\n", __FUNCTION__); newinputs |= imesa->SetupNewInputs; imesa->SetupNewInputs = 0; if (!newinputs) return; if (newinputs & VERT_BIT_POS) { setup_tab[imesa->SetupIndex].emit( ctx, start, count, v, stride ); } else { GLuint ind = 0; if (newinputs & VERT_BIT_COLOR0) ind |= I810_RGBA_BIT; if (newinputs & VERT_BIT_COLOR1) ind |= I810_SPEC_BIT; if (newinputs & VERT_BIT_TEX0) ind |= I810_TEX0_BIT; if (newinputs & VERT_BIT_TEX1) ind |= I810_TEX1_BIT; if (newinputs & VERT_BIT_FOG) ind |= I810_FOG_BIT; if (imesa->SetupIndex & I810_PTEX_BIT) ind = ~0; ind &= imesa->SetupIndex; if (ind) { setup_tab[ind].emit( ctx, start, count, v, stride ); } } }
static void i810TexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { i810ContextPtr imesa = I810_CONTEXT( ctx ); GLuint unit = ctx->Texture.CurrentUnit; /* Only one env color. Need a fallback if env colors are different * and texture setup references env color in both units. */ switch (pname) { case GL_TEXTURE_ENV_COLOR: { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLfloat *fc = texUnit->EnvColor; GLuint r, g, b, a, col; CLAMPED_FLOAT_TO_UBYTE(r, fc[0]); CLAMPED_FLOAT_TO_UBYTE(g, fc[1]); CLAMPED_FLOAT_TO_UBYTE(b, fc[2]); CLAMPED_FLOAT_TO_UBYTE(a, fc[3]); col = ((a << 24) | (r << 16) | (g << 8) | (b << 0)); if (imesa->Setup[I810_CTXREG_CF1] != col) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_CF1] = col; } break; } case GL_TEXTURE_ENV_MODE: imesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */ break; case GL_TEXTURE_LOD_BIAS_EXT: { struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; t->Setup[I810_TEXREG_MLC] &= ~(MLC_LOD_BIAS_MASK); t->Setup[I810_TEXREG_MLC] |= i810ComputeLodBias(*param); } break; default: break; } }
/* ============================================================= * Polygon stipple * * The i810 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */ static void i810PolygonStipple( struct gl_context *ctx, const GLubyte *mask ) { i810ContextPtr imesa = I810_CONTEXT(ctx); const GLubyte *m = mask; GLubyte p[4]; int i,j,k; int active = (ctx->Polygon.StippleFlag && imesa->reduced_primitive == GL_TRIANGLES); GLuint newMask; if (active) { I810_STATECHANGE(imesa, I810_UPLOAD_CTX); imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; } 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 = 0 ; j < 4; j++) for (i = 0 ; i < 4 ; i++) if (*m++ != p[j]) { imesa->stipple_in_hw = 0; return; } newMask = ((p[0] & 0xf) << 0) | ((p[1] & 0xf) << 4) | ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12); if (newMask == 0xffff) { /* this is needed to make conform pass */ imesa->stipple_in_hw = 0; return; } imesa->Setup[I810_CTXREG_ST1] &= ~0xffff; imesa->Setup[I810_CTXREG_ST1] |= newMask; imesa->stipple_in_hw = 1; if (active) imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; }