fog: fix potential issues with generated vp using fog
authorRoland Scheidegger <sroland@tungstengraphics.com>
Tue, 22 May 2007 01:30:09 +0000 (03:30 +0200)
committerRoland Scheidegger <sroland@tungstengraphics.com>
Tue, 22 May 2007 01:32:25 +0000 (03:32 +0200)
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
src/mesa/tnl/t_vp_build.c

index 35adc4846a0744aa7d899f7a338daf65f0c7aa82..b69be350a92b7bc34c66fd27ddbe783257517bbe 100644 (file)
@@ -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);
    }
 }
  
index dff062a417c8277c1d0835d398e0baca606f3c54..2a1cae77f29feda7c9379d358158d1e1d865dfde 100644 (file)
@@ -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);
    }
 }