[Mesa-dev] [PATCH] mesa: do not skip att and spot calculation for infinite light

Brian Paul brianp at vmware.com
Tue Nov 15 06:22:29 PST 2011


On 11/15/2011 12:11 AM, Yuanhan Liu wrote:
> glspec doesn't say that we should skip the attenuation and spot
> calculation for infinite light(Ppli.w == 0). Instead, it gives a same
> formula to do the light calculation for both finite light and infinite
> light(see page 62 of glspec 2.1.pdf)
>
> Also from the formula (2.4) at page 62 of glspec 2.1.pdf, we can skip
> attenuation calculation if Ppli.w == 0.
>
> This would fix all the intel oglc l_sed fail subcases and introduces no
> intel oglc regressions.
>
> Signed-off-by: Yuanhan Liu<yuanhan.liu at linux.intel.com>
> ---
>   src/mesa/main/ffvertex_prog.c |  115 ++++++++++++++++++-----------------------
>   1 files changed, 51 insertions(+), 64 deletions(-)
>
> diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
> index 8469078..fd53bc4 100644
> --- a/src/mesa/main/ffvertex_prog.c
> +++ b/src/mesa/main/ffvertex_prog.c
> @@ -949,7 +949,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
>   {
>      struct ureg attenuation = register_param3(p, STATE_LIGHT, i,
>   					     STATE_ATTENUATION);
> -   struct ureg att = get_temp(p);
> +   struct ureg att = undef;
>
>      /* Calculate spot attenuation:
>       */
> @@ -959,6 +959,8 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
>         struct ureg spot = get_temp(p);
>         struct ureg slt = get_temp(p);
>
> +      att = get_temp(p);
> +
>         emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm);
>         emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
>         emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
> @@ -968,9 +970,13 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
>         release_temp(p, slt);
>      }
>
> -   /* Calculate distance attenuation:
> +   /* Calculate distance attenuation(See formula (2.4) at glspec 2.1 page 62):
> +    *
> +    * Skip the calucation when _dist_ is undefined(light_eyepos3_is_zero)
>       */
> -   if (p->state->unit[i].light_attenuated) {
> +   if (p->state->unit[i].light_attenuated&&  !is_undef(dist)) {
> +      if (is_undef(att))
> +         att = get_temp(p);
>         /* 1/d,d,d,1/d */
>         emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist);
>         /* 1,d,d*d,1/d */
> @@ -1113,73 +1119,54 @@ static void build_lighting( struct tnl_program *p )
>         if (p->state->unit[i].light_enabled) {
>   	 struct ureg half = undef;
>   	 struct ureg att = undef, VPpli = undef;
> +	 struct ureg dist = undef;
>
>   	 count++;
> +         if (p->state->unit[i].light_eyepos3_is_zero) {
> +             VPpli = register_param3(p, STATE_INTERNAL,
> +                                     STATE_LIGHT_POSITION_NORMALIZED, i);
> +         } else {
> +            struct ureg Ppli = register_param3(p, STATE_INTERNAL,
> +                                               STATE_LIGHT_POSITION, i);
> +            struct ureg V = get_eye_position(p);
> +
> +            VPpli = get_temp(p);
> +            dist = get_temp(p);
> +
> +            /* Calculate VPpli vector
> +             */
> +            emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V);
>
> -	 if (p->state->unit[i].light_eyepos3_is_zero) {
> -	    /* Can used precomputed constants in this case.
> -	     * Attenuation never applies to infinite lights.
> -	     */
> -	    VPpli = register_param3(p, STATE_INTERNAL,
> -				    STATE_LIGHT_POSITION_NORMALIZED, i);
> -
> -            if (!p->state->material_shininess_is_zero) {
> -               if (p->state->light_local_viewer) {
> -                  struct ureg eye_hat = get_eye_position_normalized(p);
> -                  half = get_temp(p);
> -                  emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
> -                  emit_normalize_vec3(p, half, half);
> -               }
> -               else {
> -                  half = register_param3(p, STATE_INTERNAL,
> -                                         STATE_LIGHT_HALF_VECTOR, i);
> -               }
> -            }
> -	 }
> -	 else {
> -	    struct ureg Ppli = register_param3(p, STATE_INTERNAL,
> -					       STATE_LIGHT_POSITION, i);
> -	    struct ureg V = get_eye_position(p);
> -	    struct ureg dist = get_temp(p);
> -
> -	    VPpli = get_temp(p);
> -
> -	    /* Calculate VPpli vector
> -	     */
> -	    emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V);
> -
> -	    /* Normalize VPpli.  The dist value also used in
> -	     * attenuation below.
> -	     */
> -	    emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli);
> -	    emit_op1(p, OPCODE_RSQ, dist, 0, dist);
> -	    emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);
> -
> -	    /* Calculate attenuation:
> -	     */
> -	    if (!p->state->unit[i].light_spotcutoff_is_180 ||
> -		p->state->unit[i].light_attenuated) {
> -	       att = calculate_light_attenuation(p, i, VPpli, dist);
> -	    }
> -
> -	    /* Calculate viewer direction, or use infinite viewer:
> -	     */
> -            if (!p->state->material_shininess_is_zero) {
> -               half = get_temp(p);
> +            /* Normalize VPpli.  The dist value also used in
> +             * attenuation below.
> +             */
> +            emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli);
> +            emit_op1(p, OPCODE_RSQ, dist, 0, dist);
> +            emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist);
> +         }
>
> -               if (p->state->light_local_viewer) {
> -                  struct ureg eye_hat = get_eye_position_normalized(p);
> -                  emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
> -               }
> -               else {
> -                  struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z);
> -                  emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir);
> -               }
> +         /* Calculate attenuation:
> +          */
> +         att = calculate_light_attenuation(p, i, VPpli, dist);
> +         release_temp(p, dist);
>
> +	 /* Calculate viewer direction, or use infinite viewer:
> +	  */
> +         if (!p->state->material_shininess_is_zero) {
> +            if (p->state->light_local_viewer) {
> +               struct ureg eye_hat = get_eye_position_normalized(p);
> +               half = get_temp(p);
> +               emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat);
> +               emit_normalize_vec3(p, half, half);
> +            } else if (p->state->unit[i].light_eyepos3_is_zero) {
> +               half = register_param3(p, STATE_INTERNAL,
> +                                      STATE_LIGHT_HALF_VECTOR, i);
> +	    } else {
> +               struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z);
> +               half = get_temp(p);
> +               emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir);
>                  emit_normalize_vec3(p, half, half);
>               }

The indentation of 'else' above looks wrong.

> -
> -	    release_temp(p, dist);
>   	 }
>
>   	 /* Calculate dot products:

Acked-by: Brian Paul <brianp at vmware.com>


More information about the mesa-dev mailing list