Fog support (Ewald Snel)
authorAapo Tahkola <aet@rasterburn.org>
Tue, 11 Apr 2006 04:17:50 +0000 (04:17 +0000)
committerAapo Tahkola <aet@rasterburn.org>
Tue, 11 Apr 2006 04:17:50 +0000 (04:17 +0000)
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_ioctl.c
src/mesa/drivers/dri/r300/r300_reg.h
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c

index 09f7669..320e1bd 100644 (file)
@@ -337,8 +337,10 @@ void r300InitCmdBuf(r300ContextPtr r300)
                r300->hw.unk4260.cmd[0] = cmdpacket0(0x4260, 3);
        ALLOC_STATE( unk4274, always, 5, "unk4274", 0 );
                r300->hw.unk4274.cmd[0] = cmdpacket0(0x4274, 4);
-       ALLOC_STATE( unk4288, always, 6, "unk4288", 0 );
-               r300->hw.unk4288.cmd[0] = cmdpacket0(0x4288, 5);
+       ALLOC_STATE( unk4288, always, 4, "unk4288", 0 );
+               r300->hw.unk4288.cmd[0] = cmdpacket0(0x4288, 3);
+       ALLOC_STATE( fogp, always, 3, "fogp", 0 );
+               r300->hw.fogp.cmd[0] = cmdpacket0(R300_RE_FOG_SCALE, 2);
        ALLOC_STATE( unk42A0, always, 2, "unk42A0", 0 );
                r300->hw.unk42A0.cmd[0] = cmdpacket0(0x42A0, 1);
        ALLOC_STATE( zbs, always, R300_ZBS_CMDSIZE, "zbs", 0 );
@@ -374,10 +376,10 @@ void r300InitCmdBuf(r300ContextPtr r300)
                r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR2_0, 1);
        ALLOC_STATE( fpi[3], variable, R300_FPI_CMDSIZE, "fpi/3", 3 );
                r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR3_0, 1);
-       ALLOC_STATE( unk4BC0, always, 2, "unk4BC0", 0 );
-               r300->hw.unk4BC0.cmd[0] = cmdpacket0(0x4BC0, 1);
-       ALLOC_STATE( unk4BC8, always, 4, "unk4BC8", 0 );
-               r300->hw.unk4BC8.cmd[0] = cmdpacket0(0x4BC8, 3);
+       ALLOC_STATE( fogs, always, R300_FOGS_CMDSIZE, "fogs", 0 );
+               r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_RE_FOG_STATE, 1);
+       ALLOC_STATE( fogc, always, R300_FOGC_CMDSIZE, "fogc", 0 );
+               r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FOG_COLOR_R, 3);
        ALLOC_STATE( at, always, R300_AT_CMDSIZE, "at", 0 );
                r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_PP_ALPHA_TEST, 2);
        ALLOC_STATE( unk4BD8, always, 2, "unk4BD8", 0 );
@@ -478,6 +480,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4260);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4274);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4288);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fogp);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42A0);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.zbs);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk42B4);
@@ -495,8 +498,8 @@ void r300InitCmdBuf(r300ContextPtr r300)
        insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[1]);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[2]);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.fpi[3]);
-       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC0);
-       insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BC8);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fogs);
+       insert_at_tail(&r300->hw.atomlist, &r300->hw.fogc);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.at);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.unk4BD8);
        insert_at_tail(&r300->hw.atomlist, &r300->hw.fpp);
index 176341d..449459b 100644 (file)
@@ -346,6 +346,21 @@ struct r300_state_atom {
 #define R300_FPP_PARAM_0       1
 #define R300_FPP_CMDSIZE       (32*4+1)
 
+#define R300_FOGS_CMD_0                0
+#define R300_FOGS_STATE                1
+#define R300_FOGS_CMDSIZE      2
+
+#define R300_FOGC_CMD_0                0
+#define R300_FOGC_R            1
+#define R300_FOGC_G            2
+#define R300_FOGC_B            3
+#define R300_FOGC_CMDSIZE      4
+
+#define R300_FOGP_CMD_0                0
+#define R300_FOGP_SCALE                1
+#define R300_FOGP_START                2
+#define R300_FOGP_CMDSIZE      3
+
 #define R300_AT_CMD_0          0
 #define R300_AT_ALPHA_TEST     1
 #define R300_AT_UNKNOWN                2
@@ -432,6 +447,8 @@ struct r300_hw_state {
        struct r300_state_atom unk4260; /* (4260) */
        struct r300_state_atom unk4274; /* (4274) */
        struct r300_state_atom unk4288; /* (4288) */
+       struct r300_state_atom fogp;    /* fog parameters (4294) */
+       struct r300_state_atom unk429C; /* (429C) */
        struct r300_state_atom unk42A0; /* (42A0) */
        struct r300_state_atom zbs;     /* zbias (42A4) */
        struct r300_state_atom unk42B4; /* (42B4) */
@@ -446,8 +463,8 @@ struct r300_hw_state {
        struct r300_state_atom fpt;     /* texi - (4620) */
        struct r300_state_atom unk46A4; /* (46A4) */
        struct r300_state_atom fpi[4];  /* fp instructions (46C0/47C0/48C0/49C0) */
-       struct r300_state_atom unk4BC0; /* (4BC0) */
-       struct r300_state_atom unk4BC8; /* (4BC8) */
+       struct r300_state_atom fogs;    /* fog state (4BC0) */
+       struct r300_state_atom fogc;    /* fog color (4BC8) */
        struct r300_state_atom at;      /* alpha test (4BD4) */
        struct r300_state_atom unk4BD8; /* (4BD8) */
        struct r300_state_atom fpp;     /* 0x4C00 and following */
index 0115d62..1592859 100644 (file)
@@ -380,10 +380,16 @@ static void r300EmitClearState(GLcontext * ctx)
        int i;
        LOCAL_VARS;
        
+       
        R300_STATECHANGE(r300, vir[0]);
        reg_start(R300_VAP_INPUT_ROUTE_0_0, 0);
        e32(0x21030003);
        
+       /* disable fog */
+       R300_STATECHANGE(r300, fogs);
+       reg_start(R300_RE_FOG_STATE, 0);
+       e32(0x0);
+       
        R300_STATECHANGE(r300, vir[1]);
        reg_start(R300_VAP_INPUT_ROUTE_1_0, 0);
        e32(0xF688F688);
@@ -553,7 +559,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask, GLboolean all,
 
 #ifdef CB_DPATH
        /* Make sure it fits there. */
-       r300EnsureCmdBufSpace(r300, 419*3, __FUNCTION__);
+       r300EnsureCmdBufSpace(r300, 421*3, __FUNCTION__);
        if(flags || bits)
                r300EmitClearState(ctx);
 #endif
index c78462a..4afe4f2 100644 (file)
@@ -517,6 +517,10 @@ I am fairly certain that they are correct unless stated otherwise in comments.
 #      define R300_PM_BACK_LINE              (1 << 7)
 #      define R300_PM_BACK_FILL              (1 << 8)
 
+/* Fog parameters */
+#define R300_RE_FOG_SCALE                     0x4294
+#define R300_RE_FOG_START                     0x4298
+
 /* Not sure why there are duplicate of factor and constant values. 
    My best guess so far is that there are seperate zbiases for test and write. 
    Ordering might be wrong.
@@ -1113,7 +1117,17 @@ I am fairly certain that they are correct unless stated otherwise in comments.
 #       define R300_FPI2_UNKNOWN_31              (1 << 31)
 /* END */
 
-/* gap */
+/* Fog state and color */
+#define R300_RE_FOG_STATE                   0x4BC0
+#       define R300_FOG_ENABLE                   (1 << 0)
+#      define R300_FOG_MODE_LINEAR              (0 << 1)
+#      define R300_FOG_MODE_EXP                 (1 << 1)
+#      define R300_FOG_MODE_EXP2                (2 << 1)
+#      define R300_FOG_MODE_MASK                (3 << 1)
+#define R300_FOG_COLOR_R                    0x4BC8
+#define R300_FOG_COLOR_G                    0x4BCC
+#define R300_FOG_COLOR_B                    0x4BD0
+
 #define R300_PP_ALPHA_TEST                  0x4BD4
 #       define R300_REF_ALPHA_MASK               0x000000ff
 #       define R300_ALPHA_TEST_FAIL              (0 << 8)
index e6ed06a..783b2e2 100644 (file)
@@ -469,12 +469,12 @@ int r300Fallback(GLcontext *ctx)
        FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
        FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
        FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
+       FALLBACK_IF(ctx->Fog.Enabled);
 #endif
        FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
        FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
        //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
        
-       //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
        //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
        FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
        FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
index d4dafe6..466b1cb 100644 (file)
@@ -417,6 +417,25 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
        case GL_TEXTURE_3D:
                break;
 
+       case GL_FOG:
+               R300_STATECHANGE(r300, fogs);
+               if (state) {
+                       r300->hw.fogs.cmd[R300_FOGS_STATE] |=
+                           R300_FOG_ENABLE;
+                       
+                       r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
+                       ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
+                       ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+                       ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
+                       ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+                       ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+               } else {
+                       r300->hw.fogs.cmd[R300_FOGS_STATE] &=
+                           ~R300_FOG_ENABLE;
+               }
+               
+               break;
+
        case GL_ALPHA_TEST:
                R300_STATECHANGE(r300, at);
                if (state) {
@@ -640,6 +659,101 @@ static void r300ColorMask(GLcontext* ctx,
 }
 
 /* =============================================================
+ * Fog
+ */
+static void r300Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       union { int i; float f; } fogScale, fogStart;
+       
+       (void) param;
+       
+       fogScale.i = r300->hw.fogp.cmd[R300_FOGP_SCALE];
+       fogStart.i = r300->hw.fogp.cmd[R300_FOGP_START];
+
+       switch (pname) {
+       case GL_FOG_MODE:
+               if (!ctx->Fog.Enabled)
+                       return;
+               switch (ctx->Fog.Mode) {
+               case GL_LINEAR:
+                       R300_STATECHANGE(r300, fogs);
+                       r300->hw.fogs.cmd[R300_FOGS_STATE] =
+                               (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_LINEAR;
+
+                       if (ctx->Fog.Start == ctx->Fog.End) {
+                               fogScale.f = -1.0;
+                               fogStart.f = 1.0;
+                       }
+                       else {
+                               fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
+                               fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
+                       }
+                       break;
+               case GL_EXP:
+                       R300_STATECHANGE(r300, fogs);
+                       r300->hw.fogs.cmd[R300_FOGS_STATE] =
+                               (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP;
+                       fogScale.f = 0.0933*ctx->Fog.Density;
+                       fogStart.f = 0.0;
+                       break;
+               case GL_EXP2:
+                       R300_STATECHANGE(r300, fogs);
+                       r300->hw.fogs.cmd[R300_FOGS_STATE] =
+                               (r300->hw.fogs.cmd[R300_FOGS_STATE] & ~R300_FOG_MODE_MASK) | R300_FOG_MODE_EXP2;
+                       fogScale.f = 0.3*ctx->Fog.Density;
+                       fogStart.f = 0.0;
+               default:
+                       return;
+               }
+               break;
+       case GL_FOG_DENSITY:
+               switch (ctx->Fog.Mode) {
+               case GL_EXP:
+                       fogScale.f = 0.0933*ctx->Fog.Density;
+                       fogStart.f = 0.0;
+                       break;
+               case GL_EXP2:
+                       fogScale.f = 0.3*ctx->Fog.Density;
+                       fogStart.f = 0.0;
+               default:
+                       break;
+               }
+               break;
+       case GL_FOG_START:
+       case GL_FOG_END:
+               if (ctx->Fog.Mode == GL_LINEAR) {
+                       if (ctx->Fog.Start == ctx->Fog.End) {
+                               fogScale.f = -1.0;
+                               fogStart.f = 1.0;
+                       }
+                       else {
+                               fogScale.f = 1.0 / (ctx->Fog.End-ctx->Fog.Start);
+                               fogStart.f = -ctx->Fog.Start / (ctx->Fog.End-ctx->Fog.Start);
+                       }
+               }
+               break;
+       case GL_FOG_COLOR:
+               R300_STATECHANGE(r300, fogc);
+               r300->hw.fogc.cmd[R300_FOGC_R] = (GLuint) (ctx->Fog.Color[0]*1023.0F) & 0x3FF;
+               r300->hw.fogc.cmd[R300_FOGC_G] = (GLuint) (ctx->Fog.Color[1]*1023.0F) & 0x3FF;
+               r300->hw.fogc.cmd[R300_FOGC_B] = (GLuint) (ctx->Fog.Color[2]*1023.0F) & 0x3FF;
+               break;
+       case GL_FOG_COORD_SRC:
+               break;
+       default:
+               return;
+       }
+
+       if (fogScale.i != r300->hw.fogp.cmd[R300_FOGP_SCALE] ||
+           fogStart.i != r300->hw.fogp.cmd[R300_FOGP_START]) {
+               R300_STATECHANGE(r300, fogp);
+               r300->hw.fogp.cmd[R300_FOGP_SCALE] = fogScale.i;
+               r300->hw.fogp.cmd[R300_FOGP_START] = fogStart.i;
+       }
+}
+
+/* =============================================================
  * Point state
  */
 static void r300PointSize(GLcontext * ctx, GLfloat size)
@@ -1870,7 +1984,8 @@ void r300ResetHwState(r300ContextPtr r300)
                r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = R300_GB_TILE_ENABLE
                                                        | R300_GB_TILE_PIPE_COUNT_RV300
                                                        | R300_GB_TILE_SIZE_16;
-       r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = 0x00000000;
+       /* set to 0 when fog is disabled? */
+       r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W;
        r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = 0x00000000; /* No antialiasing */
 
        //r300->hw.txe.cmd[R300_TXE_ENABLE] = 0;
@@ -1907,9 +2022,6 @@ void r300ResetHwState(r300ContextPtr r300)
        r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
        r300->hw.unk4288.cmd[2] = 0x00000001;
        r300->hw.unk4288.cmd[3] = 0x00000000;
-       r300->hw.unk4288.cmd[4] = 0x00000000;
-       r300->hw.unk4288.cmd[5] = 0x00000000;
-
        r300->hw.unk42A0.cmd[1] = 0x00000000;
 
        r300PolygonOffset(ctx, ctx->Polygon.OffsetFactor, ctx->Polygon.OffsetUnits);
@@ -1949,13 +2061,13 @@ void r300ResetHwState(r300ContextPtr r300)
                r300->hw.fpi[3].cmd[i] = FP_SELA(0,W,NO,FP_TMP(0),0,0);
        }
 #endif
-
-       r300->hw.unk4BC0.cmd[1] = 0;
-
-       r300->hw.unk4BC8.cmd[1] = 0;
-       r300->hw.unk4BC8.cmd[2] = 0;
-       r300->hw.unk4BC8.cmd[3] = 0;
-
+       r300Enable(ctx, GL_FOG, ctx->Fog.Enabled);
+       ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL );
+       ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
+       ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
+       ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
+       ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
+       ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL );
 
        r300->hw.at.cmd[R300_AT_UNKNOWN] = 0;
        r300->hw.unk4BD8.cmd[1] = 0;
@@ -2128,6 +2240,7 @@ void r300InitStateFuncs(struct dd_function_table* functions)
        functions->DepthFunc = r300DepthFunc;
        functions->DepthMask = r300DepthMask;
        functions->CullFace = r300CullFace;
+       functions->Fogfv = r300Fogfv;
        functions->FrontFace = r300FrontFace;
        functions->ShadeModel = r300ShadeModel;