diff options
Diffstat (limited to 'xc/lib/GL/mesa/src/drv/r128/r128_state.c')
-rw-r--r-- | xc/lib/GL/mesa/src/drv/r128/r128_state.c | 845 |
1 files changed, 549 insertions, 296 deletions
diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c index 8517960f9..55ab014a7 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -42,69 +42,41 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_cce.h" #include "r128_tris.h" #include "r128_vb.h" +#include "r128_tex.h" -#if 0 -/* FIXME: FOR TESTING A SIMPLE DRAWING FUNCTION */ -static void pfunc(GLcontext *ctx, GLuint first, GLuint last) {} -static void lfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv) {} -static void tfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint pv) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - unsigned char *R128MMIO = r128ctx->r128Screen->mmio; - float h = r128ctx->driDrawable->h; - - if (r128ctx->dirty) { - R128_DEBUG(("Rendering with a dirty context: %08x\n", r128ctx->dirty)); - /* r128UpdateState(r128ctx); */ - } - - R128CCE_BEGIN(15); - R128CCE3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 13); - R128CCE(R128_CCE_VC_FRMT_DIFFUSE_ARGB); - R128CCE(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST | - R128_CCE_VC_CNTL_PRIM_WALK_RING | - (3 << R128_CCE_VC_CNTL_NUM_SHIFT)); - - R128CCEF(ctx->VB->Win.data[v1][0]); - R128CCEF(h-ctx->VB->Win.data[v1][1]); - R128CCEF(ctx->VB->Win.data[v1][2]); - R128CCE((ctx->VB->Color[0]->data[v1][2] << 0) | - (ctx->VB->Color[0]->data[v1][1] << 8) | - (ctx->VB->Color[0]->data[v1][0] << 16) | - (ctx->VB->Color[0]->data[v1][3] << 24)); - - R128CCEF(ctx->VB->Win.data[v2][0]); - R128CCEF(h-ctx->VB->Win.data[v2][1]); - R128CCEF(ctx->VB->Win.data[v2][2]); - R128CCE((ctx->VB->Color[0]->data[v2][2] << 0) | - (ctx->VB->Color[0]->data[v2][1] << 8) | - (ctx->VB->Color[0]->data[v2][0] << 16) | - (ctx->VB->Color[0]->data[v2][3] << 24)); - - R128CCEF(ctx->VB->Win.data[v3][0]); - R128CCEF(h-ctx->VB->Win.data[v3][1]); - R128CCEF(ctx->VB->Win.data[v3][2]); - R128CCE((ctx->VB->Color[0]->data[v3][2] << 0) | - (ctx->VB->Color[0]->data[v3][1] << 8) | - (ctx->VB->Color[0]->data[v3][0] << 16) | - (ctx->VB->Color[0]->data[v3][3] << 24)); - - R128CCE_END(); -} -static void qfunc(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4, GLuint pv) +CARD32 r128PackColor(GLuint d, + GLubyte r, GLubyte g, GLubyte b, GLubyte a) { - tfunc(ctx, v1, v2, v4, pv); - tfunc(ctx, v2, v3, v4, pv); -} + switch (d) { + case 8: + return (((r & 0xe0) >> 0) | + ((g & 0xe0) >> 3) | + ((b & 0xc0) >> 6) | + ((a & 0x00) >> 0)); + case 15: + return (((r & 0xf8) << 7) | + ((g & 0xf8) << 2) | + ((b & 0xf8) >> 3) | + ((a & 0x80) << 8)); + case 16: + return (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3) | + ((a & 0x00) << 0)); + case 24: + return (((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) >> 0) | + ((a & 0x00) << 0)); + case 32: + return (((r & 0xff) << 16) | + ((g & 0xff) << 8) | + ((b & 0xff) >> 0) | + ((a & 0xff) << 24)); + } -static void r128DDUpdateState(GLcontext *ctx) -{ - ctx->Driver.PointsFunc = pfunc; - ctx->Driver.LineFunc = lfunc; - ctx->Driver.TriangleFunc = tfunc; - ctx->Driver.QuadFunc = qfunc; + return 0; } -#else #define INTERESTED (~(NEW_MODELVIEW | \ NEW_PROJECTION | \ @@ -133,7 +105,6 @@ static void r128DDUpdateState(GLcontext *ctx) ctx->Driver.RectFunc = NULL; } } -#endif static void r128DDUpdateHWState(GLcontext *ctx) { @@ -141,7 +112,16 @@ static void r128DDUpdateHWState(GLcontext *ctx) /* FIXME: state is being updated too often */ if (r128ctx->dirty) - r128UpdateState(r128ctx); + r128UpdateHWState(r128ctx); +} + +static void r128DDReducedPrimitiveChange(GLcontext *ctx, GLenum prim) +{ + r128ContextPtr r128ctx = R128_CONTEXT(ctx); + + /* FIXME: Also need to flush between tris and tristrips/fans when we + support them directly */ + R128_FLUSH_VB(r128ctx); } static void r128DDClearColor(GLcontext *ctx, @@ -149,10 +129,7 @@ static void r128DDClearColor(GLcontext *ctx, { r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128ctx->ClearColor = (((r >> 0) << 16) | - ((g >> 0) << 8) | - ((b >> 0) << 0) | - ((a >> 0) << 24)); + r128ctx->ClearColor = r128PackColor(32, r, g, b, a); } static void r128DDColor(GLcontext *ctx, @@ -160,25 +137,19 @@ static void r128DDColor(GLcontext *ctx, { r128ContextPtr r128ctx = R128_CONTEXT(ctx); -#if 1 - r128ctx->regs.constant_color_c = (((r >> 3) << 11) | - ((g >> 2) << 5) | - ((b >> 3) << 0) | - ((a >> 8) << 16)); -#else - r128ctx->regs.constant_color_c = (((r >> 0) << 16) | - ((g >> 0) << 8) | - ((b >> 0) << 0) | - ((a >> 0) << 24)); -#endif + r128ctx->Color = r128PackColor(r128ctx->r128Screen->depth, r, g, b, a); } -static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode ) +/* FIXME: After moving to Mesa 3.3, change this to SetReadBuffer and + SetDrawBuffer */ +static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode) { r128ContextPtr r128ctx = R128_CONTEXT(ctx); - int found = GL_FALSE; int x = r128ctx->driDrawable->x; int y = r128ctx->driDrawable->y; + int found; + + r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; switch (mode) { case GL_FRONT_LEFT: @@ -191,11 +162,18 @@ static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode ) r128ctx->bufY = r128ctx->r128Screen->backY; found = GL_TRUE; break; + default: + r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; } x += r128ctx->bufX; y += r128ctx->bufY; +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | (x << R128_WINDOW_X_SHIFT)); @@ -208,6 +186,9 @@ static GLboolean r128DDSetBuffer(GLcontext *ctx, GLenum mode ) (r128ctx->r128Screen->depthY - r128ctx->bufY) * r128ctx->r128Screen->fbStride); + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; return found; } @@ -215,7 +196,9 @@ static GLboolean r128DDColorMask(GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - /* FIXME??? */ + /* FIXME: Implement this function. Make sure the fallbacks are + covered if they do not properly handle individual color channel + masking. */ return GL_TRUE; } @@ -242,10 +225,16 @@ static void r128DDAlphaFunc(GLcontext *ctx, GLenum func, GLclampf ref) return; } - r128ctx->regs.misc_3d_state_cntl_reg = a; + if (r128ctx->regs.misc_3d_state_cntl_reg != a) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.misc_3d_state_cntl_reg = a; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALPHASTATE; + } } static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) @@ -275,7 +264,9 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) case GL_SRC_ALPHA_SATURATE: b |= R128_ALPHA_BLEND_SRC_SRCALPHASAT; break; #if 0 - /* FIXME */ + /* FIXME: These are not supported directly by the Rage 128. + They could be emulated using something like the TexEnv + modes. */ case GL_CONSTANT_COLOR: b |= 0; break; case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; @@ -308,7 +299,9 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) case GL_ONE_MINUS_DST_ALPHA: b |= R128_ALPHA_BLEND_DST_INVDESTALPHA; break; #if 0 - /* FIXME */ + /* FIXME: These are not supported directly by the Rage 128. + They could be emulated using something like the TexEnv + modes. */ case GL_CONSTANT_COLOR: b |= 0; break; case GL_ONE_MINUS_CONSTANT_COLOR: b |= 0; @@ -323,10 +316,16 @@ static void r128DDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor) return; } - r128ctx->regs.misc_3d_state_cntl_reg = b; + if (r128ctx->regs.misc_3d_state_cntl_reg != b) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.misc_3d_state_cntl_reg = b; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALPHASTATE; + } } static void r128DDBlendFuncSeparate(GLcontext *ctx, GLenum sfactorRGB, @@ -346,16 +345,10 @@ static void r128DDClearDepth(GLcontext *ctx, GLclampd d) r128ContextPtr r128ctx = R128_CONTEXT(ctx); switch (r128ctx->regs.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK) { - case R128_Z_PIX_WIDTH_16: - r128ctx->ClearDepth = d * 0x0000ffff; - break; - case R128_Z_PIX_WIDTH_24: - r128ctx->ClearDepth = d * 0x00ffffff; - break; - case R128_Z_PIX_WIDTH_32: - default: - r128ctx->ClearDepth = d * 0xffffffff; - break; + case R128_Z_PIX_WIDTH_16: r128ctx->ClearDepth = d * 0x0000ffff; break; + case R128_Z_PIX_WIDTH_24: r128ctx->ClearDepth = d * 0x00ffffff; break; + case R128_Z_PIX_WIDTH_32: r128ctx->ClearDepth = d * 0xffffffff; break; + default: return; } } @@ -375,10 +368,16 @@ static void r128DDCullFace(GLcontext *ctx, GLenum mode) default: return; } - r128ctx->regs.pm4_vc_fpu_setup = f; + if (r128ctx->regs.pm4_vc_fpu_setup != f) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.pm4_vc_fpu_setup = f; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + } } static void r128DDFrontFace(GLcontext *ctx, GLenum mode) @@ -394,10 +393,16 @@ static void r128DDFrontFace(GLcontext *ctx, GLenum mode) default: return; } - r128ctx->regs.pm4_vc_fpu_setup = f; + if (r128ctx->regs.pm4_vc_fpu_setup != f) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.pm4_vc_fpu_setup = f; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; + } } static void r128DDDepthFunc(GLcontext *ctx, GLenum func) @@ -419,20 +424,36 @@ static void r128DDDepthFunc(GLcontext *ctx, GLenum func) default: return; } - r128ctx->regs.z_sten_cntl_c = z; + if (r128ctx->regs.z_sten_cntl_c != z) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.z_sten_cntl_c = z; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ZSTENSTATE; + } } static void r128DDDepthMask(GLcontext *ctx, GLboolean flag) { r128ContextPtr r128ctx = R128_CONTEXT(ctx); - if (flag) r128ctx->regs.tex_cntl_c |= R128_Z_WRITE_ENABLE; - else r128ctx->regs.tex_cntl_c &= ~R128_Z_WRITE_ENABLE; + CARD32 t = r128ctx->regs.tex_cntl_c; - /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + if (flag) t |= R128_Z_WRITE_ENABLE; + else t &= ~R128_Z_WRITE_ENABLE; + + if (r128ctx->regs.tex_cntl_c != t) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif + r128ctx->regs.tex_cntl_c = t; + + /* FIXME: Load into hardware now??? */ + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ENGINESTATE; + } } static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) @@ -442,7 +463,6 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) CARD32 f = r128ctx->regs.pm4_vc_fpu_setup; switch (cap) { -#if 0 case GL_ALPHA_TEST: if (state) t |= R128_ALPHA_TEST_ENABLE; else t &= ~R128_ALPHA_TEST_ENABLE; @@ -462,7 +482,6 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_CLIP_PLANE4: case GL_CLIP_PLANE5: case GL_COLOR_MATERIAL: return; -#endif case GL_CULL_FACE: f &= ~(R128_BACKFACE_MASK | R128_FRONTFACE_MASK); @@ -478,20 +497,21 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) } break; -#if 1 case GL_DEPTH_TEST: if (state) t |= R128_Z_ENABLE; else t &= ~R128_Z_ENABLE; break; -#endif #if 0 + /* FIXME */ case GL_DITHER: return; + /* FIXME */ case GL_FOG: if (state) t |= R128_FOG_ENABLE; else t &= ~R128_FOG_ENABLE; break; +#endif case GL_LIGHT0: case GL_LIGHT1: @@ -531,15 +551,32 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_LINE: case GL_POLYGON_OFFSET_FILL: +#if 0 + /* FIXME: Are there others in Mesa 3.3 that we need to add? */ case GL_RESCALE_NORMAL_EXT: +#endif case GL_SCISSOR_TEST: +#if 0 + /* FIXME: Are there others in Mesa 3.3 that we need to add? */ case GL_SHARED_TEXTURE_PALETTE_EXT: +#endif case GL_STENCIL_TEST: case GL_TEXTURE_1D: return; case GL_TEXTURE_2D: - if (state) t |= R128_TEXMAP_ENABLE; - else t &= ~R128_TEXMAP_ENABLE; + switch (ctx->Texture.CurrentUnit) { + case 0: + if (state) t |= R128_TEXMAP_ENABLE; + else t &= ~R128_TEXMAP_ENABLE; + break; + case 1: + if (state) t |= R128_SEC_TEXMAP_ENABLE; + else t &= ~R128_SEC_TEXMAP_ENABLE; + break; + default: + return; + } + r128ctx->dirty |= R128_UPDATE_TEXSTATE; break; case GL_TEXTURE_3D: @@ -555,22 +592,29 @@ static void r128DDEnable(GLcontext *ctx, GLenum cap, GLboolean state) case GL_INDEX_ARRAY: case GL_TEXTURE_COORD_ARRAY: case GL_EDGE_FLAG_ARRAY: return; -#endif default: return; } - if (t != r128ctx->regs.tex_cntl_c) { + if (r128ctx->regs.tex_cntl_c != t) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif r128ctx->regs.tex_cntl_c = t; /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ENGINESTATE; } - if (f != r128ctx->regs.pm4_vc_fpu_setup) { + if (r128ctx->regs.pm4_vc_fpu_setup != f) { +#if FLUSH_VB_ON_STATE_CHANGE + R128_FLUSH_VB(r128ctx); +#endif r128ctx->regs.pm4_vc_fpu_setup = f; /* FIXME: Load into hardware now??? */ - r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_SETUPSTATE; } } @@ -581,6 +625,7 @@ static void r128DDScissor(GLcontext *ctx, /* FIXME */ } +/* Initialize the driver's state functions */ void r128DDInitStateFuncs(GLcontext *ctx) { ctx->Driver.UpdateState = r128DDUpdateState; @@ -606,7 +651,7 @@ void r128DDInitStateFuncs(GLcontext *ctx) ctx->Driver.RenderVBCulledTab = NULL; ctx->Driver.RenderVBRawTab = NULL; - ctx->Driver.ReducedPrimitiveChange = NULL; + ctx->Driver.ReducedPrimitiveChange = r128DDReducedPrimitiveChange; ctx->Driver.MultipassFunc = NULL; ctx->Driver.AlphaFunc = r128DDAlphaFunc; @@ -635,9 +680,11 @@ void r128DDInitStateFuncs(GLcontext *ctx) ctx->Driver.Viewport = NULL; } +/* Initialize the context's hardware state */ void r128DDInitState(r128ContextPtr r128ctx) { - int dst_bpp, pitch; + int dst_bpp, depth_bpp, pitch, i; + CARD32 depthClear; pitch = r128ctx->r128Screen->fbStride / r128ctx->r128Screen->bpp; @@ -658,6 +705,33 @@ void r128DDInitState(r128ContextPtr r128ctx) break; } + switch ( +#if 0 + /* FIXME: Figure out how to use 16bpp depth buffer in 32bpp mode */ + r128ctx->glCtx->Visual->DepthBits +#else + r128ctx->r128Screen->bpp +#endif + ) { + case 16: + depthClear = 0x0000ffff; + depth_bpp = R128_Z_PIX_WIDTH_16; + break; + case 24: + depthClear = 0x00ffffff; + depth_bpp = R128_Z_PIX_WIDTH_24; + break; + case 32: + depthClear = 0xffffffff; + depth_bpp = R128_Z_PIX_WIDTH_32; + break; + default: + /* FIXME: This is an error */ + depthClear = 0x00000000; + depth_bpp = R128_Z_PIX_WIDTH_16; + break; + } + r128ctx->dirty = R128_CLEAN; r128ctx->needClip = GL_FALSE; @@ -679,37 +753,38 @@ void r128DDInitState(r128ContextPtr r128ctx) } r128ctx->ClearColor = 0x00000000; - r128ctx->ClearDepth = 0x0000ffff; /* FIXME: init to requested depth */ + r128ctx->ClearDepth = depthClear; r128ctx->regs.scale_3d_cntl = - R128_SCALE_DITHER_ERR_DIFF | - R128_TEX_CACHE_SIZE_FULL | - R128_DITHER_INIT_RESET | - R128_SCALE_3D_TEXMAP_SHADE | - R128_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_TABLE | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | - R128_ALPHA_TEST_ALWAYS | + R128_SCALE_DITHER_ERR_DIFF | + R128_TEX_CACHE_SIZE_FULL | + R128_DITHER_INIT_RESET | + R128_SCALE_3D_TEXMAP_SHADE | + R128_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_TABLE | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS | R128_COMPOSITE_SHADOW_CMP_EQUAL | - R128_TEX_MAP_ALPHA_IN_TEXTURE | + R128_TEX_MAP_ALPHA_IN_TEXTURE | R128_TEX_CACHE_LINE_SIZE_8QW; r128ctx->regs.dst_pitch_offset_c = pitch << R128_PITCH_SHIFT; r128ctx->regs.dp_gui_master_cntl = R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_BRUSH_SOLID_COLOR | - dst_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_GMC_BYTE_MSB_TO_LSB | - R128_GMC_CONVERSION_TEMP_6500 | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_3D_FCN_EN | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_AUX_CLIP_DIS | + R128_GMC_DST_CLIPPING | + R128_GMC_BRUSH_SOLID_COLOR | + dst_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_GMC_BYTE_MSB_TO_LSB | + R128_GMC_CONVERSION_TEMP_6500 | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_3D_FCN_EN | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS; r128ctx->regs.sc_top_left_c = 0x00000000; @@ -721,28 +796,29 @@ void r128DDInitState(r128ContextPtr r128ctx) r128ctx->regs.z_pitch_c = pitch; r128ctx->regs.z_sten_cntl_c = - R128_Z_PIX_WIDTH_16 | - R128_Z_TEST_LESS | + depth_bpp | + R128_Z_TEST_LESS | R128_STENCIL_TEST_ALWAYS | R128_STENCIL_S_FAIL_KEEP | - R128_STENCIL_ZPASS_KEEP | + R128_STENCIL_ZPASS_KEEP | R128_STENCIL_ZFAIL_KEEP; r128ctx->regs.tex_cntl_c = - R128_Z_WRITE_ENABLE | - R128_SHADE_ENABLE | + R128_Z_WRITE_ENABLE | + R128_SHADE_ENABLE | R128_ALPHA_IN_TEX_COMPLETE_A | - R128_LIGHT_DIS | - R128_ALPHA_LIGHT_DIS | + R128_LIGHT_DIS | + R128_ALPHA_LIGHT_DIS | + R128_TEX_CACHE_FLUSH | (0x0f << R128_LOD_BIAS_SHIFT); r128ctx->regs.misc_3d_state_cntl_reg = R128_MISC_SCALE_3D_TEXMAP_SHADE | - R128_MISC_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_TABLE | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | + R128_MISC_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_TABLE | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | R128_ALPHA_TEST_ALWAYS; r128ctx->regs.texture_clr_cmp_clr_c = 0x00000000; @@ -752,62 +828,44 @@ void r128DDInitState(r128ContextPtr r128ctx) r128ctx->regs.prim_tex_cntl_c = R128_MIN_BLEND_NEAREST | R128_MAG_BLEND_NEAREST | - R128_MIP_MAP_DISABLE | - R128_TEX_CLAMP_S_WRAP | + R128_MIP_MAP_DISABLE | + R128_TEX_CLAMP_S_WRAP | R128_TEX_CLAMP_T_WRAP; r128ctx->regs.prim_texture_combine_cntl_c = - R128_COMB_MODULATE | - R128_COLOR_FACTOR_TEX | + R128_COMB_MODULATE | + R128_COLOR_FACTOR_TEX | R128_INPUT_FACTOR_INT_COLOR | - R128_COMB_ALPHA_COPY | + R128_COMB_ALPHA_COPY | R128_ALPHA_FACTOR_TEX_ALPHA | R128_INP_FACTOR_A_INT_ALPHA; r128ctx->regs.tex_size_pitch_c = - (0 << R128_TEX_PITCH_SHIFT) | - (0 << R128_TEX_SIZE_SHIFT) | - (0 << R128_TEX_HEIGHT_SHIFT) | - (0 << R128_TEX_MIN_SIZE_SHIFT) | - (0 << R128_SEC_TEX_PITCH_SHIFT) | - (0 << R128_SEC_TEX_SIZE_SHIFT) | + (0 << R128_TEX_PITCH_SHIFT) | + (0 << R128_TEX_SIZE_SHIFT) | + (0 << R128_TEX_HEIGHT_SHIFT) | + (0 << R128_TEX_MIN_SIZE_SHIFT) | + (0 << R128_SEC_TEX_PITCH_SHIFT) | + (0 << R128_SEC_TEX_SIZE_SHIFT) | (0 << R128_SEC_TEX_HEIGHT_SHIFT) | (0 << R128_SEC_TEX_MIN_SIZE_SHIFT); - r128ctx->regs.prim_tex_0_offset_c = 0x00000000; - r128ctx->regs.prim_tex_1_offset_c = 0x00000000; - r128ctx->regs.prim_tex_2_offset_c = 0x00000000; - r128ctx->regs.prim_tex_3_offset_c = 0x00000000; - r128ctx->regs.prim_tex_4_offset_c = 0x00000000; - r128ctx->regs.prim_tex_5_offset_c = 0x00000000; - r128ctx->regs.prim_tex_6_offset_c = 0x00000000; - r128ctx->regs.prim_tex_7_offset_c = 0x00000000; - r128ctx->regs.prim_tex_8_offset_c = 0x00000000; - r128ctx->regs.prim_tex_9_offset_c = 0x00000000; - r128ctx->regs.prim_tex_10_offset_c = 0x00000000; + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.prim_tex_offset[i] = 0x00000000; r128ctx->regs.sec_tex_cntl_c = R128_SEC_SELECT_PRIM_ST; r128ctx->regs.sec_tex_combine_cntl_c = - R128_COMB_DIS | - R128_COLOR_FACTOR_TEX | + R128_COMB_DIS | + R128_COLOR_FACTOR_TEX | R128_INPUT_FACTOR_PREV_COLOR | - R128_COMB_ALPHA_DIS | - R128_ALPHA_FACTOR_TEX_ALPHA | + R128_COMB_ALPHA_DIS | + R128_ALPHA_FACTOR_TEX_ALPHA | R128_INP_FACTOR_A_PREV_ALPHA; - r128ctx->regs.sec_tex_0_offset_c = 0x00000000; - r128ctx->regs.sec_tex_1_offset_c = 0x00000000; - r128ctx->regs.sec_tex_2_offset_c = 0x00000000; - r128ctx->regs.sec_tex_3_offset_c = 0x00000000; - r128ctx->regs.sec_tex_4_offset_c = 0x00000000; - r128ctx->regs.sec_tex_5_offset_c = 0x00000000; - r128ctx->regs.sec_tex_6_offset_c = 0x00000000; - r128ctx->regs.sec_tex_7_offset_c = 0x00000000; - r128ctx->regs.sec_tex_8_offset_c = 0x00000000; - r128ctx->regs.sec_tex_9_offset_c = 0x00000000; - r128ctx->regs.sec_tex_10_offset_c = 0x00000000; + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + r128ctx->regs.sec_tex_offset[i] = 0x00000000; r128ctx->regs.constant_color_c = 0x00ffffff; r128ctx->regs.prim_texture_border_color_c = 0x00ffffff; @@ -816,26 +874,32 @@ void r128DDInitState(r128ContextPtr r128ctx) r128ctx->regs.plane_3d_mask_c = 0xffffffff; r128ctx->regs.setup_cntl = - R128_COLOR_GOURAUD | - R128_PRIM_TYPE_TRI | - R128_TEXTURE_ST_MULT_W | - R128_STARTING_VERTEX_1 | - R128_ENDING_VERTEX_3 | + R128_COLOR_GOURAUD | + R128_PRIM_TYPE_TRI | +#if 1 + /* FIXME: Let r128 multiply? */ + R128_TEXTURE_ST_MULT_W | +#else + /* FIXME: Or, pre multiply? */ + R128_TEXTURE_ST_DIRECT | +#endif + R128_STARTING_VERTEX_1 | + R128_ENDING_VERTEX_3 | R128_SU_POLY_LINE_NOT_LAST | R128_SUB_PIX_4BITS; r128ctx->regs.pm4_vc_fpu_setup = - R128_FRONT_DIR_CCW | - R128_BACKFACE_SOLID | - R128_FRONTFACE_SOLID | - R128_FPU_COLOR_GOURAUD | - R128_FPU_SUB_PIX_4BITS | - R128_FPU_MODE_3D | - R128_TRAP_BITS_DISABLE | - R128_XFACTOR_2 | - R128_YFACTOR_2 | + R128_FRONT_DIR_CCW | + R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID | + R128_FPU_COLOR_GOURAUD | + R128_FPU_SUB_PIX_4BITS | + R128_FPU_MODE_3D | + R128_TRAP_BITS_DISABLE | + R128_XFACTOR_2 | + R128_YFACTOR_2 | R128_FLAT_SHADE_VERTEX_OGL | - R128_FPU_ROUND_TRUNCATE | + R128_FPU_ROUND_TRUNCATE | R128_WM_SEL_8DW; r128ctx->regs.fog_3d_table_start = 0x00000000; @@ -845,105 +909,209 @@ void r128DDInitState(r128ContextPtr r128ctx) r128ctx->regs.window_xy_offset = 0x00000000; r128ctx->regs.dp_write_mask = 0xffffffff; + + r128ctx->regs.pc_gui_ctlstat = R128_PC_FLUSH_GUI; + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_ALL_DIRTY; } -/* This is only called when we have the lock */ +/* Load the current context's state into the hardware */ +/* NOTE: This function is only called while holding the hardware lock */ static void r128LoadContext(r128ContextPtr r128ctx) { unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + int i; + int tex_size_pitch_done = GL_FALSE; - R128CCE_BEGIN_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_SCALE_3D_CNTL, 0); - R128CCE(r128ctx->regs.scale_3d_cntl); - - R128CCE_WAIT_LOCKED(27); - R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 25); - R128CCE(r128ctx->regs.dst_pitch_offset_c); - R128CCE(r128ctx->regs.dp_gui_master_cntl); - R128CCE(r128ctx->regs.sc_top_left_c); - R128CCE(r128ctx->regs.sc_bottom_right_c); - R128CCE(r128ctx->regs.z_offset_c); - R128CCE(r128ctx->regs.z_pitch_c); - R128CCE(r128ctx->regs.z_sten_cntl_c); - R128CCE(r128ctx->regs.tex_cntl_c); - R128CCE(r128ctx->regs.misc_3d_state_cntl_reg); - R128CCE(r128ctx->regs.texture_clr_cmp_clr_c); - R128CCE(r128ctx->regs.texture_clr_cmp_msk_c); - R128CCE(r128ctx->regs.fog_color_c); - R128CCE(r128ctx->regs.prim_tex_cntl_c); - R128CCE(r128ctx->regs.prim_texture_combine_cntl_c); - R128CCE(r128ctx->regs.tex_size_pitch_c); - R128CCE(r128ctx->regs.prim_tex_0_offset_c); - R128CCE(r128ctx->regs.prim_tex_1_offset_c); - R128CCE(r128ctx->regs.prim_tex_2_offset_c); - R128CCE(r128ctx->regs.prim_tex_3_offset_c); - R128CCE(r128ctx->regs.prim_tex_4_offset_c); - R128CCE(r128ctx->regs.prim_tex_5_offset_c); - R128CCE(r128ctx->regs.prim_tex_6_offset_c); - R128CCE(r128ctx->regs.prim_tex_7_offset_c); - R128CCE(r128ctx->regs.prim_tex_8_offset_c); - R128CCE(r128ctx->regs.prim_tex_9_offset_c); - R128CCE(r128ctx->regs.prim_tex_10_offset_c); - - R128CCE_WAIT_LOCKED(19); - R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 17); - R128CCE(r128ctx->regs.sec_tex_cntl_c); - R128CCE(r128ctx->regs.sec_tex_combine_cntl_c); - R128CCE(r128ctx->regs.sec_tex_0_offset_c); - R128CCE(r128ctx->regs.sec_tex_1_offset_c); - R128CCE(r128ctx->regs.sec_tex_2_offset_c); - R128CCE(r128ctx->regs.sec_tex_3_offset_c); - R128CCE(r128ctx->regs.sec_tex_4_offset_c); - R128CCE(r128ctx->regs.sec_tex_5_offset_c); - R128CCE(r128ctx->regs.sec_tex_6_offset_c); - R128CCE(r128ctx->regs.sec_tex_7_offset_c); - R128CCE(r128ctx->regs.sec_tex_8_offset_c); - R128CCE(r128ctx->regs.sec_tex_9_offset_c); - R128CCE(r128ctx->regs.sec_tex_10_offset_c); - R128CCE(r128ctx->regs.constant_color_c); - R128CCE(r128ctx->regs.prim_texture_border_color_c); - R128CCE(r128ctx->regs.sec_texture_border_color_c); - R128CCE(r128ctx->regs.sten_ref_mask_c); - R128CCE(r128ctx->regs.plane_3d_mask_c); - - R128CCE_WAIT_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_SETUP_CNTL, 0); - R128CCE(r128ctx->regs.setup_cntl); - - R128CCE_WAIT_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_PM4_VC_FPU_SETUP, 0); - R128CCE(r128ctx->regs.pm4_vc_fpu_setup); +#if 0 + r128ctx->dirty_context = R128_ALL_DIRTY; +#endif - R128CCE_WAIT_LOCKED(3); - R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1); - R128CCE(r128ctx->regs.fog_3d_table_start); - R128CCE(r128ctx->regs.fog_3d_table_end); +#if 1 + /* FIXME: Why do these need to be updated even when they don't change? */ + r128ctx->dirty_context |= (R128_CTX_MISC | + R128_CTX_ENGINESTATE | + R128_CTX_ALPHASTATE); +#endif + +#if 1 + /* FIXME: Is this _really_ needed? */ + if (r128ctx->dirty_context) R128CCEWaitForIdle(r128ctx->r128Screen); +#endif + +#if !FLUSH_VB_ON_STATE_CHANGE + /* FIXME: It might make sense to do this here instead of flushing + immediately in each state setting routine. */ + /* FIXME: Is this _really_ necessary? It slows down rendering, and + it seems like state changes shouldn't take effect until after the + VB has completed rendering. */ + if (r128ctx->dirty_context) R128_FLUSH_VB(r128ctx); +#endif + + if (r128ctx->dirty_context & R128_CTX_MISC) { + R128CCE_WAIT_LOCKED(3); + R128CCE1(R128_CCE_PACKET1, R128_SCALE_3D_CNTL, R128_DP_WRITE_MASK); + R128CCE(r128ctx->regs.scale_3d_cntl); + R128CCE(r128ctx->regs.dp_write_mask); + + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_DST_PITCH_OFFSET_C, 1); + R128CCE(r128ctx->regs.dst_pitch_offset_c); + R128CCE(r128ctx->regs.dp_gui_master_cntl); + + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_TEXTURE_CLR_CMP_CLR_C, 1); + R128CCE(r128ctx->regs.texture_clr_cmp_clr_c); + R128CCE(r128ctx->regs.texture_clr_cmp_msk_c); + + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_STEN_REF_MASK_C, 1); + R128CCE(r128ctx->regs.sten_ref_mask_c); + R128CCE(r128ctx->regs.plane_3d_mask_c); + } + + if (r128ctx->dirty_context & R128_CTX_ENGINESTATE) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_TEX_CNTL_C, 0); + R128CCE(r128ctx->regs.tex_cntl_c); + } - R128CCE_WAIT_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_DENSITY, 0); - R128CCE(r128ctx->regs.fog_3d_table_density); + if (r128ctx->dirty_context & R128_CTX_TEX0STATE) { + R128CCE_WAIT_LOCKED(4+R128_TEX_MAXLEVELS); + R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEX_CNTL_C, 2+R128_TEX_MAXLEVELS); + R128CCE(r128ctx->regs.prim_tex_cntl_c); + R128CCE(r128ctx->regs.prim_texture_combine_cntl_c); + R128CCE(r128ctx->regs.tex_size_pitch_c); + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + R128CCE(r128ctx->regs.prim_tex_offset[i]); - R128CCE_WAIT_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0); - R128CCE(r128ctx->regs.window_xy_offset); + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_PRIM_TEXTURE_BORDER_COLOR_C, 0); + R128CCE(r128ctx->regs.prim_texture_border_color_c); - R128CCE_WAIT_LOCKED(2); - R128CCE0(R128_CCE_PACKET0, R128_DP_WRITE_MASK, 0); - R128CCE(r128ctx->regs.dp_write_mask); + tex_size_pitch_done = GL_TRUE; + } + + if (r128ctx->dirty_context & R128_CTX_TEX1STATE) { + if (!tex_size_pitch_done) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_TEX_SIZE_PITCH_C, 0); + R128CCE(r128ctx->regs.tex_size_pitch_c); + } + + R128CCE_WAIT_LOCKED(3+R128_TEX_MAXLEVELS); + R128CCE0(R128_CCE_PACKET0, R128_SEC_TEX_CNTL_C, 1+R128_TEX_MAXLEVELS); + R128CCE(r128ctx->regs.sec_tex_cntl_c); + R128CCE(r128ctx->regs.sec_tex_combine_cntl_c); + for (i = 0; i < R128_TEX_MAXLEVELS; i++) + R128CCE(r128ctx->regs.sec_tex_offset[i]); + + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_SEC_TEXTURE_BORDER_COLOR_C, 0); + R128CCE(r128ctx->regs.sec_texture_border_color_c); + + } + + if (r128ctx->dirty_context & R128_CTX_TEXENVSTATE) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_CONSTANT_COLOR_C, 0); + R128CCE(r128ctx->regs.constant_color_c); + } + + if (r128ctx->dirty_context & R128_CTX_FOGSTATE) { + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_FOG_3D_TABLE_START, 1); + R128CCE(r128ctx->regs.fog_3d_table_start); + R128CCE(r128ctx->regs.fog_3d_table_end); + + R128CCE_WAIT_LOCKED(3); + R128CCE1(R128_CCE_PACKET1, + R128_FOG_COLOR_C, R128_FOG_3D_TABLE_DENSITY); + R128CCE(r128ctx->regs.fog_color_c); + R128CCE(r128ctx->regs.fog_3d_table_density); + } + + if (r128ctx->dirty_context & R128_CTX_ZSTENSTATE) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_Z_STEN_CNTL_C, 0); + R128CCE(r128ctx->regs.z_sten_cntl_c); + } + + if (r128ctx->dirty_context & R128_CTX_SCISSORS) { + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1); + R128CCE(r128ctx->regs.sc_top_left_c); + R128CCE(r128ctx->regs.sc_bottom_right_c); + } + + if (r128ctx->dirty_context & (R128_CTX_ALPHASTATE | + R128_CTX_FOGSTATE)) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_MISC_3D_STATE_CNTL_REG, 0); + R128CCE(r128ctx->regs.misc_3d_state_cntl_reg); + } + + if (r128ctx->dirty_context & R128_CTX_SETUPSTATE) { + R128CCE_WAIT_LOCKED(3); + R128CCE1(R128_CCE_PACKET1, R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP); + R128CCE(r128ctx->regs.setup_cntl); + R128CCE(r128ctx->regs.pm4_vc_fpu_setup); + } + + if (r128ctx->dirty_context & R128_CTX_WIN_Z_POS) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_WINDOW_XY_OFFSET, 0); + R128CCE(r128ctx->regs.window_xy_offset); + + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_Z_OFFSET_C, 1); + R128CCE(r128ctx->regs.z_offset_c); + R128CCE(r128ctx->regs.z_pitch_c); + } + + if (r128ctx->dirty_context & R128_CTX_FLUSH_PIX_CACHE) { + R128CCE_WAIT_LOCKED(2); + R128CCE0(R128_CCE_PACKET0, R128_PC_GUI_CTLSTAT, 0); + R128CCE(r128ctx->regs.pc_gui_ctlstat); + } R128CCE_END_LOCKED(); + + /* Turn off the texture cache flushing */ + r128ctx->regs.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + + /* Turn off the pixel cache flushing */ + r128ctx->regs.pc_gui_ctlstat &= ~R128_PC_FLUSH_ALL; + + r128ctx->dirty_context = R128_CTX_CLEAN; } -/* This is only called when we have the lock */ +/* Set a hardware clip rect for drawing to the current color buffer */ +/* NOTE: This function is only called while holding the hardware lock */ void r128SetClipRect(r128ContextPtr r128ctx, XF86DRIClipRectPtr pc) { + unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + + /* FIXME: Use the Rage 128's multiple clip rects */ + R128CCE_WAIT_LOCKED(3); + R128CCE0(R128_CCE_PACKET0, R128_SC_TOP_LEFT_C, 1); + R128CCE(((pc->y1 + r128ctx->bufY) << 16)|(pc->x1 + r128ctx->bufX)); + R128CCE(((pc->y2 + r128ctx->bufY - 1) << 16)|(pc->x2 + r128ctx->bufX - 1)); + R128CCE_END_LOCKED(); } -static void r128LoadCliprects(r128ContextPtr r128ctx) +/* Update the driver's notion of the window position */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateWindowPosition(r128ContextPtr r128ctx) { int x = r128ctx->driDrawable->x + r128ctx->bufX; int y = r128ctx->driDrawable->y + r128ctx->bufY; +#if 0 + /* FIXME: This happens during a lock, but is it _really_ needed? */ + R128_FLUSH_VB(r128ctx); +#endif r128ctx->regs.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | (x << R128_WINDOW_X_SHIFT)); @@ -956,24 +1124,109 @@ static void r128LoadCliprects(r128ContextPtr r128ctx) (r128ctx->r128Screen->depthY - r128ctx->bufY) * r128ctx->r128Screen->fbStride); + + r128ctx->dirty |= R128_UPDATE_CONTEXT; + r128ctx->dirty_context |= R128_CTX_WIN_Z_POS; + + r128ctx->needClip = (r128ctx->driDrawable->numClipRects > 1); } -void r128UpdateState(r128ContextPtr r128ctx) +/* Update the hardware state */ +/* NOTE: This function is only called while holding the hardware lock */ +static void r128UpdateHWStateLocked(r128ContextPtr r128ctx) +{ + r128ScreenPtr r128Screen = r128ctx->r128Screen; + + if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE) + R128WaitForIdle(r128Screen); + + /* Update any state that might have changed recently */ + + /* Update the clip rects */ + if (r128ctx->dirty & R128_UPDATE_WINPOS) + r128UpdateWindowPosition(r128ctx); + + /* Update texture state and then upload the images */ + /* Note: Texture images can only be updated after the state has been set */ + if (r128ctx->dirty & R128_UPDATE_TEXSTATE) + r128UpdateTextureState(r128ctx); + if (r128ctx->dirty & R128_UPDATE_TEX0IMAGES) + r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[0]); + if (r128ctx->dirty & R128_UPDATE_TEX1IMAGES) + r128UploadTexImages(r128ctx, r128ctx->CurrentTexObj[1]); + + /* Load the state into the hardware */ + /* Note: This must be done after all other state has been set */ + if (r128ctx->dirty & R128_UPDATE_CONTEXT) + r128LoadContext(r128ctx); + + r128ctx->dirty = R128_CLEAN; +} + +/* Update the hardware state */ +void r128UpdateHWState(r128ContextPtr r128ctx) { LOCK_HARDWARE(r128ctx); - r128UpdateStateLocked(r128ctx); + r128UpdateHWStateLocked(r128ctx); UNLOCK_HARDWARE(r128ctx); } -/* This is only called when we have the lock */ -void r128UpdateStateLocked(r128ContextPtr r128ctx) +/* Update the driver's state */ +/* NOTE: This function is only called while holding the hardware lock */ +void r128UpdateState(r128ContextPtr r128ctx, int winMoved) { - r128ScreenPtr r128Screen = r128ctx->r128Screen; + if (r128ctx->SAREA->ctxOwner != r128ctx->driContext->hHWContext) { + r128ctx->SAREA->ctxOwner = r128ctx->driContext->hHWContext; + r128ctx->dirty |= R128_ALL_DIRTY; + } - if (r128ctx->dirty & R128_REQUIRE_QUIESCENCE) R128WaitForIdle(r128Screen); - if (r128ctx->dirty & R128_START_CCE) R128CCEStart(r128Screen); - if (r128ctx->dirty & R128_UPDATE_CLIPRECTS) r128LoadCliprects(r128ctx); - if (r128ctx->dirty & R128_UPDATE_CONTEXT) r128LoadContext(r128ctx); + if (r128ctx->SAREA->texAge != r128ctx->lastTexAge) { +#if USE_AGP_TEXTURES + int sz = 1 << r128ctx->r128Screen->log2AGPTexGran; +#else + int sz = 1 << r128ctx->r128Screen->log2TexGran; +#endif + int nr = 0; + int idx; + + for (idx = r128ctx->SAREA->texList[R128_NR_TEX_REGIONS].prev; + idx != R128_NR_TEX_REGIONS && nr < R128_NR_TEX_REGIONS; + idx = r128ctx->SAREA->texList[idx].prev, nr++) { + + /* If switching texturing schemes, then the SAREA might not + have been properly cleared, so we need to reset the + global texture LRU. */ +#if USE_AGP_TEXTURES + if (idx * sz > r128ctx->r128Screen->agpTexSize) { +#else + if (idx * sz > r128ctx->r128Screen->textureSize) { +#endif + nr = R128_NR_TEX_REGIONS; + break; + } - r128ctx->dirty = R128_CLEAN; + if (r128ctx->SAREA->texList[idx].age > r128ctx->lastTexAge) + r128TexturesGone(r128ctx, idx * sz, sz, + r128ctx->SAREA->texList[idx].in_use); + } + + if (nr == R128_NR_TEX_REGIONS) { +#if USE_AGP_TEXTURES + r128TexturesGone(r128ctx, 0, r128ctx->r128Screen->agpTexSize, 0); +#else + r128TexturesGone(r128ctx, 0, r128ctx->r128Screen->textureSize, 0); +#endif + r128ResetGlobalLRU(r128ctx); + } + + r128ctx->dirty |= R128_UPDATE_TEX0IMAGES; + r128ctx->dirty |= R128_UPDATE_TEX1IMAGES; + r128ctx->lastTexAge = r128ctx->SAREA->texAge; + } + + if (winMoved) { /* FIXME??: handle window moves */ + r128ctx->dirty |= R128_UPDATE_WINPOS; + } + + if (r128ctx->dirty) r128UpdateHWStateLocked(r128ctx); } |