summaryrefslogtreecommitdiff
path: root/xc/lib/GL/mesa/src/drv/r128/r128_state.c
diff options
context:
space:
mode:
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.c845
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);
}