summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/mga/mgastate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/mga/mgastate.c')
-rw-r--r--src/mesa/drivers/dri/mga/mgastate.c1297
1 files changed, 722 insertions, 575 deletions
diff --git a/src/mesa/drivers/dri/mga/mgastate.c b/src/mesa/drivers/dri/mga/mgastate.c
index 02b98fdb766..0d304966d7e 100644
--- a/src/mesa/drivers/dri/mga/mgastate.c
+++ b/src/mesa/drivers/dri/mga/mgastate.c
@@ -26,9 +26,9 @@
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.13 2002/10/30 12:51:36 alanh Exp $ */
-#include <stdio.h>
#include "mtypes.h"
+#include "colormac.h"
#include "dd.h"
#include "mm.h"
@@ -40,19 +40,22 @@
#include "mgatris.h"
#include "mgaioctl.h"
#include "mgaregs.h"
-#include "mgabuffers.h"
#include "swrast/swrast.h"
#include "array_cache/acache.h"
#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
+static void updateSpecularLighting( GLcontext *ctx );
+
/* Some outstanding problems with accelerating logic ops...
*/
#if defined(ACCEL_ROP)
-static GLuint mgarop_NoBLK[16] = {
+static const GLuint mgarop_NoBLK[16] = {
DC_atype_rpl | 0x00000000, DC_atype_rstr | 0x00080000,
DC_atype_rstr | 0x00040000, DC_atype_rpl | 0x000c0000,
DC_atype_rstr | 0x00020000, DC_atype_rstr | 0x000a0000,
@@ -65,221 +68,57 @@ static GLuint mgarop_NoBLK[16] = {
#endif
-static void mgaUpdateStencil(const GLcontext *ctx)
-{
- mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- GLuint stencil = 0, stencilctl = 0;
-
- if (ctx->Stencil.Enabled)
- {
- stencil = ctx->Stencil.Ref[0] |
- ( ctx->Stencil.ValueMask[0] << 8 ) |
- ( ctx->Stencil.WriteMask[0] << 16 );
-
- switch (ctx->Stencil.Function[0])
- {
- case GL_NEVER:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_snever);
- break;
- case GL_LESS:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slt);
- break;
- case GL_LEQUAL:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_slte);
- break;
- case GL_GREATER:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgt);
- break;
- case GL_GEQUAL:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sgte);
- break;
- case GL_NOTEQUAL:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_sne);
- break;
- case GL_EQUAL:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_se);
- break;
- case GL_ALWAYS:
- MGA_SET_FIELD(stencilctl, SC_smode_MASK, SC_smode_salways);
- default:
- break;
- }
-
- switch (ctx->Stencil.FailFunc[0])
- {
- case GL_KEEP:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_keep);
- break;
- case GL_ZERO:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_zero);
- break;
- case GL_REPLACE:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_replace);
- break;
- case GL_INCR:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_incrsat);
- break;
- case GL_DECR:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_decrsat);
- break;
- case GL_INVERT:
- MGA_SET_FIELD(stencilctl, SC_sfailop_MASK, SC_sfailop_invert);
- break;
- default:
- break;
- }
-
- switch (ctx->Stencil.ZFailFunc[0])
- {
- case GL_KEEP:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_keep);
- break;
- case GL_ZERO:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_zero);
- break;
- case GL_REPLACE:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_replace);
- break;
- case GL_INCR:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_incrsat);
- break;
- case GL_DECR:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_decrsat);
- break;
- case GL_INVERT:
- MGA_SET_FIELD(stencilctl, SC_szfailop_MASK, SC_szfailop_invert);
- break;
- default:
- break;
- }
-
- switch (ctx->Stencil.ZPassFunc[0])
- {
- case GL_KEEP:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_keep);
- break;
- case GL_ZERO:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_zero);
- break;
- case GL_REPLACE:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_replace);
- break;
- case GL_INCR:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_incrsat);
- break;
- case GL_DECR:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_decrsat);
- break;
- case GL_INVERT:
- MGA_SET_FIELD(stencilctl, SC_szpassop_MASK, SC_szpassop_invert);
- break;
- default:
- break;
- }
- }
-
- mmesa->setup.stencil = stencil;
- mmesa->setup.stencilctl = stencilctl;
- mmesa->dirty |= MGA_UPLOAD_CONTEXT;
-}
-
-static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
- GLuint mask)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
-}
-
-static void mgaDDStencilMask(GLcontext *ctx, GLuint mask)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
-}
-
-static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
- GLenum zpass)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_STENCIL;
-}
+/* =============================================================
+ * Alpha blending
+ */
-static void mgaDDClearDepth(GLcontext *ctx, GLclampd d)
+static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLubyte refByte;
+ GLuint a;
- /* KW: should the ~ be there? */
- switch (mmesa->setup.maccess & ~MA_zwidth_MASK) {
- case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break;
- case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break;
- case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break;
- default: return;
- }
-}
-
-static void mgaUpdateZMode(const GLcontext *ctx)
-{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- int zmode = 0;
-
- if (ctx->Depth.Test) {
- switch(ctx->Depth.Func) {
- case GL_NEVER:
- /* can't do this in h/w, we'll use a s/w fallback */
- zmode = DC_zmode_nozcmp;
- break;
- case GL_ALWAYS:
- zmode = DC_zmode_nozcmp; break;
- case GL_LESS:
- zmode = DC_zmode_zlt; break;
- case GL_LEQUAL:
- zmode = DC_zmode_zlte; break;
- case GL_EQUAL:
- zmode = DC_zmode_ze; break;
- case GL_GREATER:
- zmode = DC_zmode_zgt; break;
- case GL_GEQUAL:
- zmode = DC_zmode_zgte; break;
- case GL_NOTEQUAL:
- zmode = DC_zmode_zne; break;
- default:
- break;
- }
+ CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
- if (ctx->Depth.Mask)
- zmode |= DC_atype_zi;
- else
- zmode |= DC_atype_i;
- }
- else {
- zmode |= DC_zmode_nozcmp;
- zmode |= DC_atype_i; /* don't write to zbuffer */
+ switch ( func ) {
+ case GL_NEVER:
+ a = AC_atmode_alt;
+ refByte = 0;
+ break;
+ case GL_LESS:
+ a = AC_atmode_alt;
+ break;
+ case GL_GEQUAL:
+ a = AC_atmode_agte;
+ break;
+ case GL_LEQUAL:
+ a = AC_atmode_alte;
+ break;
+ case GL_GREATER:
+ a = AC_atmode_agt;
+ break;
+ case GL_NOTEQUAL:
+ a = AC_atmode_ane;
+ break;
+ case GL_EQUAL:
+ a = AC_atmode_ae;
+ break;
+ case GL_ALWAYS:
+ a = AC_atmode_noacmp;
+ break;
+ default:
+ a = 0;
+ break;
}
-#if defined(ACCEL_ROP)
- mmesa->setup.dwgctl &= DC_bop_MASK;
- if (ctx->Color.ColorLogicOpEnabled)
- zmode |= mgarop_NoBLK[(ctx->Color.LogicOp)&0xf];
- else
- zmode |= mgarop_NoBLK[GL_COPY & 0xf];
-#endif
-
- mmesa->setup.dwgctl &= DC_zmode_MASK & DC_atype_MASK;
- mmesa->setup.dwgctl |= zmode;
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.alpha_func = a | MGA_FIELD( AC_atref, refByte );
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
-
-static void mgaDDAlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
-}
-
-
static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
{
FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
/* BlendEquation sets ColorLogicOpEnabled in an unexpected
* manner.
@@ -291,247 +130,169 @@ static void mgaDDBlendEquation(GLcontext *ctx, GLenum mode)
static void mgaDDBlendFunc(GLcontext *ctx, GLenum sfactor, GLenum dfactor)
{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
+ GLuint src;
+ GLuint dst;
+
+ switch (ctx->Color.BlendSrcRGB) {
+ case GL_ZERO:
+ src = AC_src_zero; break;
+ case GL_SRC_ALPHA:
+ src = AC_src_src_alpha; break;
+ case GL_ONE:
+ default: /* never happens */
+ src = AC_src_one; break;
+ case GL_DST_COLOR:
+ src = AC_src_dst_color; break;
+ case GL_ONE_MINUS_DST_COLOR:
+ src = AC_src_om_dst_color; break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ src = AC_src_om_src_alpha; break;
+ case GL_DST_ALPHA:
+ src = (mgaScreen->cpp == 4)
+ ? AC_src_dst_alpha : AC_src_one;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ src = (mgaScreen->cpp == 4)
+ ? AC_src_om_dst_alpha : AC_src_zero;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ src = (ctx->Visual.alphaBits > 0)
+ ? AC_src_src_alpha_sat : AC_src_zero;
+ break;
+ }
+
+ switch (ctx->Color.BlendDstRGB) {
+ case GL_SRC_ALPHA:
+ dst = AC_dst_src_alpha; break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ dst = AC_dst_om_src_alpha; break;
+ default: /* never happens */
+ case GL_ZERO:
+ dst = AC_dst_zero; break;
+ case GL_ONE:
+ dst = AC_dst_one; break;
+ case GL_SRC_COLOR:
+ dst = AC_dst_src_color; break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ dst = AC_dst_om_src_color; break;
+ case GL_DST_ALPHA:
+ dst = (mgaScreen->cpp == 4)
+ ? AC_dst_dst_alpha : AC_dst_one;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ dst = (mgaScreen->cpp == 4)
+ ? AC_dst_om_dst_alpha : AC_dst_zero;
+ break;
+ }
+
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.blend_func = (src | dst);
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
static void mgaDDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
GLenum dfactorRGB, GLenum sfactorA,
GLenum dfactorA )
{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_ALPHA;
+ mgaDDBlendFunc( ctx, sfactorRGB, dfactorRGB );
}
+/* =============================================================
+ * Depth testing
+ */
-static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
- const GLfloat *param)
+static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
{
- if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ int zmode;
+
+ switch (func) {
+ case GL_NEVER:
+ /* can't do this in h/w, we'll use a s/w fallback */
+ FALLBACK (ctx, MGA_FALLBACK_DEPTH, ctx->Depth.Test);
+
+ /* FALLTHROUGH */
+ case GL_ALWAYS:
+ zmode = DC_zmode_nozcmp; break;
+ case GL_LESS:
+ zmode = DC_zmode_zlt; break;
+ case GL_LEQUAL:
+ zmode = DC_zmode_zlte; break;
+ case GL_EQUAL:
+ zmode = DC_zmode_ze; break;
+ case GL_GREATER:
+ zmode = DC_zmode_zgt; break;
+ case GL_GEQUAL:
+ zmode = DC_zmode_zgte; break;
+ case GL_NOTEQUAL:
+ zmode = DC_zmode_zne; break;
+ default:
+ zmode = 0; break;
}
-}
-
-static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
-}
-
-
-static void mgaDDDepthFunc(GLcontext *ctx, GLenum func)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.zmode &= DC_zmode_MASK;
+ mmesa->hw.zmode |= zmode;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
static void mgaDDDepthMask(GLcontext *ctx, GLboolean flag)
{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
-}
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
-#if defined(ACCEL_ROP)
-static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_DEPTH;
-}
-#else
-static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
- (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
-}
-#endif
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.zmode &= DC_atype_MASK;
+ mmesa->hw.zmode |= (flag) ? DC_atype_zi : DC_atype_i;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
-static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
+static void mgaDDClearDepth(GLcontext *ctx, GLclampd d)
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- if (pname == GL_FOG_COLOR) {
- GLuint color = MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
- (GLubyte)(ctx->Fog.Color[1]*255.0F),
- (GLubyte)(ctx->Fog.Color[2]*255.0F));
-
- MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);
- mmesa->setup.fogcolor = color;
+ /* Select the Z depth. The ~ is used because the _MASK values in the
+ * MGA driver are used to mask OFF the selected bits. In this case,
+ * we want to mask off everything except the MA_zwidth bits.
+ */
+ switch (mmesa->setup.maccess & ~MA_zwidth_MASK) {
+ case MA_zwidth_16: mmesa->ClearDepth = d * 0x0000ffff; break;
+ case MA_zwidth_24: mmesa->ClearDepth = d * 0xffffff00; break;
+ case MA_zwidth_32: mmesa->ClearDepth = d * 0xffffffff; break;
+ default: return;
}
}
-
-
/* =============================================================
- * Alpha blending
+ * Fog
*/
-static void mgaUpdateAlphaMode(GLcontext *ctx)
+static void mgaDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
- int a = 0;
-
- /* determine source of alpha for blending and testing */
- if ( !ctx->Texture.Unit[0]._ReallyEnabled ) {
- a |= AC_alphasel_diffused;
- }
- else {
- /* G400: Regardless of texture env mode, we use the alpha from the
- * texture unit (AC_alphasel_fromtex) since it will have already
- * been modulated by the incoming fragment color, if needed.
- * We don't want (AC_alphasel_modulate) since that'll effectively
- * do the modulation twice.
- */
- if (MGA_IS_G400(mmesa)) {
- a |= AC_alphasel_fromtex;
- }
- else {
- /* G200 */
- switch (ctx->Texture.Unit[0].EnvMode) {
- case GL_DECAL:
- a |= AC_alphasel_diffused;
- case GL_REPLACE:
- a |= AC_alphasel_fromtex;
- break;
- case GL_BLEND:
- case GL_MODULATE:
- a |= AC_alphasel_modulated;
- break;
- default:
- break;
- }
- }
- }
-
-
- /* alpha test control.
- */
- if (ctx->Color.AlphaEnabled) {
- GLubyte ref = ctx->Color.AlphaRef;
- switch (ctx->Color.AlphaFunc) {
- case GL_NEVER:
- a |= AC_atmode_alt;
- ref = 0;
- break;
- case GL_LESS:
- a |= AC_atmode_alt;
- break;
- case GL_GEQUAL:
- a |= AC_atmode_agte;
- break;
- case GL_LEQUAL:
- a |= AC_atmode_alte;
- break;
- case GL_GREATER:
- a |= AC_atmode_agt;
- break;
- case GL_NOTEQUAL:
- a |= AC_atmode_ane;
- break;
- case GL_EQUAL:
- a |= AC_atmode_ae;
- break;
- case GL_ALWAYS:
- a |= AC_atmode_noacmp;
- break;
- default:
- break;
- }
- a |= MGA_FIELD(AC_atref,ref);
- }
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- /* blending control */
- if (ctx->Color.BlendEnabled) {
- switch (ctx->Color.BlendSrcRGB) {
- case GL_ZERO:
- a |= AC_src_zero; break;
- case GL_SRC_ALPHA:
- a |= AC_src_src_alpha; break;
- case GL_ONE:
- a |= AC_src_one; break;
- case GL_DST_COLOR:
- a |= AC_src_dst_color; break;
- case GL_ONE_MINUS_DST_COLOR:
- a |= AC_src_om_dst_color; break;
- case GL_ONE_MINUS_SRC_ALPHA:
- a |= AC_src_om_src_alpha; break;
- case GL_DST_ALPHA:
- if (mgaScreen->cpp == 4)
- a |= AC_src_dst_alpha;
- else
- a |= AC_src_one;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- if (mgaScreen->cpp == 4)
- a |= AC_src_om_dst_alpha;
- else
- a |= AC_src_zero;
- break;
- case GL_SRC_ALPHA_SATURATE:
- if (ctx->Visual.alphaBits > 0)
- a |= AC_src_src_alpha_sat;
- else
- a |= AC_src_zero;
- break;
- default: /* never happens */
- break;
- }
+ if (pname == GL_FOG_COLOR) {
+ GLuint color = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
+ (GLubyte)(ctx->Fog.Color[1]*255.0F),
+ (GLubyte)(ctx->Fog.Color[2]*255.0F));
- switch (ctx->Color.BlendDstRGB) {
- case GL_SRC_ALPHA:
- a |= AC_dst_src_alpha; break;
- case GL_ONE_MINUS_SRC_ALPHA:
- a |= AC_dst_om_src_alpha; break;
- case GL_ZERO:
- a |= AC_dst_zero; break;
- case GL_ONE:
- a |= AC_dst_one; break;
- case GL_SRC_COLOR:
- a |= AC_dst_src_color; break;
- case GL_ONE_MINUS_SRC_COLOR:
- a |= AC_dst_om_src_color; break;
- case GL_DST_ALPHA:
- if (mgaScreen->cpp == 4)
- a |= AC_dst_dst_alpha;
- else
- a |= AC_dst_one;
- break;
- case GL_ONE_MINUS_DST_ALPHA:
- if (mgaScreen->cpp == 4)
- a |= AC_dst_om_dst_alpha;
- else
- a |= AC_dst_zero;
- break;
- default: /* never happens */
- break;
- }
- } else {
- a |= AC_src_one|AC_dst_zero;
+ MGA_STATECHANGE(mmesa, MGA_UPLOAD_CONTEXT);
+ mmesa->setup.fogcolor = color;
}
-
- mmesa->setup.alphactrl = (AC_amode_alpha_channel |
- AC_astipple_disable |
- AC_aten_disable |
- AC_atmode_noacmp |
- a);
-
- mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
-
/* =============================================================
- * Hardware clipping
+ * Scissoring
*/
+
void mgaUpdateClipping(const GLcontext *ctx)
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
@@ -554,13 +315,6 @@ void mgaUpdateClipping(const GLcontext *ctx)
mmesa->scissor_rect.x2 = x2;
mmesa->scissor_rect.y2 = y2;
- if (MGA_DEBUG&DEBUG_VERBOSE_2D)
- fprintf(stderr, "SET SCISSOR %d,%d-%d,%d\n",
- mmesa->scissor_rect.x1,
- mmesa->scissor_rect.y1,
- mmesa->scissor_rect.x2,
- mmesa->scissor_rect.y2);
-
mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}
}
@@ -569,19 +323,10 @@ void mgaUpdateClipping(const GLcontext *ctx)
static void mgaDDScissor( GLcontext *ctx, GLint x, GLint y,
GLsizei w, GLsizei h )
{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CLIP;
-}
-
-
-static void mgaDDClearColor(GLcontext *ctx,
- const GLfloat color[4] )
-{
- mgaContextPtr mmesa = MGA_CONTEXT(ctx);
-
- mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
- color[0], color[1],
- color[2], color[3]);
+ if ( ctx->Scissor.Enabled ) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) ); /* don't pipeline cliprect changes */
+ mgaUpdateClipping( ctx );
+ }
}
@@ -589,46 +334,42 @@ static void mgaDDClearColor(GLcontext *ctx,
* Culling
*/
+
#define _CULL_DISABLE 0
#define _CULL_NEGATIVE ((1<<11)|(1<<5)|(1<<16))
#define _CULL_POSITIVE (1<<11)
-
-void mgaUpdateCull( GLcontext *ctx )
+static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- GLuint mode = _CULL_DISABLE;
+
+ FLUSH_BATCH( mmesa );
if (ctx->Polygon.CullFlag &&
- mmesa->raster_primitive == GL_TRIANGLES &&
ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
{
- mode = _CULL_NEGATIVE;
+ mmesa->hw.cull = _CULL_NEGATIVE;
+
if (ctx->Polygon.CullFaceMode == GL_FRONT)
- mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
+ mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
+
if (ctx->Polygon.FrontFace != GL_CCW)
- mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
- if ((ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_2D_BIT) &&
- (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_2D_BIT))
- mode ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
+ mmesa->hw.cull ^= (_CULL_POSITIVE ^ _CULL_NEGATIVE);
+
+ mmesa->hw.cull_dualtex = mmesa->hw.cull ^
+ (_CULL_POSITIVE ^ _CULL_NEGATIVE); /* warp bug? */
+ }
+ else {
+ mmesa->hw.cull = _CULL_DISABLE;
+ mmesa->hw.cull_dualtex = _CULL_DISABLE;
}
- mmesa->setup.wflag = mode;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
-static void mgaDDCullFaceFrontFace(GLcontext *ctx, GLenum mode)
-{
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_CULL;
-}
-
-
-
-
/* =============================================================
- * Color masks
+ * Masks
*/
static void mgaDDColorMask(GLcontext *ctx,
@@ -654,15 +395,11 @@ static void mgaDDColorMask(GLcontext *ctx,
}
}
+
/* =============================================================
- * Polygon stipple
- *
- * The mga supports a subset of possible 4x4 stipples natively, GL
- * wants 32x32. Fortunately stipple is usually a repeating pattern.
- *
- * Note: the fully opaque pattern (0xffff) has been disabled in order
- * to work around a conformance issue.
+ * Polygon state
*/
+
static int mgaStipples[16] = {
0xffff1, /* See above note */
0xa5a5,
@@ -682,6 +419,17 @@ static int mgaStipples[16] = {
0x0000
};
+/**
+ * The MGA supports a subset of possible 4x4 stipples natively, GL
+ * wants 32x32. Fortunately stipple is usually a repeating pattern.
+ *
+ * \param ctx GL rendering context to be affected
+ * \param mask Pointer to the 32x32 stipple mask
+ *
+ * \note the fully opaque pattern (0xffff) has been disabled in order
+ * to work around a conformance issue.
+ */
+
static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
{
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
@@ -730,93 +478,216 @@ static void mgaDDPolygonStipple( GLcontext *ctx, const GLubyte *mask )
}
}
+
/* =============================================================
+ * Rendering attributes
+ *
+ * We really don't want to recalculate all this every time we bind a
+ * texture. These things shouldn't change all that often, so it makes
+ * sense to break them out of the core texture state update routines.
*/
-static void mgaDDPrintDirty( const char *msg, GLuint state )
+static void updateSpecularLighting( GLcontext *ctx )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s%s\n",
- msg,
- (unsigned int) state,
- (state & MGA_WAIT_AGE) ? "wait-age, " : "",
- (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img, " : "",
- (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img, " : "",
- (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx, " : "",
- (state & MGA_UPLOAD_TEX0) ? "upload-tex0, " : "",
- (state & MGA_UPLOAD_TEX1) ? "upload-tex1, " : "",
- (state & MGA_UPLOAD_PIPE) ? "upload-pipe, " : ""
- );
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ unsigned int specen;
+
+ specen = (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
+ ctx->Light.Enabled) ? TMC_specen_enable : 0;
+
+ if ( specen != mmesa->hw.specen ) {
+ mmesa->hw.specen = specen;
+ mmesa->dirty |= MGA_UPLOAD_TEX0 | MGA_UPLOAD_TEX1;
+
+ mgaChooseVertexState( ctx );
+ }
}
-/* Push the state into the sarea and/or texture memory.
+
+/* =============================================================
+ * Materials
*/
-void mgaEmitHwStateLocked( mgaContextPtr mmesa )
-{
- MGASAREAPrivPtr sarea = mmesa->sarea;
- if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
- mgaDDPrintDirty( "mgaEmitHwStateLocked", mmesa->dirty );
- if ((mmesa->dirty & MGA_UPLOAD_TEX0IMAGE) && mmesa->CurrentTexObj[0])
- mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[0]);
+static void mgaDDLightModelfv(GLcontext *ctx, GLenum pname,
+ const GLfloat *param)
+{
+ if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) {
+ FLUSH_BATCH( MGA_CONTEXT(ctx) );
+ updateSpecularLighting( ctx );
+ }
+}
- if ((mmesa->dirty & MGA_UPLOAD_TEX1IMAGE) && mmesa->CurrentTexObj[1])
- mgaUploadTexImages(mmesa, mmesa->CurrentTexObj[1]);
- if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
- memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup));
- }
+static void mgaDDShadeModel(GLcontext *ctx, GLenum mode)
+{
+ /* FIXME: This used to FLUSH_BATCH and set MGA_NEW_TEXTURE in new_state,
+ * FIXME: so I'm not sure what to do here now.
+ */
+}
- if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
- memcpy(&sarea->TexState[0],
- &mmesa->CurrentTexObj[0]->setup,
- sizeof(sarea->TexState[0]));
- }
- if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
- memcpy(&sarea->TexState[1],
- &mmesa->CurrentTexObj[1]->setup,
- sizeof(sarea->TexState[1]));
- }
+/* =============================================================
+ * Stencil
+ */
- if (sarea->TexState[0].texctl2 !=
- sarea->TexState[1].texctl2) {
- memcpy(&sarea->TexState[1],
- &sarea->TexState[0],
- sizeof(sarea->TexState[0]));
- mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
- }
- if (mmesa->dirty & MGA_UPLOAD_PIPE) {
-/* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
- mmesa->sarea->WarpPipe = mmesa->vertex_format;
- mmesa->sarea->vertsize = mmesa->vertex_size;
+static void mgaDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
+ GLuint mask)
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLuint stencil;
+ GLuint stencilctl;
+
+ stencil = (ref << S_sref_SHIFT) | (mask << S_smsk_SHIFT);
+ switch (func)
+ {
+ case GL_NEVER:
+ stencilctl = SC_smode_snever;
+ break;
+ case GL_LESS:
+ stencilctl = SC_smode_slt;
+ break;
+ case GL_LEQUAL:
+ stencilctl = SC_smode_slte;
+ break;
+ case GL_GREATER:
+ stencilctl = SC_smode_sgt;
+ break;
+ case GL_GEQUAL:
+ stencilctl = SC_smode_sgte;
+ break;
+ case GL_NOTEQUAL:
+ stencilctl = SC_smode_sne;
+ break;
+ case GL_EQUAL:
+ stencilctl = SC_smode_se;
+ break;
+ case GL_ALWAYS:
+ default:
+ stencilctl = SC_smode_salways;
+ break;
}
- mmesa->sarea->dirty |= mmesa->dirty;
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.stencil &= (S_sref_MASK & S_smsk_MASK);
+ mmesa->hw.stencil |= stencil;
+ mmesa->hw.stencilctl &= SC_smode_MASK;
+ mmesa->hw.stencilctl |= stencilctl;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+}
- mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE);
+static void mgaDDStencilMask(GLcontext *ctx, GLuint mask)
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- /* This is a bit of a hack but seems to be the best place to ensure
- * that separate specular is disabled when not needed.
- */
- if (mmesa->glCtx->Texture.Unit[0]._ReallyEnabled == 0 ||
- !mmesa->glCtx->Light.Enabled ||
- mmesa->glCtx->Light.Model.ColorControl == GL_SINGLE_COLOR) {
- sarea->TexState[0].texctl2 &= ~TMC_specen_enable;
- sarea->TexState[1].texctl2 &= ~TMC_specen_enable;
- }
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.stencil &= S_swtmsk_MASK;
+ mmesa->hw.stencil |= (mask << S_swtmsk_SHIFT);
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
-/* Fallback to swrast for select and feedback.
- */
-static void mgaRenderMode( GLcontext *ctx, GLenum mode )
+static void mgaDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
+ GLenum zpass)
{
- FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+ GLuint stencilctl;
+
+ stencilctl = 0;
+ switch (ctx->Stencil.FailFunc[0])
+ {
+ case GL_KEEP:
+ stencilctl |= SC_sfailop_keep;
+ break;
+ case GL_ZERO:
+ stencilctl |= SC_sfailop_zero;
+ break;
+ case GL_REPLACE:
+ stencilctl |= SC_sfailop_replace;
+ break;
+ case GL_INCR:
+ stencilctl |= SC_sfailop_incrsat;
+ break;
+ case GL_DECR:
+ stencilctl |= SC_sfailop_decrsat;
+ break;
+ case GL_INCR_WRAP:
+ stencilctl |= SC_sfailop_incr;
+ break;
+ case GL_DECR_WRAP:
+ stencilctl |= SC_sfailop_decr;
+ break;
+ case GL_INVERT:
+ stencilctl |= SC_sfailop_invert;
+ break;
+ default:
+ break;
+ }
+
+ switch (ctx->Stencil.ZFailFunc[0])
+ {
+ case GL_KEEP:
+ stencilctl |= SC_szfailop_keep;
+ break;
+ case GL_ZERO:
+ stencilctl |= SC_szfailop_zero;
+ break;
+ case GL_REPLACE:
+ stencilctl |= SC_szfailop_replace;
+ break;
+ case GL_INCR:
+ stencilctl |= SC_szfailop_incrsat;
+ break;
+ case GL_DECR:
+ stencilctl |= SC_szfailop_decrsat;
+ break;
+ case GL_INCR_WRAP:
+ stencilctl |= SC_szfailop_incr;
+ break;
+ case GL_DECR_WRAP:
+ stencilctl |= SC_szfailop_decr;
+ break;
+ case GL_INVERT:
+ stencilctl |= SC_szfailop_invert;
+ break;
+ default:
+ break;
+ }
+
+ switch (ctx->Stencil.ZPassFunc[0])
+ {
+ case GL_KEEP:
+ stencilctl |= SC_szpassop_keep;
+ break;
+ case GL_ZERO:
+ stencilctl |= SC_szpassop_zero;
+ break;
+ case GL_REPLACE:
+ stencilctl |= SC_szpassop_replace;
+ break;
+ case GL_INCR:
+ stencilctl |= SC_szpassop_incrsat;
+ break;
+ case GL_DECR:
+ stencilctl |= SC_szpassop_decrsat;
+ break;
+ case GL_INVERT:
+ stencilctl |= SC_szpassop_invert;
+ break;
+ default:
+ break;
+ }
+
+ FLUSH_BATCH( mmesa );
+ mmesa->hw.stencilctl &= (SC_sfailop_MASK & SC_szfailop_MASK
+ & SC_szpassop_MASK);
+ mmesa->hw.stencilctl |= stencilctl;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
/* =============================================================
+ * Window position and viewport transformation
*/
void mgaCalcViewport( GLcontext *ctx )
@@ -850,8 +721,167 @@ static void mgaDepthRange( GLcontext *ctx,
mgaCalcViewport( ctx );
}
+
/* =============================================================
+ * Miscellaneous
+ */
+
+static void mgaDDClearColor(GLcontext *ctx,
+ const GLfloat color[4] )
+{
+ mgaContextPtr mmesa = MGA_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]);
+
+ mmesa->ClearColor = mgaPackColor( mmesa->mgaScreen->cpp,
+ c[0], c[1], c[2], c[3]);
+}
+
+
+/* Fallback to swrast for select and feedback.
*/
+static void mgaRenderMode( GLcontext *ctx, GLenum mode )
+{
+ FALLBACK( ctx, MGA_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
+}
+
+
+static void mgaDDLogicOp( GLcontext *ctx, GLenum opcode )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+
+ FLUSH_BATCH( mmesa );
+#if defined(ACCEL_ROP)
+ mmesa->hw.rop = mgarop_NoBLK[ opcode & 0x0f ];
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+#else
+ FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
+ (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
+#endif
+}
+
+
+static void mgaXMesaSetFrontClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+ if (driDrawable->numClipRects == 0) {
+ static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+ mmesa->numClipRects = 1;
+ mmesa->pClipRects = &zeroareacliprect;
+ } else {
+ mmesa->numClipRects = driDrawable->numClipRects;
+ mmesa->pClipRects = driDrawable->pClipRects;
+ }
+ mmesa->drawX = driDrawable->x;
+ mmesa->drawY = driDrawable->y;
+
+ mmesa->setup.dstorg = mmesa->drawOffset;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
+}
+
+
+static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+
+ if (driDrawable->numBackClipRects == 0)
+ {
+ if (driDrawable->numClipRects == 0) {
+ static XF86DRIClipRectRec zeroareacliprect = {0,0,0,0};
+ mmesa->numClipRects = 1;
+ mmesa->pClipRects = &zeroareacliprect;
+ } else {
+ mmesa->numClipRects = driDrawable->numClipRects;
+ mmesa->pClipRects = driDrawable->pClipRects;
+ }
+ mmesa->drawX = driDrawable->x;
+ mmesa->drawY = driDrawable->y;
+ } else {
+ mmesa->numClipRects = driDrawable->numBackClipRects;
+ mmesa->pClipRects = driDrawable->pBackClipRects;
+ mmesa->drawX = driDrawable->backX;
+ mmesa->drawY = driDrawable->backY;
+ }
+
+ mmesa->setup.dstorg = mmesa->drawOffset;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
+}
+
+
+void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers )
+{
+ __DRIdrawablePrivate *driDrawable = mmesa->driDrawable;
+ MGASAREAPrivPtr sarea = mmesa->sarea;
+
+
+ DRI_VALIDATE_DRAWABLE_INFO(mmesa->driScreen, driDrawable);
+ mmesa->dirty_cliprects = 0;
+
+ if (mmesa->draw_buffer == MGA_FRONT)
+ mgaXMesaSetFrontClipRects( mmesa );
+ else
+ mgaXMesaSetBackClipRects( mmesa );
+
+ sarea->req_draw_buffer = mmesa->draw_buffer;
+
+ mgaUpdateClipping( mmesa->glCtx );
+ mgaCalcViewport( mmesa->glCtx );
+
+ mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
+}
+
+
+static void mgaDDDrawBuffer(GLcontext *ctx, GLenum mode )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ FLUSH_BATCH( mmesa );
+
+ /*
+ * _DrawDestMask is easier to cope with than <mode>.
+ */
+ switch ( ctx->Color._DrawDestMask ) {
+ case FRONT_LEFT_BIT:
+ mmesa->setup.dstorg = mmesa->mgaScreen->frontOffset;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+ mmesa->draw_buffer = MGA_FRONT;
+ mgaXMesaSetFrontClipRects( mmesa );
+ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ break;
+ case BACK_LEFT_BIT:
+ mmesa->setup.dstorg = mmesa->mgaScreen->backOffset;
+ mmesa->draw_buffer = MGA_BACK;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
+ mgaXMesaSetBackClipRects( mmesa );
+ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_FALSE );
+ break;
+ default:
+ /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
+ FALLBACK( ctx, MGA_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ /* We want to update the s/w rast state too so that r200SetBuffer()
+ * gets called.
+ */
+ _swrast_DrawBuffer(ctx, mode);
+}
+
+
+static void mgaDDReadBuffer(GLcontext *ctx, GLenum mode )
+{
+ /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
+}
+
+
+/* =============================================================
+ * State enable/disable
+ */
+
static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
{
@@ -860,11 +890,11 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
switch(cap) {
case GL_ALPHA_TEST:
FLUSH_BATCH( mmesa );
- mmesa->new_state |= MGA_NEW_ALPHA;
+ mmesa->hw.alpha_func_enable = (state) ? ~0 : 0;
break;
case GL_BLEND:
FLUSH_BATCH( mmesa );
- mmesa->new_state |= MGA_NEW_ALPHA;
+ mmesa->hw.blend_func_enable = (state) ? ~0 : 0;
/* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
*/
@@ -874,31 +904,31 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
break;
case GL_DEPTH_TEST:
FLUSH_BATCH( mmesa );
- mmesa->new_state |= MGA_NEW_DEPTH;
FALLBACK (ctx, MGA_FALLBACK_DEPTH,
ctx->Depth.Func == GL_NEVER && ctx->Depth.Test);
break;
+
case GL_SCISSOR_TEST:
FLUSH_BATCH( mmesa );
mmesa->scissor = state;
- mmesa->new_state |= MGA_NEW_CLIP;
+ mgaUpdateClipping( ctx );
break;
+
case GL_FOG:
MGA_STATECHANGE( mmesa, MGA_UPLOAD_CONTEXT );
if (ctx->Fog.Enabled)
mmesa->setup.maccess |= MA_fogen_enable;
else
mmesa->setup.maccess &= ~MA_fogen_enable;
+
+ mgaChooseVertexState( ctx );
break;
case GL_CULL_FACE:
- FLUSH_BATCH( mmesa );
- mmesa->new_state |= MGA_NEW_CULL;
+ mgaDDCullFaceFrontFace( ctx, 0 );
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
- FLUSH_BATCH( mmesa );
- mmesa->new_state |= (MGA_NEW_TEXTURE|MGA_NEW_ALPHA);
break;
case GL_POLYGON_STIPPLE:
if (mmesa->haveHwStipple && mmesa->raster_primitive == GL_TRIANGLES) {
@@ -914,16 +944,16 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
#if !defined(ACCEL_ROP)
FALLBACK( ctx, MGA_FALLBACK_LOGICOP,
(state && ctx->Color.LogicOp != GL_COPY));
-#else
- mmesa->new_state |= MGA_NEW_DEPTH;
#endif
break;
case GL_STENCIL_TEST:
FLUSH_BATCH( mmesa );
- if (mmesa->hw_stencil)
- mmesa->new_state |= MGA_NEW_STENCIL;
- else
+ if (mmesa->hw_stencil) {
+ mmesa->hw.stencil_enable = ( state ) ? ~0 : 0;
+ }
+ else {
FALLBACK( ctx, MGA_FALLBACK_STENCIL, state );
+ }
default:
break;
}
@@ -933,56 +963,150 @@ static void mgaDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
/* =============================================================
*/
-
-
-/* =============================================================
- */
-
-static void mgaDDPrintState( const char *msg, GLuint state )
+static void mgaDDPrintDirty( const char *msg, GLuint state )
{
- fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
+ fprintf(stderr, "%s (0x%03x): %s%s%s%s%s%s%s\n",
msg,
- state,
- (state & MGA_NEW_DEPTH) ? "depth, " : "",
- (state & MGA_NEW_ALPHA) ? "alpha, " : "",
- (state & MGA_NEW_CLIP) ? "clip, " : "",
- (state & MGA_NEW_CULL) ? "cull, " : "",
- (state & MGA_NEW_TEXTURE) ? "texture, " : "",
- (state & MGA_NEW_CONTEXT) ? "context, " : "");
+ (unsigned int) state,
+ (state & MGA_WAIT_AGE) ? "wait-age " : "",
+ (state & MGA_UPLOAD_TEX0IMAGE) ? "upload-tex0-img " : "",
+ (state & MGA_UPLOAD_TEX1IMAGE) ? "upload-tex1-img " : "",
+ (state & MGA_UPLOAD_CONTEXT) ? "upload-ctx " : "",
+ (state & MGA_UPLOAD_TEX0) ? "upload-tex0 " : "",
+ (state & MGA_UPLOAD_TEX1) ? "upload-tex1 " : "",
+ (state & MGA_UPLOAD_PIPE) ? "upload-pipe " : ""
+ );
}
-void mgaDDUpdateHwState( GLcontext *ctx )
+/* Push the state into the sarea and/or texture memory.
+ */
+void mgaEmitHwStateLocked( mgaContextPtr mmesa )
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- int new_state = mmesa->new_state;
+ MGASAREAPrivPtr sarea = mmesa->sarea;
+ GLcontext * ctx = mmesa->glCtx;
- if (new_state)
- {
- FLUSH_BATCH( mmesa );
+ if (MGA_DEBUG & DEBUG_VERBOSE_MSG)
+ mgaDDPrintDirty( __FUNCTION__, mmesa->dirty );
- mmesa->new_state = 0;
+ if (mmesa->dirty & MGA_UPLOAD_CONTEXT) {
+ mmesa->setup.wflag = _CULL_DISABLE;
+ if (mmesa->raster_primitive == GL_TRIANGLES) {
+ if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT &&
+ ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
+ mmesa->setup.wflag = mmesa->hw.cull_dualtex;
+ }
+ else {
+ mmesa->setup.wflag = mmesa->hw.cull;
+ }
+ }
- if (MESA_VERBOSE&VERBOSE_DRIVER)
- mgaDDPrintState("UpdateHwState", new_state);
+ mmesa->setup.stencil = mmesa->hw.stencil
+ & mmesa->hw.stencil_enable;
+ mmesa->setup.stencilctl = mmesa->hw.stencilctl
+ & mmesa->hw.stencil_enable;
- if (new_state & MGA_NEW_DEPTH)
- mgaUpdateZMode(ctx);
+ /* If depth testing is not enabled, then use the no Z-compare / no
+ * Z-write mode. Otherwise, use whatever is set in hw.zmode.
+ */
+ mmesa->setup.dwgctl &= (DC_zmode_MASK & DC_atype_MASK);
+ mmesa->setup.dwgctl |= (ctx->Depth.Test)
+ ? mmesa->hw.zmode : (DC_zmode_nozcmp | DC_atype_i);
- if (new_state & MGA_NEW_ALPHA)
- mgaUpdateAlphaMode(ctx);
+#if defined(ACCEL_ROP)
+ mmesa->setup.dwgctl &= DC_bop_MASK;
+ mmesa->setup.dwgctl |= (ctx->Color.ColorLogicOpEnabled)
+ ? mmesa->hw.rop : mgarop_NoBLK[ GL_COPY & 0x0f ];
+#endif
- if (new_state & MGA_NEW_CLIP)
- mgaUpdateClipping(ctx);
+ mmesa->setup.alphactrl &= AC_src_MASK & AC_dst_MASK & AC_atmode_MASK
+ & AC_atref_MASK & AC_alphasel_MASK;
+ mmesa->setup.alphactrl |=
+ ((mmesa->hw.alpha_func & mmesa->hw.alpha_func_enable)
+ | ((mmesa->hw.blend_func & mmesa->hw.blend_func_enable)
+ | ((AC_src_one | AC_dst_zero) & ~mmesa->hw.blend_func_enable))
+ | mmesa->hw.alpha_sel
+ | (AC_amode_alpha_channel
+ | AC_astipple_disable
+ | AC_aten_disable
+ | AC_atmode_noacmp));
- if (new_state & MGA_NEW_STENCIL)
- mgaUpdateStencil(ctx);
+ memcpy( &sarea->ContextState, &mmesa->setup, sizeof(mmesa->setup));
+ }
- if (new_state & (MGA_NEW_WARP|MGA_NEW_CULL))
- mgaUpdateCull(ctx);
+ if ((mmesa->dirty & MGA_UPLOAD_TEX0) && mmesa->CurrentTexObj[0]) {
+ mmesa->CurrentTexObj[0]->setup.texctl2 &= ~TMC_specen_enable;
+ mmesa->CurrentTexObj[0]->setup.texctl2 |= mmesa->hw.specen;
- if (new_state & (MGA_NEW_WARP|MGA_NEW_TEXTURE))
- mgaUpdateTextureState(ctx);
+ memcpy(&sarea->TexState[0],
+ &mmesa->CurrentTexObj[0]->setup,
+ sizeof(sarea->TexState[0]));
}
+
+ if ((mmesa->dirty & MGA_UPLOAD_TEX1) && mmesa->CurrentTexObj[1]) {
+ mmesa->CurrentTexObj[1]->setup.texctl2 &= ~TMC_specen_enable;
+ mmesa->CurrentTexObj[1]->setup.texctl2 |= mmesa->hw.specen;
+
+ memcpy(&sarea->TexState[1],
+ &mmesa->CurrentTexObj[1]->setup,
+ sizeof(sarea->TexState[1]));
+ }
+
+ if ( (sarea->TexState[0].texctl2 & TMC_borderen_MASK) !=
+ (sarea->TexState[1].texctl2 & TMC_borderen_MASK) ) {
+ const int borderen = sarea->TexState[1].texctl2 & ~TMC_borderen_MASK;
+
+ memcpy( &sarea->TexState[1], &sarea->TexState[0],
+ sizeof(sarea->TexState[0]) );
+ sarea->TexState[1].texctl2 |= borderen;
+ mmesa->dirty |= MGA_UPLOAD_TEX1|MGA_UPLOAD_TEX0;
+ }
+
+ if (mmesa->dirty & MGA_UPLOAD_PIPE) {
+/* mmesa->sarea->wacceptseq = mmesa->hw_primitive; */
+ mmesa->sarea->WarpPipe = mmesa->vertex_format;
+ mmesa->sarea->vertsize = mmesa->vertex_size;
+ }
+
+ mmesa->sarea->dirty |= mmesa->dirty;
+ mmesa->dirty &= MGA_UPLOAD_CLIPRECTS;
+
+ /* This is a bit of a hack but seems to be the best place to ensure
+ * that separate specular is disabled when not needed.
+ */
+ if (ctx->Texture._EnabledUnits == 0 ||
+ !ctx->Light.Enabled ||
+ ctx->Light.Model.ColorControl == GL_SINGLE_COLOR) {
+ sarea->TexState[0].texctl2 &= ~TMC_specen_enable;
+ sarea->TexState[1].texctl2 &= ~TMC_specen_enable;
+ }
+}
+
+
+/* =============================================================
+ */
+
+
+static void mgaDDValidateState( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ int new_state = mmesa->NewGLState;
+
+
+ FLUSH_BATCH( mmesa );
+
+ if (mmesa->NewGLState & _MGA_NEW_RASTERSETUP) {
+ mgaChooseVertexState( ctx );
+ }
+
+ if (mmesa->NewGLState & _MGA_NEW_RENDERSTATE) {
+ mgaChooseRenderState( ctx );
+ }
+
+ if (new_state & _NEW_TEXTURE) {
+ mgaUpdateTextureState(ctx);
+ }
+
+ mmesa->NewGLState = 0;
}
@@ -992,25 +1116,40 @@ static void mgaDDInvalidateState( GLcontext *ctx, GLuint new_state )
_swsetup_InvalidateState( ctx, new_state );
_ac_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
- MGA_CONTEXT(ctx)->new_gl_state |= new_state;
+ MGA_CONTEXT(ctx)->NewGLState |= new_state;
}
+static void mgaRunPipeline( GLcontext *ctx )
+{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+ if (mmesa->NewGLState) {
+ mgaDDValidateState( ctx );
+ }
+
+ if (mmesa->dirty) {
+ mgaEmitHwStateLocked( mmesa );
+ }
+
+ _tnl_run_pipeline( ctx );
+}
+
void mgaInitState( mgaContextPtr mmesa )
{
mgaScreenPrivate *mgaScreen = mmesa->mgaScreen;
GLcontext *ctx = mmesa->glCtx;
- if (ctx->Color._DrawDestMask == BACK_LEFT_BIT) {
+ if (ctx->Visual.doubleBufferMode) {
+ /* use back buffer by default */
mmesa->draw_buffer = MGA_BACK;
- mmesa->read_buffer = MGA_BACK;
mmesa->drawOffset = mmesa->mgaScreen->backOffset;
mmesa->readOffset = mmesa->mgaScreen->backOffset;
mmesa->setup.dstorg = mgaScreen->backOffset;
} else {
+ /* use front buffer by default */
mmesa->draw_buffer = MGA_FRONT;
- mmesa->read_buffer = MGA_FRONT;
mmesa->drawOffset = mmesa->mgaScreen->frontOffset;
mmesa->readOffset = mmesa->mgaScreen->frontOffset;
mmesa->setup.dstorg = mgaScreen->frontOffset;
@@ -1043,14 +1182,21 @@ void mgaInitState( mgaContextPtr mmesa )
mmesa->setup.maccess |= MA_zwidth_24;
break;
case 32:
- mmesa->setup.maccess |= MA_pwidth_32;
+ mmesa->setup.maccess |= MA_zwidth_32;
break;
}
+ mmesa->hw.zmode = DC_zmode_zlt | DC_atype_zi;
+ mmesa->hw.stencil = (0x0ff << S_smsk_SHIFT) | (0x0ff << S_swtmsk_SHIFT);
+ mmesa->hw.stencilctl = SC_smode_salways | SC_sfailop_keep
+ | SC_szfailop_keep | SC_szpassop_keep;
+ mmesa->hw.stencil_enable = 0;
+ mmesa->hw.cull = _CULL_NEGATIVE;
+ mmesa->hw.cull_dualtex = _CULL_POSITIVE;
+ mmesa->hw.specen = 0;
+
mmesa->setup.dwgctl = (DC_opcod_trap |
- DC_atype_i |
DC_linear_xy |
- DC_zmode_nozcmp |
DC_solid_disable |
DC_arzero_disable |
DC_sgnzero_disable |
@@ -1072,16 +1218,15 @@ void mgaInitState( mgaContextPtr mmesa )
AC_atmode_noacmp |
AC_alphasel_fromtex );
- mmesa->setup.fogcolor =
- MGAPACKCOLOR888((GLubyte)(ctx->Fog.Color[0]*255.0F),
- (GLubyte)(ctx->Fog.Color[1]*255.0F),
- (GLubyte)(ctx->Fog.Color[2]*255.0F));
+ mmesa->setup.fogcolor = PACK_COLOR_888((GLubyte)(ctx->Fog.Color[0]*255.0F),
+ (GLubyte)(ctx->Fog.Color[1]*255.0F),
+ (GLubyte)(ctx->Fog.Color[2]*255.0F));
mmesa->setup.wflag = 0;
mmesa->setup.tdualstage0 = 0;
mmesa->setup.tdualstage1 = 0;
mmesa->setup.fcol = 0;
- mmesa->new_state = ~0;
+ mmesa->dirty |= MGA_UPLOAD_CONTEXT;
}
@@ -1103,8 +1248,8 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
ctx->Driver.FrontFace = mgaDDCullFaceFrontFace;
ctx->Driver.ColorMask = mgaDDColorMask;
- ctx->Driver.DrawBuffer = mgaDDSetDrawBuffer;
- ctx->Driver.ReadBuffer = mgaDDSetReadBuffer;
+ ctx->Driver.DrawBuffer = mgaDDDrawBuffer;
+ ctx->Driver.ReadBuffer = mgaDDReadBuffer;
ctx->Driver.ClearColor = mgaDDClearColor;
ctx->Driver.ClearDepth = mgaDDClearDepth;
ctx->Driver.LogicOpcode = mgaDDLogicOp;
@@ -1128,4 +1273,6 @@ void mgaDDInitStateFuncs( GLcontext *ctx )
ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+
+ TNL_CONTEXT(ctx)->Driver.RunPipeline = mgaRunPipeline;
}