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

📄 s_fragprog_to_c.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
	 need_result = GL_TRUE;

   if (is_swizzled(arg))
      need_tex = GL_TRUE;

   if (!need_tex && !need_result) {
      do_tex_simple( p, inst, fn, texunit, arg );
      return;
   }

   emit(p, "   {\n");
   emit(p, "       float texcoord[4];\n");
   emit(p, "       float result[4];\n");

   for (i = 0; i < 4; i++) {
      emit(p, "      texcoord[%d] = ", i);
      print_arg( p, deref(arg, i) );
      emit(p, ";\n");
   }

   emit(p, "       %s( ctx, texcoord, %d, result);\n", fn, texunit );

   for (i = 0; i < 4; i++) {
      if (inst->DstReg.WriteMask[i]) {
	 emit(p, "      ");
	 print_dest(p, inst, i);
	 emit(p, " = result[%d];\n", i);
      }
   }

   emit(p, "   }\n");
}


static void saturate( struct fragment_program *p,
		      const struct fp_instruction *inst,
		      GLuint i )
{
   emit(p, "   ");
   print_dest(p, inst, i);
   emit(p, " = SATURATE( ");
   print_dest(p, inst, i);
   emit(p, ");\n");
}
		     
static void assign_single( GLuint i,
			   struct fragment_program *p,
			   const struct fp_instruction *inst,
			   const char *fmt,
			   ... )
{
   va_list ap;
   va_start( ap, fmt );  

   if (inst->DstReg.WriteMask[i]) {
      emit(p, "   ");
      print_dest(p, inst, i);
      emit(p, " = ");
      print_expression( p, i, fmt, ap);
      if (inst->Saturate)
	 saturate(p, inst, i);
   }

   va_end( ap );
}

static void assign4( struct fragment_program *p,
		     const struct fp_instruction *inst,
		     const char *fmt,
		     ... )
{
   GLuint i;
   va_list ap;
   va_start( ap, fmt );  

   for (i = 0; i < 4; i++)
      if (inst->DstReg.WriteMask[i]) {
	 emit(p, "   ");
	 print_dest(p, inst, i);
	 emit(p, " = ");
	 print_expression( p, i, fmt, ap);
	 if (inst->Saturate)
	    saturate(p, inst, i);
      }

   va_end( ap );
}

static void assign4_replicate( struct fragment_program *p,
			       const struct fp_instruction *inst,
			       const char *fmt,
			       ... )
{
   GLuint i, first = 0;
   GLboolean ok = 0;
   va_list ap;

   for (i = 0; i < 4; i++)
      if (inst->DstReg.WriteMask[i]) {
	 ok = 1;
	 first = i;
	 break;
      }

   if (!ok) return;

   va_start( ap, fmt );  

   emit(p, "   ");

   print_dest(p, inst, first);
   emit(p, " = ");
   print_expression( p, 0, fmt, ap);
   if (inst->Saturate)
      saturate(p, inst, first);
   va_end( ap );

   for (i = first+1; i < 4; i++)
      if (inst->DstReg.WriteMask[i]) {
	 emit(p, "   ");
	 print_dest(p, inst, i);
	 emit(p, " = ");
	 print_dest(p, inst, first);
	 emit(p, ";\n");
      }
}
	 



static GLuint nr_args( GLuint opcode )
{
   switch (opcode) {
   case FP_OPCODE_ABS: return 1;
   case FP_OPCODE_ADD: return 2;
   case FP_OPCODE_CMP: return 3;
   case FP_OPCODE_COS: return 1;
   case FP_OPCODE_DP3: return 2;
   case FP_OPCODE_DP4: return 2;
   case FP_OPCODE_DPH: return 2;
   case FP_OPCODE_DST: return 2;
   case FP_OPCODE_EX2: return 1;
   case FP_OPCODE_FLR: return 1;
   case FP_OPCODE_FRC: return 1;
   case FP_OPCODE_KIL: return 1;
   case FP_OPCODE_LG2: return 1;
   case FP_OPCODE_LIT: return 1;
   case FP_OPCODE_LRP: return 3;
   case FP_OPCODE_MAD: return 3;
   case FP_OPCODE_MAX: return 2;
   case FP_OPCODE_MIN: return 2;
   case FP_OPCODE_MOV: return 1;
   case FP_OPCODE_MUL: return 2;
   case FP_OPCODE_POW: return 2;
   case FP_OPCODE_RCP: return 1;
   case FP_OPCODE_RSQ: return 1;
   case FP_OPCODE_SCS: return 1;
   case FP_OPCODE_SGE: return 2;
   case FP_OPCODE_SIN: return 1;
   case FP_OPCODE_SLT: return 2;
   case FP_OPCODE_SUB: return 2;
   case FP_OPCODE_SWZ: return 1;
   case FP_OPCODE_TEX: return 1;
   case FP_OPCODE_TXB: return 1;
   case FP_OPCODE_TXP: return 1;
   case FP_OPCODE_XPD: return 2;
   default: return 0;
   }
}



static void translate_program( struct fragment_program *p )
{
   const struct fp_instruction *inst = p->Instructions;

   for (; inst->Opcode != FP_OPCODE_END; inst++) {

      GLuint src[3], i;
      GLuint nr = nr_args( inst->Opcode );
      
      for (i = 0; i < nr; i++) 
	 src[i] = src_vector( &inst->SrcReg[i] );

      /* Print the original program instruction string */
      if (p->Base.String)
      {
         const char *s = (const char *) p->Base.String + inst->StringPos;
         emit(p, "   /* ");
         while (*s != ';') {
            emit_char(p, *s);
            s++;
         }
         emit(p, "; */\n");
      }

      switch (inst->Opcode) {
      case FP_OPCODE_ABS: 
	 assign4(p, inst, "fabsf(%s)", src[0]);
	 break;

      case FP_OPCODE_ADD: 
	 assign4(p, inst, "%s + %s", src[0], src[1]);
	 break;

      case FP_OPCODE_CMP: 
	 assign4(p, inst, "%s < 0.0F ? %s : %s", src[0], src[1], src[2]);
	 break;

      case FP_OPCODE_COS:
	 assign4_replicate(p, inst, "COS(%s)", src[0]);
	 break;

      case FP_OPCODE_DP3: 
	 assign4_replicate(p, inst, 
			   "%s*%s + %s*%s + %s*%s", 
			   deref(src[0],_X),
			   deref(src[1],_X),
			   deref(src[0],_Y),
			   deref(src[1],_Y),
			   deref(src[0],_Z),
			   deref(src[1],_Z));
	 break;

      case FP_OPCODE_DP4: 
	 assign4_replicate(p, inst, 
			   "%s*%s + %s*%s + %s*%s + %s*%s", 
			   deref(src[0],_X),
			   deref(src[1],_X),
			   deref(src[0],_Y),
			   deref(src[1],_Y),
			   deref(src[0],_Z),
			   deref(src[1],_Z));
	 break;

      case FP_OPCODE_DPH:  
	 assign4_replicate(p, inst, 
			   "%s*%s + %s*%s + %s*%s + %s", 
			   deref(src[0],_X),
			   deref(src[1],_X),
			   deref(src[0],_Y),
			   deref(src[1],_Y),
			   deref(src[1],_Z));
	 break;

      case FP_OPCODE_DST: 
	 /* result[0] = 1    * 1;
	  * result[1] = a[1] * b[1];
	  * result[2] = a[2] * 1;
	  * result[3] = 1    * b[3];
	  */
	 assign_single(0, p, inst, "1.0");

	 assign_single(1, p, inst, "%s * %s", 
		       deref(src[0], _Y), deref(src[1], _Y));

	 assign_single(2, p, inst, "%s", deref(src[0], _Z));
	 assign_single(3, p, inst, "%s", deref(src[1], _W));
	 break;

      case FP_OPCODE_EX2: 
	 assign4_replicate(p, inst, "powf(2.0, %s)", src[0]);
	 break;

      case FP_OPCODE_FLR: 
	 assign4_replicate(p, inst, "floorf(%s)", src[0]);
	 break;

      case FP_OPCODE_FRC: 
	 assign4_replicate(p, inst, "%s - floorf(%s)", src[0], src[0]);
	 break;

      case FP_OPCODE_KIL:
	 do_tex_kill(p, inst, src[0]);
	 break;

      case FP_OPCODE_LG2: 
	 assign4_replicate(p, inst, "LOG2(%s)", src[0]);
	 break;

      case FP_OPCODE_LIT: 
	 assign_single(0, p, inst, "1.0");
	 assign_single(1, p, inst, "MIN2(%s, 0)", deref(src[0], _X));
	 assign_single(2, p, inst, "(%s > 0.0) ? expf(%s * MIN2(%s, 0)) : 0.0",
		       deref(src[0], _X),
		       deref(src[0], _Z),
		       deref(src[0], _Y));
	 assign_single(3, p, inst, "1.0");
	 break;

      case FP_OPCODE_LRP: 
	 assign4(p, inst, 
		 "%s * %s + (1.0 - %s) * %s", 
		 src[0], src[1], src[0], src[2]);
	 break;

      case FP_OPCODE_MAD:
	 assign4(p, inst, "%s * %s + %s", src[0], src[1], src[2]);
	 break;

      case FP_OPCODE_MAX:
	 assign4(p, inst, "MAX2(%s, %s)", src[0], src[1]);
	 break;

      case FP_OPCODE_MIN: 
	 assign4(p, inst, "MIN2(%s, %s)", src[0], src[1]);
	 break;

      case FP_OPCODE_MOV: 
	 assign4(p, inst, "%s", src[0]);
	 break;

      case FP_OPCODE_MUL: 
	 assign4(p, inst, "%s * %s", src[0], src[1]);
	 break;

      case FP_OPCODE_POW: 
	 assign4_replicate(p, inst, "powf(%s, %s)", src[0], src[1]);
	 break;

      case FP_OPCODE_RCP: 
	 assign4_replicate(p, inst, "1.0/%s", src[0]);
	 break;

      case FP_OPCODE_RSQ: 
	 assign4_replicate(p, inst, "_mesa_inv_sqrtf(%s)", src[0]);
	 break;
	 
      case FP_OPCODE_SCS:
	 if (inst->DstReg.WriteMask[0]) {
	    assign_single(0, p, inst, "cosf(%s)", deref(src[0], _X));
	 }

	 if (inst->DstReg.WriteMask[1]) {
	    assign_single(1, p, inst, "sinf(%s)", deref(src[0], _X));
	 }
	 break;

      case FP_OPCODE_SGE: 
	 assign4(p, inst, "%s >= %s ? 1.0 : 0.0", src[0], src[1]);
	 break;

      case FP_OPCODE_SIN:
	 assign4_replicate(p, inst, "sinf(%s)", src[0]);
	 break;

      case FP_OPCODE_SLT: 
	 assign4(p, inst, "%s < %s ? 1.0 : 0.0", src[0], src[1]);
	 break;

      case FP_OPCODE_SUB: 
	 assign4(p, inst, "%s - %s", src[0], src[1]);
	 break;

      case FP_OPCODE_SWZ: 	/* same implementation as MOV: */
	 assign4(p, inst, "%s", src[0]);
	 break;

      case FP_OPCODE_TEX: 
	 do_tex(p, inst, "TEX", inst->TexSrcUnit, src[0]);
	 break;

      case FP_OPCODE_TXB:
	 do_tex(p, inst, "TXB", inst->TexSrcUnit, src[0]);
	 break;

      case FP_OPCODE_TXP:
	 do_tex(p, inst, "TXP", inst->TexSrcUnit, src[0]);
	 break;

      case FP_OPCODE_XPD:
	 /* Cross product:
	  *      result.x = src[0].y * src[1].z - src[0].z * src[1].y;
	  *      result.y = src[0].z * src[1].x - src[0].x * src[1].z;
	  *      result.z = src[0].x * src[1].y - src[0].y * src[1].x;
	  *      result.w = undef;
	  */
	 assign4(p, inst, 
		 "%s * %s - %s * %s",
		 swizzle(src[0], _Y, _Z, _X, _ONE),
		 swizzle(src[1], _Z, _X, _Y, _ONE),
		 swizzle(src[0], _Z, _X, _Y, _ONE),
		 swizzle(src[1], _Y, _Z, _X, _ONE));
	 break;

      default:
	 emit(p, "BOGUS OPCODE\n");
	 return;
      }
   }
}





void _swrast_translate_program( GLcontext *ctx )
{
   struct fragment_program *p = ctx->FragmentProgram._Current;

   if (p) {
      p->c_strlen = 0;

      print_header( p );
      translate_program( p );
      print_footer( p );
   }
}

#endif /*USE_TCC*/

⌨️ 快捷键说明

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