⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texenvprogram.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
   p->temp_in_use |= 1<<(bit-1);
   return make_ureg(PROGRAM_TEMPORARY, (bit-1));
}


static void release_temps( struct texenv_fragment_program *p )
{
   GLuint max_temp = p->ctx->Const.MaxFragmentProgramTemps;

   /* KW: To support tex_env_crossbar, don't release the registers in
    * temps_output.
    */
   if (max_temp >= sizeof(int) * 8)
      p->temp_in_use = p->temps_output;
   else
      p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output;
}


static struct ureg register_param6( struct texenv_fragment_program *p, 
				    GLint s0,
				    GLint s1,
				    GLint s2,
				    GLint s3,
				    GLint s4,
				    GLint s5)
{
   GLint tokens[6];
   GLuint idx;
   tokens[0] = s0;
   tokens[1] = s1;
   tokens[2] = s2;
   tokens[3] = s3;
   tokens[4] = s4;
   tokens[5] = s5;
   idx = _mesa_add_state_reference( p->program->Parameters, tokens );
   return make_ureg(PROGRAM_STATE_VAR, idx);
}


#define register_param1(p,s0)          register_param6(p,s0,0,0,0,0,0)
#define register_param2(p,s0,s1)       register_param6(p,s0,s1,0,0,0,0)
#define register_param3(p,s0,s1,s2)    register_param6(p,s0,s1,s2,0,0,0)
#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)


static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
{
   p->program->InputsRead |= (1<<input);
   return make_ureg(PROGRAM_INPUT, input);
}


static void emit_arg( struct fp_src_register *reg,
		      struct ureg ureg )
{
   reg->File = ureg.file;
   reg->Index = ureg.idx;
   reg->Swizzle = ureg.swz;
   reg->NegateBase = ureg.negatebase;
   reg->Abs = ureg.abs;
   reg->NegateAbs = ureg.negateabs;
}

static void emit_dst( struct fp_dst_register *dst,
		      struct ureg ureg, GLuint mask )
{
   dst->File = ureg.file;
   dst->Index = ureg.idx;
   dst->WriteMask = mask;
   dst->CondMask = 0;
   dst->CondSwizzle = 0;
}

static struct fp_instruction *
emit_op(struct texenv_fragment_program *p,
	GLuint op,
	struct ureg dest,
	GLuint mask,
	GLuint saturate,
	struct ureg src0,
	struct ureg src1,
	struct ureg src2 )
{
   GLuint nr = p->program->Base.NumInstructions++;
   struct fp_instruction *inst = &p->program->Instructions[nr];
      
   memset(inst, 0, sizeof(*inst));
   inst->Opcode = op;
   
   emit_arg( &inst->SrcReg[0], src0 );
   emit_arg( &inst->SrcReg[1], src1 );
   emit_arg( &inst->SrcReg[2], src2 );
   
   inst->Saturate = saturate;

   emit_dst( &inst->DstReg, dest, mask );

   /* Accounting for indirection tracking:
    */
   if (dest.file == PROGRAM_TEMPORARY)
      p->temps_output |= 1 << dest.idx;

   return inst;
}
   

static struct ureg emit_arith( struct texenv_fragment_program *p,
			       GLuint op,
			       struct ureg dest,
			       GLuint mask,
			       GLuint saturate,
			       struct ureg src0,
			       struct ureg src1,
			       struct ureg src2 )
{
   emit_op(p, op, dest, mask, saturate, src0, src1, src2);
   
   /* Accounting for indirection tracking:
    */
   if (src0.file == PROGRAM_TEMPORARY)
      p->alu_temps |= 1 << src0.idx;

   if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY)
      p->alu_temps |= 1 << src1.idx;

   if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY)
      p->alu_temps |= 1 << src2.idx;

   if (dest.file == PROGRAM_TEMPORARY)
      p->alu_temps |= 1 << dest.idx;
       
   p->program->NumAluInstructions++;
   return dest;
}

static struct ureg emit_texld( struct texenv_fragment_program *p,
			       GLuint op,
			       struct ureg dest,
			       GLuint destmask,
			       GLuint tex_unit,
			       GLuint tex_idx,
			       struct ureg coord )
{
   struct fp_instruction *inst = emit_op( p, op, 
					  dest, destmask, 
					  0,		/* don't saturate? */
					  coord, 	/* arg 0? */
					  undef,
					  undef);
   
   inst->TexSrcIdx = tex_idx;
   inst->TexSrcUnit = tex_unit;

   p->program->NumTexInstructions++;

   /* Is this a texture indirection?
    */
   if ((coord.file == PROGRAM_TEMPORARY &&
	(p->temps_output & (1<<coord.idx))) ||
       (dest.file == PROGRAM_TEMPORARY &&
	(p->alu_temps & (1<<dest.idx)))) {
      p->program->NumTexIndirections++;
      p->temps_output = 1<<coord.idx;
      p->alu_temps = 0;
      assert(0);		/* KW: texture env crossbar */
   }

   return dest;
}


static struct ureg register_const4f( struct texenv_fragment_program *p, 
				     GLfloat s0,
				     GLfloat s1,
				     GLfloat s2,
				     GLfloat s3)
{
   GLfloat values[4];
   GLuint idx;
   values[0] = s0;
   values[1] = s1;
   values[2] = s2;
   values[3] = s3;
   idx = _mesa_add_unnamed_constant( p->program->Parameters, values );
   return make_ureg(PROGRAM_STATE_VAR, idx);
}

#define register_scalar_const(p, s0)    register_const4f(p, s0, s0, s0, s0)
#define register_const1f(p, s0)         register_const4f(p, s0, 0, 0, 1)
#define register_const2f(p, s0, s1)     register_const4f(p, s0, s1, 0, 1)
#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)




static struct ureg get_one( struct texenv_fragment_program *p )
{
   if (is_undef(p->one)) 
      p->one = register_scalar_const(p, 1.0);
   return p->one;
}

static struct ureg get_half( struct texenv_fragment_program *p )
{
   if (is_undef(p->half)) 
      p->one = register_scalar_const(p, 0.5);
   return p->half;
}

static struct ureg get_zero( struct texenv_fragment_program *p )
{
   if (is_undef(p->zero)) 
      p->one = register_scalar_const(p, 0.0);
   return p->zero;
}





static void program_error( struct texenv_fragment_program *p, const char *msg )
{
   _mesa_problem(NULL, msg);
   p->error = 1;
}

static struct ureg get_source( struct texenv_fragment_program *p, 
			       GLuint src, GLuint unit )
{
   switch (src) {
   case SRC_TEXTURE: 
      assert(!is_undef(p->src_texture[unit]));
      return p->src_texture[unit];

   case SRC_TEXTURE0:
   case SRC_TEXTURE1:
   case SRC_TEXTURE2:
   case SRC_TEXTURE3:
   case SRC_TEXTURE4:
   case SRC_TEXTURE5:
   case SRC_TEXTURE6:
   case SRC_TEXTURE7: 
      assert(!is_undef(p->src_texture[src - SRC_TEXTURE0]));
      return p->src_texture[src - SRC_TEXTURE0];

   case SRC_CONSTANT:
      return register_param2(p, STATE_TEXENV_COLOR, unit);

   case SRC_PRIMARY_COLOR:
      return register_input(p, FRAG_ATTRIB_COL0);

   case SRC_PREVIOUS:
   default:
      if (is_undef(p->src_previous))
	 return register_input(p, FRAG_ATTRIB_COL0);
      else
	 return p->src_previous;
   }
}

static struct ureg emit_combine_source( struct texenv_fragment_program *p, 
					GLuint mask,
					GLuint unit,
					GLuint source, 
					GLuint operand )
{
   struct ureg arg, src, one;

   src = get_source(p, source, unit);

   switch (operand) {
   case OPR_ONE_MINUS_SRC_COLOR: 
      /* Get unused tmp,
       * Emit tmp = 1.0 - arg.xyzw
       */
      arg = get_temp( p );
      one = get_one( p );
      return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0, one, src, undef);

   case OPR_SRC_ALPHA: 
      if (mask == WRITEMASK_W)
	 return src;
      else
	 return swizzle1( src, W );
   case OPR_ONE_MINUS_SRC_ALPHA: 
      /* Get unused tmp,
       * Emit tmp = 1.0 - arg.wwww
       */
      arg = get_temp(p);
      one = get_one(p);
      return emit_arith(p, FP_OPCODE_SUB, arg, mask, 0,
			one, swizzle1(src, W), undef);
   case OPR_ZERO:
      return get_zero(p);
   case OPR_ONE:
      return get_one(p);
   case OPR_SRC_COLOR: 
   default:
      return src;
   }
}

static GLboolean args_match( struct state_key *key, GLuint unit )
{
   int i, nr = key->unit[unit].NumArgsRGB;

   for (i = 0 ; i < nr ; i++) {
      if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 
	 return GL_FALSE;

      switch(key->unit[unit].OptA[i].Operand) {
      case OPR_SRC_ALPHA: 
	 switch(key->unit[unit].OptRGB[i].Operand) {
	 case OPR_SRC_COLOR: 
	 case OPR_SRC_ALPHA: 
	    break;
	 default:
	    return GL_FALSE;
	 }
	 break;
      case OPR_ONE_MINUS_SRC_ALPHA: 
	 switch(key->unit[unit].OptRGB[i].Operand) {
	 case OPR_ONE_MINUS_SRC_COLOR: 
	 case OPR_ONE_MINUS_SRC_ALPHA: 
	    break;
	 default:
	    return GL_FALSE;
	 }
	 break;
      default: 
	 return GL_FALSE;	/* impossible */
      }
   }

   return GL_TRUE;
}

static struct ureg emit_combine( struct texenv_fragment_program *p,
				 struct ureg dest,
				 GLuint mask,
				 GLuint saturate,
				 GLuint unit,
				 GLuint nr,
				 GLuint mode,
				 struct mode_opt *opt)
{
   struct ureg src[3];
   struct ureg tmp, half;
   int i;

   for (i = 0; i < nr; i++)
      src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand );

   switch (mode) {
   case MODE_REPLACE: 
      if (mask == WRITEMASK_XYZW && !saturate)
	 return src[0];
      else
	 return emit_arith( p, FP_OPCODE_MOV, dest, mask, saturate, src[0], undef, undef );
   case MODE_MODULATE: 
      return emit_arith( p, FP_OPCODE_MUL, dest, mask, saturate,
			 src[0], src[1], undef );
   case MODE_ADD: 
      return emit_arith( p, FP_OPCODE_ADD, dest, mask, saturate, 
			 src[0], src[1], undef );
   case MODE_ADD_SIGNED:
      /* tmp = arg0 + arg1
       * result = tmp - .5
       */
      half = get_half(p);
      emit_arith( p, FP_OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef );
      emit_arith( p, FP_OPCODE_SUB, dest, mask, saturate, tmp, half, undef );
      return dest;
   case MODE_INTERPOLATE: 
      /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered:
       */
      return emit_arith( p, FP_OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] );

   case MODE_SUBTRACT: 
      return emit_arith( p, FP_OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef );

   case MODE_DOT3_RGBA:
   case MODE_DOT3_RGBA_EXT: 
   case MODE_DOT3_RGB_EXT:
   case MODE_DOT3_RGB: {
      struct ureg tmp0 = get_temp( p );
      struct ureg tmp1 = get_temp( p );
      struct ureg neg1 = register_scalar_const(p, -1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -