From 3e21a014c308a87e1dd7bdabba255aad02d3ad1b Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 22 May 2007 03:29:59 +0200 Subject: fog: fix issues with negative fog coords (may fix #10529) Rework tnl fog a bit. Make sure we always use ABS(eyez) when fog coord source is depth, OTOH it does not seem to be necessary to use it (as was done before in some cases) if fog coord source is fogcoord (just to save some work). This fixes tests/fog (the first 2 cases) with i915/i915tex. --- src/mesa/tnl/t_vb_fog.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src/mesa/tnl') diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 5440ff7894..f6518500d8 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -114,7 +114,7 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in) else d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; GLfloat f = (end - z) * d; data[i][0] = CLAMP(f, 0.0F, 1.0F); } @@ -122,14 +122,14 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in) case GL_EXP: d = ctx->Fog.Density; for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; NEG_EXP( data[i][0], d * z ); } break; case GL_EXP2: d = ctx->Fog.Density*ctx->Fog.Density; for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; NEG_EXP( data[i][0], d * z * z ); } break; @@ -153,6 +153,8 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { + GLuint i; + GLfloat *coord; /* Fog is computed from vertex or fragment Z values */ /* source = VB->ObjPtr or VB->EyePtr coords */ /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */ @@ -168,6 +170,8 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) input = &store->fogcoord; /* NOTE: negate plane here so we get positive fog coords! */ + /* NOTE2: this doesn't always work (tests/fog - all frag depth fog + coords will be negative). */ plane[0] = -m[2]; plane[1] = -m[6]; plane[2] = -m[10]; @@ -180,18 +184,29 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) VB->ObjPtr, plane ); input->count = VB->ObjPtr->count; + + /* make sure coords are really positive + NOTE should avoid going through array twice */ + coord = input->start; + for (i = 0; i < input->count; i++) { + input->data[i][0] = FABSF(*coord); + STRIDE_F(coord, input->stride); + } } else { /* fog coordinates = eye Z coordinates (use ABS later) */ - input = &store->input; + input = &store->fogcoord; if (VB->EyePtr->size < 2) _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 ); - input->data = (GLfloat (*)[4]) &(VB->EyePtr->data[0][2]); - input->start = VB->EyePtr->start+2; - input->stride = VB->EyePtr->stride; + input->stride = 4 * sizeof(GLfloat); input->count = VB->EyePtr->count; + coord = VB->EyePtr->start; + for (i = 0 ; i < VB->EyePtr->count; i++) { + input->data[i][0] = FABSF(coord[2]); + STRIDE_F(coord, VB->EyePtr->stride); + } } } else { -- cgit v1.2.3 From 74a30c351fe98f41150dfe81a6aba05087997206 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 22 May 2007 03:30:09 +0200 Subject: fog: fix potential issues with generated vp using fog Change the generated vertex programs (tnl/brw) to follow the same logic as the tnl fog wrt using absolute value, and sync them up a bit (untested). --- src/mesa/drivers/dri/i965/brw_vs_tnl.c | 22 ++++++++++++++-------- src/mesa/tnl/t_vp_build.c | 23 +++++++++++++++-------- 2 files changed, 29 insertions(+), 16 deletions(-) (limited to 'src/mesa/tnl') diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 35adc4846a..b69be350a9 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1154,7 +1154,9 @@ static void build_fog( struct tnl_program *p ) { struct ureg fog = register_output(p, VERT_RESULT_FOGC); struct ureg input; - + GLuint useabs = p->state->fog_source_is_depth && p->state->fog_option && + (p->state->fog_option != FOG_EXP2); + if (p->state->fog_source_is_depth) { input = swizzle1(get_eye_position(p), Z); } @@ -1171,26 +1173,30 @@ static void build_fog( struct tnl_program *p ) emit_op1(p, OPCODE_MOV, fog, 0, id); + if (useabs) { + emit_op1(p, OPCODE_ABS, tmp, 0, input); + } + switch (p->state->fog_option) { case FOG_LINEAR: { - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op3(p, OPCODE_MAD, tmp, 0, tmp, swizzle1(params,X), swizzle1(params,Y)); + emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, + swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, + swizzle1(params,Z)); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp)); break; case FOG_EXP2: emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp)); break; } - + release_temp(p, tmp); } else { @@ -1198,7 +1204,7 @@ static void build_fog( struct tnl_program *p ) * * KW: Is it really necessary to do anything in this case? */ - emit_op1(p, OPCODE_MOV, fog, 0, input); + emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, 0, input); } } diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index dff062a417..2a1cae77f2 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -1103,7 +1103,9 @@ static void build_fog( struct tnl_program *p ) { struct ureg fog = register_output(p, VERT_RESULT_FOGC); struct ureg input; - + GLuint useabs = p->state->fog_source_is_depth && p->state->fog_mode && + (p->state->fog_mode != FOG_EXP2); + if (p->state->fog_source_is_depth) { input = swizzle1(get_eye_position(p), Z); } @@ -1111,31 +1113,36 @@ static void build_fog( struct tnl_program *p ) input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); } - if (p->state->tnl_do_vertex_fog) { + if (p->state->fog_mode && p->state->tnl_do_vertex_fog) { struct ureg params = register_param2(p, STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED); struct ureg tmp = get_temp(p); + if (useabs) { + emit_op1(p, OPCODE_ABS, tmp, 0, input); + } + switch (p->state->fog_mode) { case FOG_LINEAR: { struct ureg id = get_identity_param(p); - emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y)); + emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, + swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, + swizzle1(params,Z)); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; case FOG_EXP2: emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; } - + release_temp(p, tmp); } else { @@ -1143,7 +1150,7 @@ static void build_fog( struct tnl_program *p ) * * KW: Is it really necessary to do anything in this case? */ - emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input); + emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input); } } -- cgit v1.2.3 From d062b6cd2672f42fdfe20f6d932aacef9895aebc Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 23 May 2007 08:58:08 -0600 Subject: Fix point attentuation problem (bug 11042) ctx->Point._Attentuation was computed in wrong place and the VB->Eye coord Z array wasn't indexed correctly in run_point_stage(). --- src/mesa/main/points.c | 11 +++++------ src/mesa/tnl/t_vb_points.c | 10 ++++++---- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'src/mesa/tnl') diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 9caa9ab3ab..8674c7299c 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.0 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -61,10 +61,6 @@ _mesa_PointSize( GLfloat size ) ctx->Point.MinSize, ctx->Point.MaxSize); - ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || - ctx->Point.Params[1] != 0.0 || - ctx->Point.Params[2] != 0.0); - if (ctx->Driver.PointSize) ctx->Driver.PointSize(ctx, size); } @@ -122,6 +118,9 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) return; FLUSH_VERTICES(ctx, _NEW_POINT); COPY_3V(ctx->Point.Params, params); + ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || + ctx->Point.Params[1] != 0.0 || + ctx->Point.Params[2] != 0.0); } else { _mesa_error(ctx, GL_INVALID_ENUM, diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c index 9327f8c273..1ac14fedf9 100644 --- a/src/mesa/tnl/t_vb_points.c +++ b/src/mesa/tnl/t_vb_points.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.0 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -50,7 +50,8 @@ run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) { struct point_stage_data *store = POINT_STAGE_DATA(stage); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data; + const GLfloat *eyeCoord = (GLfloat *) VB->EyePtr->data + 2; + const GLint eyeCoordStride = VB->EyePtr->stride / sizeof(GLfloat); const GLfloat p0 = ctx->Point.Params[0]; const GLfloat p1 = ctx->Point.Params[1]; const GLfloat p2 = ctx->Point.Params[2]; @@ -59,10 +60,11 @@ run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) GLuint i; for (i = 0; i < VB->Count; i++) { - const GLfloat dist = FABSF(eye[i][2]); + const GLfloat dist = FABSF(*eyeCoord); const GLfloat q = p0 + dist * (p1 + dist * p2); const GLfloat atten = (q != 0.0) ? SQRTF(1.0 / q) : 1.0; size[i][0] = pointSize * atten; /* clamping done in rasterization */ + eyeCoord += eyeCoordStride; } VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize; -- cgit v1.2.3