Ejemplo n.º 1
0
static GLboolean update_tex_common( GLcontext *ctx, int unit )
{
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
   const int source = rmesa->tmu_source[unit];
   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
   const struct gl_texture_object *tObj = texUnit->_Current;
   r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;


   /* Fallback if there's a texture border */
   if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
      return GL_FALSE;
   }


   /* Update state if this is a different texture object to last
    * time.
    */
   if ( rmesa->CurrentTexObj[unit] != t ) {
      if ( rmesa->CurrentTexObj[unit] != NULL ) {
	 /* The old texture is no longer bound to this texture unit.
	  * Mark it as such.
	  */

	 rmesa->CurrentTexObj[unit]->base.bound &= 
	     ~(1UL << unit);
      }

      rmesa->CurrentTexObj[unit] = t;
      t->base.bound |= (1UL << unit);
      rmesa->dirty |= R128_UPLOAD_TEX0 << unit;

      driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
   }

   /* FIXME: We need to update the texture unit if any texture parameters have
    * changed, but this texture was already bound.  This could be changed to
    * work like the Radeon driver where the texture object has it's own
    * dirty state flags
    */
   rmesa->dirty |= R128_UPLOAD_TEX0 << unit;

   /* register setup */
   rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << 
				      (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit));

   if ( unit == 0 ) {
      rmesa->setup.tex_cntl_c       |= R128_TEXMAP_ENABLE;
      rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0;
      rmesa->setup.scale_3d_cntl    &= ~R128_TEX_CACHE_SPLIT;
      t->setup.tex_cntl             &= ~R128_SEC_SELECT_SEC_ST;
   }
   else {
      rmesa->setup.tex_cntl_c       |= R128_SEC_TEXMAP_ENABLE;
      rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16;
      rmesa->setup.scale_3d_cntl    |= R128_TEX_CACHE_SPLIT;
      t->setup.tex_cntl             |=  R128_SEC_SELECT_SEC_ST;

      /* If the second TMU is enabled, then multitexturing is happening.
       */
      if ( R128_IS_PLAIN( rmesa ) )
	  rmesa->blend_flags            |= R128_BLEND_MULTITEX;
   }

   rmesa->dirty |= R128_UPLOAD_CONTEXT;


   /* FIXME: The Radeon has some cached state so that it can avoid calling
    * FIXME: UpdateTextureEnv in some cases.  Is that possible here?
    */
   return r128UpdateTextureEnv( ctx, unit );
}
Ejemplo n.º 2
0
static void r128TexEnv( GLcontext *ctx, GLenum target,
			  GLenum pname, const GLfloat *param )
{
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
   struct gl_texture_unit *texUnit;
   GLubyte c[4];

   if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s( %s )\n",
	       __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
   }

   switch ( pname ) {
   case GL_TEXTURE_ENV_MODE:
      FLUSH_BATCH( rmesa );
      rmesa->new_state |= R128_NEW_ALPHA;
      break;

   case GL_TEXTURE_ENV_COLOR:
      texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
      CLAMPED_FLOAT_TO_UBYTE( c[0], texUnit->EnvColor[0] );
      CLAMPED_FLOAT_TO_UBYTE( c[1], texUnit->EnvColor[1] );
      CLAMPED_FLOAT_TO_UBYTE( c[2], texUnit->EnvColor[2] );
      CLAMPED_FLOAT_TO_UBYTE( c[3], texUnit->EnvColor[3] );
      rmesa->env_color = r128PackColor( 4, c[0], c[1], c[2], c[3] );
      if ( rmesa->setup.constant_color_c != rmesa->env_color ) {
	 FLUSH_BATCH( rmesa );
	 rmesa->setup.constant_color_c = rmesa->env_color;

	 /* More complex multitexture/multipass fallbacks for GL_BLEND
	  * can be done later, but this allows a single pass GL_BLEND
	  * in some cases (ie. Performer town demo).  This is only
	  * applicable to the regular Rage 128, as the Pro and M3 can
	  * handle true single-pass GL_BLEND texturing.
	  */
	 rmesa->blend_flags &= ~R128_BLEND_ENV_COLOR;
	 if ( R128_IS_PLAIN( rmesa ) &&
	      rmesa->env_color != 0x00000000 &&
	      rmesa->env_color != 0xff000000 &&
	      rmesa->env_color != 0x00ffffff &&
	      rmesa->env_color != 0xffffffff ) {
	    rmesa->blend_flags |= R128_BLEND_ENV_COLOR;
	 }
      }
      break;

   case GL_TEXTURE_LOD_BIAS:
      {
	 uint32_t t = rmesa->setup.tex_cntl_c;
	 GLint bias;
	 uint32_t b;

	 /* GTH: This isn't exactly correct, but gives good results up to a
	  * certain point.  It is better than completely ignoring the LOD
	  * bias.  Unfortunately there isn't much range in the bias, the
	  * spec mentions strides that vary between 0.5 and 2.0 but these
	  * numbers don't seem to relate to the GL LOD bias value at all.
	  */
	 if ( param[0] >= 1.0 ) {
	    bias = -128;
	 } else if ( param[0] >= 0.5 ) {
	    bias = -64;
	 } else if ( param[0] >= 0.25 ) {
	    bias = 0;
	 } else if ( param[0] >= 0.0 ) {
	    bias = 63;
	 } else {
	    bias = 127;
	 }

	 b = (uint32_t)bias & 0xff;
	 t &= ~R128_LOD_BIAS_MASK;
	 t |= (b << R128_LOD_BIAS_SHIFT);

	 if ( rmesa->setup.tex_cntl_c != t ) {
	    FLUSH_BATCH( rmesa );
	    rmesa->setup.tex_cntl_c = t;
	    rmesa->dirty |= R128_UPLOAD_CONTEXT;
	 }
      }
      break;

   default:
      return;
   }
}
Ejemplo n.º 3
0
static GLboolean r128UpdateTextureEnv( GLcontext *ctx, int unit )
{
   r128ContextPtr rmesa = R128_CONTEXT(ctx);
   GLint source = rmesa->tmu_source[unit];
   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
   const struct gl_texture_object *tObj = texUnit->_Current;
   const GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
   GLuint combine;

   if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
      fprintf( stderr, "%s( %p, %d )\n",
	       __FUNCTION__, (void *) ctx, unit );
   }

   if ( unit == 0 ) {
      combine = INPUT_INTERP;
   } else {
      combine = INPUT_PREVIOUS;
   }

   /* Set the texture environment state */
   switch ( texUnit->EnvMode ) {
   case GL_REPLACE:
      switch ( format ) {
      case GL_RGBA:
      case GL_LUMINANCE_ALPHA:
      case GL_INTENSITY:
	 combine |= (COLOR_COMB_DISABLE |		/* C = Ct            */
		     ALPHA_COMB_DISABLE);		/* A = At            */
	 break;
      case GL_RGB:
      case GL_LUMINANCE:
	 combine |= (COLOR_COMB_DISABLE |		/* C = Ct            */
		     ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 break;
      case GL_ALPHA:
	 combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
		     ALPHA_COMB_DISABLE);		/* A = At            */
	 break;
      case GL_COLOR_INDEX:
      default:
	 return GL_FALSE;
      }
      break;

   case GL_MODULATE:
      switch ( format ) {
      case GL_RGBA:
      case GL_LUMINANCE_ALPHA:
      case GL_INTENSITY:
	 combine |= (COLOR_COMB_MODULATE |		/* C = CfCt          */
		     ALPHA_COMB_MODULATE);		/* A = AfAt          */
	 break;
      case GL_RGB:
      case GL_LUMINANCE:
	 combine |= (COLOR_COMB_MODULATE |		/* C = CfCt          */
		     ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 break;
      case GL_ALPHA:
	 combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
		     ALPHA_COMB_MODULATE);		/* A = AfAt          */
	 break;
      case GL_COLOR_INDEX:
      default:
	 return GL_FALSE;
      }
      break;

   case GL_DECAL:
      switch ( format ) {
      case GL_RGBA:
	 combine |= (COLOR_COMB_BLEND_TEX |		/* C = Cf(1-At)+CtAt */
		     ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 break;
      case GL_RGB:
	 combine |= (COLOR_COMB_DISABLE |		/* C = Ct            */
		     ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 break;
      case GL_ALPHA:
      case GL_LUMINANCE:
      case GL_LUMINANCE_ALPHA:
      case GL_INTENSITY:
	 /* Undefined behaviour - just copy the incoming fragment */
	 combine |= (COLOR_COMB_COPY_INPUT |		/* C = undefined     */
		     ALPHA_COMB_COPY_INPUT);		/* A = undefined     */
	 break;
      case GL_COLOR_INDEX:
      default:
	 return GL_FALSE;
      }
      break;

   case GL_BLEND:
      /* Rage 128 Pro and M3 can handle GL_BLEND texturing.
       */
      if ( !R128_IS_PLAIN( rmesa ) ) {
         /* XXX this hasn't been fully tested, I don't have a Pro card. -BP */
	 switch ( format ) {
	 case GL_RGBA:
	 case GL_LUMINANCE_ALPHA:
	    combine |= (COLOR_COMB_BLEND_COLOR |	/* C = Cf(1-Ct)+CcCt */
			ALPHA_COMB_MODULATE);		/* A = AfAt          */
	    break;

	 case GL_RGB:
	 case GL_LUMINANCE:
	    combine |= (COLOR_COMB_BLEND_COLOR |	/* C = Cf(1-Ct)+CcCt */
			ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	    break;

	 case GL_ALPHA:
	    combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
			ALPHA_COMB_MODULATE);		/* A = AfAt          */
	    break;

	 case GL_INTENSITY:
	    /* GH: We could be smarter about this... */
	    switch ( rmesa->env_color & 0xff000000 ) {
	    case 0x00000000:
	       combine |= (COLOR_COMB_BLEND_COLOR |	/* C = Cf(1-It)+CcIt */
			   ALPHA_COMB_MODULATE_NTEX);	/* A = Af(1-It)      */
	    default:
	       combine |= (COLOR_COMB_MODULATE |	/* C = fallback      */
			   ALPHA_COMB_MODULATE);	/* A = fallback      */
	       return GL_FALSE;
	    }
	    break;

	 case GL_COLOR_INDEX:
	 default:
	    return GL_FALSE;
	 }
	 break;
      }

      /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback
       * to software rendering.
       */
      if ( rmesa->blend_flags ) {
	 return GL_FALSE;
      }
      switch ( format ) {
      case GL_RGBA:
      case GL_LUMINANCE_ALPHA:
	 switch ( rmesa->env_color & 0x00ffffff ) {
	 case 0x00000000:
	    combine |= (COLOR_COMB_MODULATE_NTEX |	/* C = Cf(1-Ct)      */
			ALPHA_COMB_MODULATE);		/* A = AfAt          */
	    break;
#if 0
         /* This isn't right - BP */
	 case 0x00ffffff:
	    if ( unit == 0 ) {
	       combine |= (COLOR_COMB_MODULATE_NTEX |	/* C = Cf(1-Ct)      */
			   ALPHA_COMB_MODULATE);	/* A = AfAt          */
	    } else {
	       combine |= (COLOR_COMB_ADD |		/* C = Cf+Ct         */
			   ALPHA_COMB_COPY_INPUT);	/* A = Af            */
	    }
	    break;
#endif
	 default:
	    combine |= (COLOR_COMB_MODULATE |		/* C = fallback      */
			ALPHA_COMB_MODULATE);		/* A = fallback      */
	    return GL_FALSE;
	 }
	 break;
      case GL_RGB:
      case GL_LUMINANCE:
	 switch ( rmesa->env_color & 0x00ffffff ) {
	 case 0x00000000:
	    combine |= (COLOR_COMB_MODULATE_NTEX |	/* C = Cf(1-Ct)      */
			ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	    break;
#if 0
         /* This isn't right - BP */
	 case 0x00ffffff:
	    if ( unit == 0 ) {
	       combine |= (COLOR_COMB_MODULATE_NTEX |	/* C = Cf(1-Ct)      */
			   ALPHA_COMB_COPY_INPUT);	/* A = Af            */
	    } else {
	       combine |= (COLOR_COMB_ADD |		/* C = Cf+Ct         */
			   ALPHA_COMB_COPY_INPUT);	/* A = Af            */
	    }
	    break;
#endif
	 default:
	    combine |= (COLOR_COMB_MODULATE |		/* C = fallback      */
			ALPHA_COMB_COPY_INPUT);		/* A = fallback      */
	    return GL_FALSE;
	 }
	 break;
      case GL_ALPHA:
	 if ( unit == 0 ) {
	    combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
			ALPHA_COMB_MODULATE);		/* A = AfAt          */
	 } else {
	    combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
			ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 }
	 break;
      case GL_INTENSITY:
	 switch ( rmesa->env_color & 0x00ffffff ) {
	 case 0x00000000:
	    combine |= COLOR_COMB_MODULATE_NTEX;	/* C = Cf(1-It)      */
	    break;
#if 0
         /* This isn't right - BP */
	 case 0x00ffffff:
	    if ( unit == 0 ) {
	       combine |= COLOR_COMB_MODULATE_NTEX;	/* C = Cf(1-It)      */
	    } else {
	       combine |= COLOR_COMB_ADD;		/* C = Cf+It         */
	    }
	    break;
#endif
	 default:
	    combine |= (COLOR_COMB_MODULATE |		/* C = fallback      */
			ALPHA_COMB_MODULATE);		/* A = fallback      */
	    return GL_FALSE;
	 }
	 switch ( rmesa->env_color & 0xff000000 ) {
	 case 0x00000000:
	    combine |= ALPHA_COMB_MODULATE_NTEX;	/* A = Af(1-It)      */
	    break;
#if 0
         /* This isn't right - BP */
	 case 0xff000000:
	    if ( unit == 0 ) {
	       combine |= ALPHA_COMB_MODULATE_NTEX;	/* A = Af(1-It)      */
	    } else {
	       combine |= ALPHA_COMB_ADD;		/* A = Af+It         */
	    }
	    break;
#endif
	 default:
	    combine |= (COLOR_COMB_MODULATE |		/* C = fallback      */
			ALPHA_COMB_MODULATE);		/* A = fallback      */
	    return GL_FALSE;
	 }
	 break;
      case GL_COLOR_INDEX:
      default:
	 return GL_FALSE;
      }
      break;

   case GL_ADD:
      switch ( format ) {
      case GL_RGBA:
      case GL_LUMINANCE_ALPHA:
	 combine |= (COLOR_COMB_ADD |			/* C = Cf+Ct         */
		     ALPHA_COMB_MODULATE);		/* A = AfAt          */
	 break;
      case GL_RGB:
      case GL_LUMINANCE:
	 combine |= (COLOR_COMB_ADD |			/* C = Cf+Ct         */
		     ALPHA_COMB_COPY_INPUT);		/* A = Af            */
	 break;
      case GL_ALPHA:
	 combine |= (COLOR_COMB_COPY_INPUT |		/* C = Cf            */
		     ALPHA_COMB_MODULATE);		/* A = AfAt          */
	 break;
      case GL_INTENSITY:
	 combine |= (COLOR_COMB_ADD |			/* C = Cf+Ct         */
		     ALPHA_COMB_ADD);			/* A = Af+At         */
	 break;
      case GL_COLOR_INDEX:
      default:
	 return GL_FALSE;
      }
      break;

   default:
      return GL_FALSE;
   }

   if ( rmesa->tex_combine[unit] != combine ) {
     rmesa->tex_combine[unit] = combine;
     rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
   }
   return GL_TRUE;
}