summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Scheidegger <rscheidegger@gmx.ch>2005-10-17 00:54:12 +0000
committerRoland Scheidegger <rscheidegger@gmx.ch>2005-10-17 00:54:12 +0000
commit2d61d301171620efe624d83a5457f4094eb49cba (patch)
treefc53f97e4e2cba24bdf654fc2aba72975c18ccaf
parentdd5a86339f8b10f72c8a0e15c14463af3e0f717d (diff)
add GL_EXT_fog_coord support to radeon driver. No vtxfmt code (just uses fallback) yet. May cause a tcl fallback if fog coord is used together with separate specular lighting. Fog factors are precomputed and then submitted instead of the raw coords (chip limitation, same as on r200).
-rw-r--r--docs/VERSIONS3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_arrays.c58
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h15
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_verts.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c77
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c87
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_vtxfmt.c14
10 files changed, 217 insertions, 58 deletions
diff --git a/docs/VERSIONS b/docs/VERSIONS
index 58ec9edff2..7d14e022ed 100644
--- a/docs/VERSIONS
+++ b/docs/VERSIONS
@@ -1383,7 +1383,8 @@ Mesa Version History
- GL_EXT_timer_query extension
- r200: add support for GL_ATI_fragment_shader
- added fast XOR-mode line drawing optimization
- - radeon: add support for all 3 tmus and cube maps
+ - radeon: add support for all 3 tmus, GL_ARB_texture_cube_map
+ and GL_EXT_fog_coord
Changes:
- removed GL_HP_occlusion_test (use GL_ARB_occlusion_query instead)
Bug fixes:
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index a1e3582415..4b81b53980 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -66,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define need_GL_ARB_multisample
#define need_GL_ARB_texture_compression
#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_fog_coord
#define need_GL_EXT_secondary_color
#include "extension_helper.h"
@@ -139,6 +140,7 @@ const struct dri_extension card_extensions[] =
{ "GL_ARB_texture_mirrored_repeat", NULL },
{ "GL_EXT_blend_logic_op", NULL },
{ "GL_EXT_blend_subtract", GL_EXT_blend_minmax_functions },
+ { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
{ "GL_EXT_texture_edge_clamp", NULL },
@@ -238,6 +240,9 @@ radeonCreateContext( const __GLcontextModes *glVisual,
if ( !rmesa )
return GL_FALSE;
+ /* init exp fog table data */
+ radeonInitStaticFogData();
+
/* Parse configuration files.
* Do this here so that initialMaxAnisotropy is set before we create
* the default textures.
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
index 76ad1f3cd4..49d64148ca 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
@@ -48,6 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_state.h"
#include "radeon_swtcl.h"
#include "radeon_maos.h"
+#include "radeon_tcl.h"
#if 0
/* Usage:
@@ -169,6 +170,46 @@ do { \
} while (0)
#endif
+static void emit_vecfog( GLcontext *ctx,
+ struct radeon_dma_region *rvb,
+ char *data,
+ int stride,
+ int count )
+{
+ int i;
+ GLfloat *out;
+
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if (RADEON_DEBUG & DEBUG_VERTS)
+ fprintf(stderr, "%s count %d stride %d\n",
+ __FUNCTION__, count, stride);
+
+ assert (!rvb->buf);
+
+ if (stride == 0) {
+ radeonAllocDmaRegion( rmesa, rvb, 4, 4 );
+ count = 1;
+ rvb->aos_start = GET_START(rvb);
+ rvb->aos_stride = 0;
+ rvb->aos_size = 1;
+ }
+ else {
+ radeonAllocDmaRegion( rmesa, rvb, count * 4, 4 ); /* alignment? */
+ rvb->aos_start = GET_START(rvb);
+ rvb->aos_stride = 1;
+ rvb->aos_size = 1;
+ }
+
+ /* Emit the data
+ */
+ out = (GLfloat *)(rvb->address + rvb->start);
+ for (i = 0; i < count; i++) {
+ out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data );
+ out++;
+ data += stride;
+ }
+}
static void emit_vec4( GLcontext *ctx,
struct radeon_dma_region *rvb,
@@ -525,6 +566,20 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
component[nr++] = &rmesa->tcl.spec;
}
+
+ if (inputs & VERT_BIT_FOG) {
+ if (!rmesa->tcl.fog.buf)
+ emit_vecfog( ctx,
+ &(rmesa->tcl.fog),
+ (char *)VB->FogCoordPtr->data,
+ VB->FogCoordPtr->stride,
+ count);
+
+ vfmt |= RADEON_CP_VC_FRMT_FPFOG;
+ component[nr++] = &rmesa->tcl.fog;
+ }
+
+
vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1|RADEON_TCL_VTX_Q2));
@@ -589,6 +644,9 @@ void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
if (newinputs & VERT_BIT_COLOR1)
radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );
+
+ if (newinputs & VERT_BIT_FOG)
+ radeonReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ );
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
if (newinputs & VERT_BIT_TEX(unit))
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
index 265d061b36..034cda8a65 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
@@ -50,7 +50,6 @@ static void TAG(emit)( GLcontext *ctx,
GLuint rqcoordsnoswap = 0;
GLuint (*coord)[4];
GLuint coord_stride; /* object coordinates */
- GLubyte dummy[4];
int i;
union emit_union *v = (union emit_union *)dest;
@@ -133,7 +132,7 @@ static void TAG(emit)( GLcontext *ctx,
}
}
- if (DO_SPEC) {
+ if (DO_SPEC_OR_FOG) {
if (VB->SecondaryColorPtr[0]) {
spec = VB->SecondaryColorPtr[0]->data;
spec_stride = VB->SecondaryColorPtr[0]->stride;
@@ -143,12 +142,12 @@ static void TAG(emit)( GLcontext *ctx,
}
}
- if (DO_FOG) {
+ if (DO_SPEC_OR_FOG) {
if (VB->FogCoordPtr) {
fog = VB->FogCoordPtr->data;
fog_stride = VB->FogCoordPtr->stride;
} else {
- fog = (GLfloat (*)[4])&dummy; fog[0][0] = 0.0F;
+ fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG];
fog_stride = 0;
}
}
@@ -202,7 +201,7 @@ static void TAG(emit)( GLcontext *ctx,
STRIDE_4F(col, col_stride);
v++;
}
- if (DO_SPEC || DO_FOG) {
+ if (DO_SPEC_OR_FOG) {
if (DO_SPEC) {
UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.red, spec[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.green, spec[0][1]);
@@ -210,8 +209,8 @@ static void TAG(emit)( GLcontext *ctx,
STRIDE_4F(spec, spec_stride);
}
if (DO_FOG) {
- UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, fog[0][0]);
- fog = (GLfloat (*)[4])((GLubyte *)fog + fog_stride);
+ UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, radeonComputeFogBlendFactor(ctx, fog[0][0]));
+ STRIDE_4F(fog, fog_stride);
}
if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
v++;
@@ -283,7 +282,7 @@ static void TAG(init)( void )
if (DO_W) sz++;
if (DO_NORM) sz += 3;
if (DO_RGBA) sz++;
- if (DO_SPEC || DO_FOG) sz++;
+ if (DO_SPEC_OR_FOG) sz++;
if (DO_TEX0) sz += 2;
if (DO_TEX0 && DO_PTEX) sz++;
if (DO_TEX1) sz += 2;
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
index 24e681c8c0..91a60bb9f1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_verts.c
@@ -63,8 +63,11 @@ static struct {
#define DO_W (IND & RADEON_CP_VC_FRMT_W0)
#define DO_RGBA (IND & RADEON_CP_VC_FRMT_PKCOLOR)
-#define DO_SPEC (IND & RADEON_CP_VC_FRMT_PKSPEC)
-#define DO_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
+#define DO_SPEC_OR_FOG (IND & RADEON_CP_VC_FRMT_PKSPEC)
+#define DO_SPEC ((IND & RADEON_CP_VC_FRMT_PKSPEC) && \
+ (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR))
+#define DO_FOG ((IND & RADEON_CP_VC_FRMT_PKSPEC) && ctx->Fog.Enabled && \
+ (ctx->Fog.FogCoordinateSource == GL_FOG_COORD))
#define DO_TEX0 (IND & RADEON_CP_VC_FRMT_ST0)
#define DO_TEX1 (IND & RADEON_CP_VC_FRMT_ST1)
#define DO_TEX2 (IND & RADEON_CP_VC_FRMT_ST2)
@@ -337,7 +340,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
req |= RADEON_CP_VC_FRMT_PKCOLOR;
}
- if (inputs & VERT_BIT_COLOR1) {
+ if (inputs & (VERT_BIT_COLOR1|VERT_BIT_FOG)) {
req |= RADEON_CP_VC_FRMT_PKSPEC;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 28033881c5..681de914e8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -55,6 +55,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_vtxfmt.h"
#include "drirenderbuffer.h"
+static void radeonUpdateSpecular( GLcontext *ctx );
+
/* =============================================================
* Alpha blending
*/
@@ -329,9 +331,6 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
union { int i; float f; } c, d;
GLchan col[4];
- c.i = rmesa->hw.fog.cmd[FOG_C];
- d.i = rmesa->hw.fog.cmd[FOG_D];
-
switch (pname) {
case GL_FOG_MODE:
if (!ctx->Fog.Enabled)
@@ -341,30 +340,24 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
switch (ctx->Fog.Mode) {
case GL_LINEAR:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
- if (ctx->Fog.Start == ctx->Fog.End) {
- c.f = 1.0F;
- d.f = 1.0F;
- }
- else {
- c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
- d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
- }
break;
case GL_EXP:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
- c.f = 0.0;
- d.f = ctx->Fog.Density;
break;
case GL_EXP2:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
- c.f = 0.0;
- d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
default:
return;
}
- break;
+ /* fallthrough */
case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ if (!ctx->Fog.Enabled)
+ return;
+ c.i = rmesa->hw.fog.cmd[FOG_C];
+ d.i = rmesa->hw.fog.cmd[FOG_D];
switch (ctx->Fog.Mode) {
case GL_EXP:
c.f = 0.0;
@@ -374,13 +367,7 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
c.f = 0.0;
d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
- default:
- break;
- }
- break;
- case GL_FOG_START:
- case GL_FOG_END:
- if (ctx->Fog.Mode == GL_LINEAR) {
+ case GL_LINEAR:
if (ctx->Fog.Start == ctx->Fog.End) {
c.f = 1.0F;
d.f = 1.0F;
@@ -388,27 +375,29 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
}
+ break;
+ default:
+ break;
+ }
+ if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
+ RADEON_STATECHANGE( rmesa, fog );
+ rmesa->hw.fog.cmd[FOG_C] = c.i;
+ rmesa->hw.fog.cmd[FOG_D] = d.i;
}
break;
case GL_FOG_COLOR:
RADEON_STATECHANGE( rmesa, ctx );
UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
- rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] =
+ rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
+ rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
radeonPackColor( 4, col[0], col[1], col[2], 0 );
break;
- case GL_FOG_COORDINATE_SOURCE_EXT:
- /* What to do?
- */
+ case GL_FOG_COORD_SRC:
+ radeonUpdateSpecular( ctx );
break;
default:
return;
}
-
- if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
- RADEON_STATECHANGE( rmesa, fog );
- rmesa->hw.fog.cmd[FOG_C] = c.i;
- rmesa->hw.fog.cmd[FOG_D] = d.i;
- }
}
@@ -692,6 +681,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
+ GLuint flag = 0;
RADEON_STATECHANGE( rmesa, tcl );
@@ -730,13 +720,22 @@ static void radeonUpdateSpecular( GLcontext *ctx )
}
if (ctx->Fog.Enabled) {
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
-
- /* Bizzare: have to leave lighting enabled to get fog.
- */
- rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+ if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
+ /* Bizzare: have to leave lighting enabled to get fog. */
+ rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+ }
+ else {
+ /* cannot do tcl fog factor calculation with fog coord source
+ * (send precomputed factors). Cannot use precomputed fog
+ * factors together with tcl spec light (need tcl fallback) */
+ flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
+ RADEON_TCL_COMPUTE_SPECULAR) != 0;
+ }
}
+
+ TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
if (NEED_SECONDARY_COLOR(ctx)) {
assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
@@ -1809,8 +1808,6 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
}
radeonUpdateSpecular( ctx ); /* for PK_SPEC */
- if (rmesa->TclFallback)
- radeonChooseVertexState( ctx );
_mesa_allow_light_in_model( ctx, !state );
break;
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index 6e538a2973..6c0298a6f7 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -345,6 +345,7 @@ void radeonInitState( radeonContextPtr rmesa )
RADEON_RIGHT_HAND_CUBE_OGL */);
rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (RADEON_FOG_VERTEX |
+ /* this bit unused for vertex fog */
RADEON_FOG_USE_DEPTH);
rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000;
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index fb0f10a862..90383d4091 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -279,6 +279,88 @@ void radeonTclPrimitive( GLcontext *ctx,
}
}
+/**********************************************************************/
+/* Fog blend factor computation for hw tcl */
+/* same calculation used as in t_vb_fog.c */
+/**********************************************************************/
+
+#define FOG_EXP_TABLE_SIZE 256
+#define FOG_MAX (10.0)
+#define EXP_FOG_MAX .0006595
+#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE)
+static GLfloat exp_table[FOG_EXP_TABLE_SIZE];
+
+#if 1
+#define NEG_EXP( result, narg ) \
+do { \
+ GLfloat f = (GLfloat) (narg * (1.0/FOG_INCR)); \
+ GLint k = (GLint) f; \
+ if (k > FOG_EXP_TABLE_SIZE-2) \
+ result = (GLfloat) EXP_FOG_MAX; \
+ else \
+ result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]); \
+} while (0)
+#else
+#define NEG_EXP( result, narg ) \
+do { \
+ result = exp(-narg); \
+} while (0)
+#endif
+
+
+/**
+ * Initialize the exp_table[] lookup table for approximating exp().
+ */
+void
+radeonInitStaticFogData( void )
+{
+ GLfloat f = 0.0F;
+ GLint i = 0;
+ for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) {
+ exp_table[i] = (GLfloat) exp(-f);
+ }
+}
+
+
+/**
+ * Compute per-vertex fog blend factors from fog coordinates by
+ * evaluating the GL_LINEAR, GL_EXP or GL_EXP2 fog function.
+ * Fog coordinates are distances from the eye (typically between the
+ * near and far clip plane distances).
+ * Note the fog (eye Z) coords may be negative so we use ABS(z) below.
+ * Fog blend factors are in the range [0,1].
+ */
+float
+radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord )
+{
+ GLfloat end = ctx->Fog.End;
+ GLfloat d, temp;
+ const GLfloat z = FABSF(fogcoord);
+
+ switch (ctx->Fog.Mode) {
+ case GL_LINEAR:
+ if (ctx->Fog.Start == ctx->Fog.End)
+ d = 1.0F;
+ else
+ d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
+ temp = (end - z) * d;
+ return CLAMP(temp, 0.0F, 1.0F);
+ break;
+ case GL_EXP:
+ d = ctx->Fog.Density;
+ NEG_EXP( temp, d * z );
+ return temp;
+ break;
+ case GL_EXP2:
+ d = ctx->Fog.Density*ctx->Fog.Density;
+ NEG_EXP( temp, d * z * z );
+ return temp;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad fog mode in make_fog_coord");
+ return 0;
+ }
+}
/**********************************************************************/
/* Render pipeline stage */
@@ -314,7 +396,7 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
}
}
- if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+ if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) {
inputs |= VERT_BIT_FOG;
}
@@ -445,7 +527,8 @@ static char *fallbackStrings[] = {
"Texgen unit 0",
"Texgen unit 1",
"Texgen unit 2",
- "User disable"
+ "User disable",
+ "Fogcoord with separate specular lighting"
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.h b/src/mesa/drivers/dri/radeon/radeon_tcl.h
index 062c9fbb54..168ab958a2 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.h
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.h
@@ -46,7 +46,10 @@ extern void radeonEmitPrimitive( GLcontext *ctx, GLuint first, GLuint last,
GLuint flags );
extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
-
+
+extern void radeonInitStaticFogData( void );
+extern float radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord );
+
#define RADEON_TCL_FALLBACK_RASTER 0x1 /* rasterization */
#define RADEON_TCL_FALLBACK_UNFILLED 0x2 /* unfilled tris */
#define RADEON_TCL_FALLBACK_LIGHT_TWOSIDE 0x4 /* twoside tris */
@@ -55,6 +58,7 @@ extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define RADEON_TCL_FALLBACK_TEXGEN_1 0x20 /* texgen, unit 1 */
#define RADEON_TCL_FALLBACK_TEXGEN_2 0x40 /* texgen, unit 2 */
#define RADEON_TCL_FALLBACK_TCL_DISABLE 0x80 /* user disable */
+#define RADEON_TCL_FALLBACK_FOGCOORDSPEC 0x100 /* fogcoord, sep. spec light */
/* max maos_verts vertex format has a size of 18 floats */
#define RADEON_MAX_TCL_VERTSIZE (18*4)
diff --git a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
index e554aeb330..c734ab8d5a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
+++ b/src/mesa/drivers/dri/radeon/radeon_vtxfmt.c
@@ -549,7 +549,8 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
GLuint ind = RADEON_CP_VC_FRMT_Z;
GLuint unit;
- if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag)
+ if (rmesa->TclFallback || rmesa->vb.fell_back || ctx->CompileFlag ||
+ (ctx->Fog.Enabled && (ctx->Fog.FogCoordinateSource == GL_FOG_COORD)))
return GL_FALSE;
if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT)
@@ -582,6 +583,10 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
}
}
+ if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD ) {
+ ind |= RADEON_CP_VC_FRMT_PKSPEC;
+ }
+
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
if (ctx->Texture.Unit[unit].TexGenEnabled) {
@@ -657,6 +662,9 @@ static GLboolean check_vtx_fmt( GLcontext *ctx )
UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->red, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0] );
UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->green, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1] );
UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->blue, ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2] );
+ /* fog ??? */
+/* UNCLAMPED_FLOAT_TO_CHAN( rmesa->vb.specptr->alpha,
+ radeonComputeFogFactor(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]) ); */
}
for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
@@ -948,8 +956,6 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
/* Not active in supported states; just keep ctx->Current uptodate:
*/
- vfmt->FogCoordfvEXT = _mesa_noop_FogCoordfvEXT;
- vfmt->FogCoordfEXT = _mesa_noop_FogCoordfEXT;
vfmt->EdgeFlag = _mesa_noop_EdgeFlag;
vfmt->EdgeFlagv = _mesa_noop_EdgeFlagv;
vfmt->Indexf = _mesa_noop_Indexf;
@@ -986,6 +992,8 @@ void radeonVtxfmtInit( GLcontext *ctx, GLboolean useCodegen )
vfmt->VertexAttrib3fvNV = radeon_fallback_VertexAttrib3fvNV;
vfmt->VertexAttrib4fNV = radeon_fallback_VertexAttrib4fNV;
vfmt->VertexAttrib4fvNV = radeon_fallback_VertexAttrib4fvNV;
+ vfmt->FogCoordfEXT = radeon_fallback_FogCoordfEXT;
+ vfmt->FogCoordfvEXT = radeon_fallback_FogCoordfvEXT;
(void)radeon_fallback_vtxfmt;