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 );
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 );
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);
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);
#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
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) */
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 */
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);
#ifdef CB_DPATH
/* Make sure it fits there. */
- r300EnsureCmdBufSpace(r300, 419*3, __FUNCTION__);
+ r300EnsureCmdBufSpace(r300, 421*3, __FUNCTION__);
if(flags || bits)
r300EmitClearState(ctx);
#endif
# 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.
# 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)
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
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) {
}
}
+/* =============================================================
+ * 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
*/
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;
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);
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;
functions->DepthFunc = r300DepthFunc;
functions->DepthMask = r300DepthMask;
functions->CullFace = r300CullFace;
+ functions->Fogfv = r300Fogfv;
functions->FrontFace = r300FrontFace;
functions->ShadeModel = r300ShadeModel;