diff options
author | Alan Hourihane <[email protected]> | 2003-09-30 10:54:15 +0000 |
---|---|---|
committer | Alan Hourihane <[email protected]> | 2003-09-30 10:54:15 +0000 |
commit | 73b0420bba16b5dcfbb75b32bc519295f925041a (patch) | |
tree | ead492c4189053125e161564ba849891cbcc1822 /src/mesa/drivers/dri/i810/i810state.c | |
parent | 5b5142b54376493081835cb2b4836b81a652cb36 (diff) |
add the i810 driver - no kernel driver yet
(build tested, but not physically tested)
Diffstat (limited to 'src/mesa/drivers/dri/i810/i810state.c')
-rw-r--r-- | src/mesa/drivers/dri/i810/i810state.c | 1019 |
1 files changed, 1019 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c new file mode 100644 index 00000000000..23432b2c072 --- /dev/null +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -0,0 +1,1019 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */ + +#include <stdio.h> + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "enums.h" +#include "dd.h" +#include "colormac.h" + +#include "texmem.h" + +#include "i810screen.h" +#include "i810_dri.h" + +#include "i810context.h" +#include "i810state.h" +#include "i810tex.h" +#include "i810vb.h" +#include "i810tris.h" +#include "i810ioctl.h" + +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +static __inline__ GLuint i810PackColor(GLuint format, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a) +{ + + if (I810_DEBUG&DEBUG_DRI) + fprintf(stderr, "%s\n", __FUNCTION__); + + switch (format) { + case DV_PF_555: + return PACK_COLOR_1555( a, r, g, b ); + case DV_PF_565: + return PACK_COLOR_565( r, g, b ); + default: + fprintf(stderr, "unknown format %d\n", (int)format); + return 0; + } +} + + +static void i810AlphaFunc(GLcontext *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 i810BlendEquation(GLcontext *ctx, GLenum mode) +{ + /* Can only do GL_ADD equation in hardware */ + FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ, mode != GL_FUNC_ADD_EXT); + + /* BlendEquation sets ColorLogicOpEnabled in an unexpected + * manner. + */ + FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); +} + +static void i810BlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) +{ + 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; + } +} + + +/* Shouldn't be called as the extension is disabled. + */ +static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, + GLenum dfactorA ) +{ + if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)"); + } + + i810BlendFunc( ctx, sfactorRGB, dfactorRGB ); +} + + + +static void i810DepthFunc(GLcontext *ctx, GLenum func) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + int zmode; + + switch(func) { + case GL_NEVER: zmode = LCS_Z_NEVER; break; + case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break; + case GL_LESS: zmode = LCS_Z_LESS; break; + case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break; + case GL_EQUAL: zmode = LCS_Z_EQUAL; break; + case GL_GREATER: zmode = LCS_Z_GREATER; break; + case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break; + case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break; + default: return; + } + + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK; + imesa->Setup[I810_CTXREG_LCS] |= zmode; +} + +static void i810DepthMask(GLcontext *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; +} + + +/* ============================================================= + * Polygon stipple + * + * The i810 supports a 4x4 stipple natively, GL wants 32x32. + * Fortunately stipple is usually a repeating pattern. + */ +static void i810PolygonStipple( GLcontext *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; +} + + + +/* ============================================================= + * Hardware clipping + */ + + +static void i810Scissor( GLcontext *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 i810LogicOp( GLcontext *ctx, GLenum opcode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) ); +} + +/* Fallback to swrast for select and feedback. + */ +static void i810RenderMode( GLcontext *ctx, GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) ); +} + + +void i810DrawBuffer(GLcontext *ctx, GLenum mode ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + int front = 0; + + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + front=1; + break; + case BACK_LEFT_BIT: + front = 0; + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + if ( imesa->sarea->pf_current_page == 1 ) + front ^= 1; + + FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE ); + I810_FIREVERTICES(imesa); + I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS); + + if (front) + { + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset | + imesa->i810Screen->backPitchBits); + i810XMesaSetFrontClipRects( imesa ); + } + else + { + imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset | + imesa->i810Screen->backPitchBits); + i810XMesaSetBackClipRects( imesa ); + } + + /* We want to update the s/w rast state too so that r200SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); +} + + +static void i810ReadBuffer(GLcontext *ctx, GLenum mode ) +{ + /* XXX anything? */ +} + + +static void i810ClearColor(GLcontext *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] ); +} + + +/* ============================================================= + * Culling - the i810 isn't quite as clean here as the rest of + * its interfaces, but it's not bad. + */ +static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + GLuint mode = LCS_CULL_BOTH; + + if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) { + mode = LCS_CULL_CW; + if (ctx->Polygon.CullFaceMode == GL_FRONT) + mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); + if (ctx->Polygon.FrontFace != GL_CCW) + mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW); + } + + imesa->LcsCullMode = mode; + + if (ctx->Polygon.CullFlag) + { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; + imesa->Setup[I810_CTXREG_LCS] |= mode; + } +} + + +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 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; + } +} + +/* ============================================================= + * Color masks + */ + +static void i810ColorMask(GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + i810ContextPtr imesa = I810_CONTEXT( ctx ); + GLuint tmp = 0; + + if (r && g && b) { + tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE; + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); + } else if (!r && !g && !b) { + tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE; + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE ); + } else { + FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE ); + return; + } + + if (tmp != imesa->Setup[I810_CTXREG_B2]) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B2] = tmp; + imesa->dirty |= I810_UPLOAD_CTX; + } +} + +/* Seperate specular not fully implemented on the i810. + */ +static void i810LightModelfv(GLcontext *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)); + } +} + +/* But the 815 has it... + */ +static void i810LightModelfv_i815(GLcontext *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; + } +} + +/* In Mesa 3.5 we can reliably do native flatshading. + */ +static void i810ShadeModel(GLcontext *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; +} + + + +/* ============================================================= + * Fog + */ +static void i810Fogfv(GLcontext *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); + } +} + + +/* ============================================================= + */ +static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + + switch(cap) { + case GL_ALPHA_TEST: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE; + break; + case GL_BLEND: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE; + + /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. + */ + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + break; + case GL_DEPTH_TEST: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE; + break; + case GL_SCISSOR_TEST: + /* XXX without these next two lines, conform's scissor test fails */ + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS); + I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */ + imesa->upload_cliprects = GL_TRUE; + imesa->scissor = state; + break; + case GL_POLYGON_STIPPLE: + if (imesa->stipple_in_hw && imesa->reduced_primitive == GL_TRIANGLES) + { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE; + } + break; + case GL_LINE_SMOOTH: + /* Need to fatten the lines by .5, or they disappear... + */ + if (imesa->reduced_primitive == GL_LINES) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (state) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + } + break; + case GL_POINT_SMOOTH: + if (imesa->reduced_primitive == GL_POINTS) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5; + if (state) { + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5; + } + } + break; + case GL_POLYGON_SMOOTH: + if (imesa->reduced_primitive == GL_TRIANGLES) { + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE; + } + break; + case GL_FOG: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE; + break; + case GL_CULL_FACE: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK; + if (state) + imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode; + else + imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE; + break; + case GL_TEXTURE_2D: + I810_STATECHANGE(imesa, I810_UPLOAD_CTX); + if (ctx->Texture.CurrentUnit == 0) { + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE; + } else { + imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE; + if (state) + imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE; + } + break; + case GL_COLOR_LOGIC_OP: + FALLBACK( imesa, I810_FALLBACK_LOGICOP, + (state && ctx->Color.LogicOp != GL_COPY)); + break; + case GL_STENCIL_TEST: + FALLBACK( imesa, I810_FALLBACK_STENCIL, state ); + break; + default: + ; + } +} + + + + + + + +/* ============================================================= + */ + + + + +void i810EmitDrawingRectangle( i810ContextPtr imesa ) +{ + __DRIdrawablePrivate *dPriv = imesa->driDrawable; + i810ScreenPrivate *i810Screen = imesa->i810Screen; + int x0 = imesa->drawX; + int y0 = imesa->drawY; + int x1 = x0 + dPriv->w; + int y1 = y0 + dPriv->h; + GLuint dr2, dr3, dr4; + + + /* Coordinate origin of the window - may be offscreen. + */ + dr4 = imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) | + (((unsigned)x0)&0xFFFF)); + + /* Clip to screen. + */ + if (x0 < 0) x0 = 0; + if (y0 < 0) y0 = 0; + if (x1 > i810Screen->width-1) x1 = i810Screen->width-1; + if (y1 > i810Screen->height-1) y1 = i810Screen->height-1; + + + /* Onscreen drawing rectangle. + */ + dr2 = imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0); + dr3 = imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1)); + + + imesa->dirty |= I810_UPLOAD_BUFFERS; +} + + + +static void i810CalcViewport( GLcontext *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 i810Viewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + i810CalcViewport( ctx ); +} + +static void i810DepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + i810CalcViewport( ctx ); +} + + + +void i810PrintDirty( const char *msg, GLuint state ) +{ + fprintf(stderr, "%s (0x%x): %s%s%s%s\n", + msg, + (unsigned int) state, + (state & I810_UPLOAD_TEX0) ? "upload-tex0, " : "", + (state & I810_UPLOAD_TEX1) ? "upload-tex1, " : "", + (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "", + (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : "" + ); +} + + + +void i810InitState( GLcontext *ctx ) +{ + i810ContextPtr imesa = I810_CONTEXT(ctx); + i810ScreenPrivate *i810Screen = imesa->i810Screen; + + memset(imesa->Setup, 0, sizeof(imesa->Setup)); + + imesa->Setup[I810_CTXREG_VF] = 0; + + imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS | + MT_UPDATE_TEXEL1_STATE | + MT_TEXEL1_COORD1 | + MT_TEXEL1_MAP1 | + MT_TEXEL1_DISABLE | + MT_UPDATE_TEXEL0_STATE | + MT_TEXEL0_COORD0 | + MT_TEXEL0_MAP0 | + MT_TEXEL0_DISABLE); + + imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_0 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ITERATED_COLOR | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_ARG1 ); + + imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_1 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_ONE | + MC_ARG1_DONT_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); + + + imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES | + MC_STAGE_2 | + MC_UPDATE_DEST | + MC_DEST_CURRENT | + MC_UPDATE_ARG1 | + MC_ARG1_CURRENT_COLOR | + MC_ARG1_REPLICATE_ALPHA | + MC_ARG1_DONT_INVERT | + MC_UPDATE_ARG2 | + MC_ARG2_ONE | + MC_ARG2_DONT_REPLICATE_ALPHA | + MC_ARG2_DONT_INVERT | + MC_UPDATE_OP | + MC_OP_DISABLE ); + + + imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_0 | + MA_UPDATE_ARG1 | + MA_ARG1_ITERATED_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_1 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES | + MA_STAGE_2 | + MA_UPDATE_ARG1 | + MA_ARG1_CURRENT_ALPHA | + MA_ARG1_DONT_INVERT | + MA_UPDATE_ARG2 | + MA_ARG2_CURRENT_ALPHA | + MA_ARG2_DONT_INVERT | + MA_UPDATE_OP | + MA_OP_ARG1 ); + + + imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO | + SDM_UPDATE_MONO_ENABLE | + 0 | + SDM_UPDATE_SRC_BLEND | + SDM_SRC_ONE | + SDM_UPDATE_DST_BLEND | + SDM_DST_ZERO ); + + /* Use for colormask: + */ + imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR; + imesa->Setup[I810_CTXREG_CF1] = 0xffffffff; + + imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC | + ZA_UPDATE_ALPHAFUNC | + ZA_ALPHA_ALWAYS | + ZA_UPDATE_ZBIAS | + 0 | + ZA_UPDATE_ALPHAREF | + 0x0); + + imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR | + (0xffffff & ~FOG_RESERVED_MASK)); + + /* Choose a pipe + */ + imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 | + B1_UPDATE_SPEC_SETUP_ENABLE | + 0 | + B1_UPDATE_ALPHA_SETUP_ENABLE | + B1_ALPHA_SETUP_ENABLE | + B1_UPDATE_CI_KEY_ENABLE | + 0 | + B1_UPDATE_CHROMAKEY_ENABLE | + 0 | + B1_UPDATE_Z_BIAS_ENABLE | + 0 | + B1_UPDATE_SPEC_ENABLE | + 0 | + B1_UPDATE_FOG_ENABLE | + 0 | + B1_UPDATE_ALPHA_TEST_ENABLE | + 0 | + B1_UPDATE_BLEND_ENABLE | + 0 | + B1_UPDATE_Z_TEST_ENABLE | + 0 ); + + imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 | + B2_UPDATE_MAP_CACHE_ENABLE | + B2_MAP_CACHE_ENABLE | + B2_UPDATE_ALPHA_DITHER_ENABLE | + 0 | + B2_UPDATE_FOG_DITHER_ENABLE | + 0 | + B2_UPDATE_SPEC_DITHER_ENABLE | + 0 | + B2_UPDATE_RGB_DITHER_ENABLE | + B2_RGB_DITHER_ENABLE | + B2_UPDATE_FB_WRITE_ENABLE | + B2_FB_WRITE_ENABLE | + B2_UPDATE_ZB_WRITE_ENABLE | + B2_ZB_WRITE_ENABLE ); + + imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE | + LCS_UPDATE_ZMODE | + LCS_Z_LESS | + LCS_UPDATE_LINEWIDTH | + LCS_LINEWIDTH_1_0 | + LCS_UPDATE_ALPHA_INTERP | + LCS_ALPHA_INTERP | + LCS_UPDATE_FOG_INTERP | + 0 | + LCS_UPDATE_SPEC_INTERP | + 0 | + LCS_UPDATE_RGB_INTERP | + LCS_RGB_INTERP | + LCS_UPDATE_CULL_MODE | + LCS_CULL_DISABLE); + + imesa->LcsCullMode = LCS_CULL_CW; + imesa->LcsLineWidth = LCS_LINEWIDTH_1_0; + imesa->LcsPointSize = LCS_LINEWIDTH_1_0; + + imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE | + PV_UPDATE_PIXRULE | + PV_PIXRULE_ENABLE | + PV_UPDATE_LINELIST | + PV_LINELIST_PV1 | + PV_UPDATE_TRIFAN | + PV_TRIFAN_PV2 | + PV_UPDATE_TRISTRIP | + PV_TRISTRIP_PV2 ); + + + imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE; + imesa->Setup[I810_CTXREG_ST1] = 0; + + imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS | + AA_UPDATE_EDGEFLAG | + 0 | + AA_UPDATE_POLYWIDTH | + AA_POLYWIDTH_05 | + AA_UPDATE_LINEWIDTH | + AA_LINEWIDTH_05 | + AA_UPDATE_BB_EXPANSION | + 0 | + AA_UPDATE_AA_ENABLE | + 0 ); + + memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup)); + imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO; + + if (imesa->glCtx->Visual.doubleBufferMode && imesa->sarea->pf_current_page == 0) { + /* use back buffer by default */ + imesa->drawMap = i810Screen->back.map; + imesa->readMap = i810Screen->back.map; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset | + i810Screen->backPitchBits); + } else { + /* use front buffer by default */ + imesa->drawMap = (char *)imesa->driScreen->pFB; + imesa->readMap = (char *)imesa->driScreen->pFB; + imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset | + i810Screen->backPitchBits); + } + + imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS; + imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL | + DV_VORG_BIAS_OGL | + i810Screen->fbFormat); + + imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO; + imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE; +} + + +static void i810InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + I810_CONTEXT(ctx)->new_state |= new_state; +} + + +void i810InitStateFuncs(GLcontext *ctx) +{ + /* Callbacks for internal Mesa events. + */ + ctx->Driver.UpdateState = i810InvalidateState; + + /* API callbacks + */ + ctx->Driver.AlphaFunc = i810AlphaFunc; + ctx->Driver.BlendEquation = i810BlendEquation; + ctx->Driver.BlendFunc = i810BlendFunc; + 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; +} |