From 6c419be40201323c83e5428f6de148be1eded28e Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Tue, 11 Apr 2006 04:17:50 +0000 Subject: Fog support (Ewald Snel) --- src/mesa/drivers/dri/r300/r300_cmdbuf.c | 19 +++-- src/mesa/drivers/dri/r300/r300_context.h | 21 ++++- src/mesa/drivers/dri/r300/r300_ioctl.c | 8 +- src/mesa/drivers/dri/r300/r300_reg.h | 16 +++- src/mesa/drivers/dri/r300/r300_render.c | 2 +- src/mesa/drivers/dri/r300/r300_state.c | 135 ++++++++++++++++++++++++++++--- 6 files changed, 177 insertions(+), 24 deletions(-) diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 09f7669bd7..320e1bd13e 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -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); diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 176341d771..449459b5b1 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -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 */ diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 0115d622a9..159285962d 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -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 diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index c78462af2e..4afe4f239c 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -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) diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index e6ed06a69d..783b2e292a 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -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 diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index d4dafe62a7..466b1cbe4f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -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) { @@ -639,6 +658,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 */ @@ -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; -- cgit v1.2.3