Пример #1
0
bool TGlslOutputTraverser::traverseDeclaration(bool preVisit, TIntermDeclaration* decl, TIntermTraverser* it) {
	TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it);
	GlslFunction *current = goit->current;
	std::stringstream& out = current->getActiveOutput();
	EGlslSymbolType symbol_type = translateType(decl->getTypePointer());
	TType& type = *decl->getTypePointer();
	
	
	bool emit_osx10_6_arrays = goit->m_EmitSnowLeopardCompatibleArrayInitializers
		&& decl->containsArrayInitialization();
	
	if (emit_osx10_6_arrays) {
		assert(decl->isSingleInitialization() && "Emission of multiple in-line array declarations isn't supported when running in OS X 10.6 compatible mode.");
		
		current->indent(out);
		out << "#if defined(OSX_SNOW_LEOPARD)" << std::endl;
		current->increaseDepth();
		
		TQualifier q = type.getQualifier();
		if (q == EvqConst)
			q = EvqTemporary;
		
		current->beginStatement();
		if (q != EvqTemporary && q != EvqGlobal)
			out << type.getQualifierString() << " ";
		
		TIntermBinary* assign = decl->getDeclaration()->getAsBinaryNode();
		TIntermSymbol* sym = assign->getLeft()->getAsSymbolNode();
		TIntermSequence& init = assign->getRight()->getAsAggregate()->getSequence();
		
		writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined);
		out << "[" << type.getArraySize() << "] " << sym->getSymbol();
		current->endStatement();
		
		unsigned n_vals = init.size();
		for (unsigned i = 0; i != n_vals; ++i) {
			current->beginStatement();
			sym->traverse(goit);
			out << "[" << i << "]" << " = ";
			init[i]->traverse(goit);
			current->endStatement();
		}
		
		current->decreaseDepth();
		current->indent(out);
		out << "#else" << std::endl;
		current->increaseDepth();
	}
	
	current->beginStatement();
	
	if (type.getQualifier() != EvqTemporary && type.getQualifier() != EvqGlobal)
		out << type.getQualifierString() << " ";
	
	if (type.getBasicType() == EbtStruct)
		out << type.getTypeName();
	else
		writeType(out, symbol_type, NULL, goit->m_UsePrecision ? decl->getPrecision() : EbpUndefined);
	
	if (type.isArray())
		out << "[" << type.getArraySize() << "]";
	
	out << " ";
	
	decl->getDeclaration()->traverse(goit);
	
	current->endStatement();
	
	if (emit_osx10_6_arrays) {
		current->decreaseDepth();
		current->indent(out);
		out << "#endif" << std::endl;
	}
	
	return false;
}
Пример #2
0
bool TGlslOutputTraverser::traverseBinary( bool preVisit, TIntermBinary *node, TIntermTraverser *it )
{
   TString op = "??";
   TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it);
   GlslFunction *current = goit->current;
   std::stringstream& out = current->getActiveOutput();
   bool infix = true;
   bool assign = false;
   bool needsParens = true;

   switch (node->getOp())
   {
   case EOpAssign:                   op = "=";   infix = true; needsParens = false; break;
   case EOpAddAssign:                op = "+=";  infix = true; needsParens = false; break;
   case EOpSubAssign:                op = "-=";  infix = true; needsParens = false; break;
   case EOpMulAssign:                op = "*=";  infix = true; needsParens = false; break;
   case EOpVectorTimesMatrixAssign:  op = "*=";  infix = true; needsParens = false; break;
   case EOpVectorTimesScalarAssign:  op = "*=";  infix = true; needsParens = false; break;
   case EOpMatrixTimesScalarAssign:  op = "*=";  infix = true; needsParens = false; break;
   case EOpMatrixTimesMatrixAssign:  op = "*=";  infix = true; needsParens = false; break;
   case EOpDivAssign:                op = "/=";  infix = true; needsParens = false; break;
   case EOpModAssign:                op = "%=";  infix = true; needsParens = false; break;
   case EOpAndAssign:                op = "&=";  infix = true; needsParens = false; break;
   case EOpInclusiveOrAssign:        op = "|=";  infix = true; needsParens = false; break;
   case EOpExclusiveOrAssign:        op = "^=";  infix = true; needsParens = false; break;
   case EOpLeftShiftAssign:          op = "<<="; infix = true; needsParens = false; break;
   case EOpRightShiftAssign:         op = "??="; infix = true; needsParens = false; break;

   case EOpIndexDirect:
      {
         TIntermTyped *left = node->getLeft();
         TIntermTyped *right = node->getRight();
         assert( left && right);

         current->beginStatement();

		 if (Check2DMatrixIndex (goit, out, left, right))
			 return false;

		 if (left->isMatrix() && !left->isArray())
		 {
			 if (right->getAsConstant())
			 {
				 current->addLibFunction (EOpMatrixIndex);
				 out << "xll_matrixindex (";
				 left->traverse(goit);
				 out << ", ";
				 right->traverse(goit);
				 out << ")";
				 return false;
			 }
			 else
			 {
				 current->addLibFunction (EOpTranspose);
				 current->addLibFunction (EOpMatrixIndex);
				 current->addLibFunction (EOpMatrixIndexDynamic);
				 out << "xll_matrixindexdynamic (";
				 left->traverse(goit);
				 out << ", ";
				 right->traverse(goit);
				 out << ")";
				 return false;
			 }
		 }

         left->traverse(goit);

         // Special code for handling a vector component select (this improves readability)
         if (left->isVector() && !left->isArray() && right->getAsConstant())
         {
            char swiz[] = "xyzw";
            goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
            goit->generatingCode = false;
            right->traverse(goit);
            assert( goit->indexList.size() == 1);
            assert( goit->indexList[0] < 4);
            out << "." << swiz[goit->indexList[0]];
            goit->indexList.clear();
            goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
            goit->generatingCode = true;
         }
         else
         {
            out << "[";
            right->traverse(goit);
            out << "]";
         }
         return false;
      }
   case EOpIndexIndirect:
      {
      TIntermTyped *left = node->getLeft();
      TIntermTyped *right = node->getRight();
      current->beginStatement();

	  if (Check2DMatrixIndex (goit, out, left, right))
		  return false;

	  if (left && right && left->isMatrix() && !left->isArray())
	  {
		  if (right->getAsConstant())
		  {
			  current->addLibFunction (EOpMatrixIndex);
			  out << "xll_matrixindex (";
			  left->traverse(goit);
			  out << ", ";
			  right->traverse(goit);
			  out << ")";
			  return false;
		  }
		  else
		  {
			  current->addLibFunction (EOpTranspose);
			  current->addLibFunction (EOpMatrixIndex);
			  current->addLibFunction (EOpMatrixIndexDynamic);
			  out << "xll_matrixindexdynamic (";
			  left->traverse(goit);
			  out << ", ";
			  right->traverse(goit);
			  out << ")";
			  return false;
		  }
	  }

      if (left)
         left->traverse(goit);
      out << "[";
      if (right)
         right->traverse(goit);
      out << "]";
      return false;
	  }

   case EOpIndexDirectStruct:
      {
         current->beginStatement();
         GlslStruct *s = goit->createStructFromType(node->getLeft()->getTypePointer());
         if (node->getLeft())
            node->getLeft()->traverse(goit);

         // The right child is always an offset into the struct, switch to get an
         // immediate constant, and put it back afterwords
         goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
         goit->generatingCode = false;

         if (node->getRight())
         {
            node->getRight()->traverse(goit);
            assert( goit->indexList.size() == 1);
            assert( goit->indexList[0] < s->memberCount());
            out << "." << s->getMember(goit->indexList[0]).name;

         }

         goit->indexList.clear();
         goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
         goit->generatingCode = true;
      }
      return false;

   case EOpVectorSwizzle:
      current->beginStatement();
      if (node->getLeft())
         node->getLeft()->traverse(goit);
      goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
      goit->generatingCode = false;
      if (node->getRight())
      {
         node->getRight()->traverse(goit);
         assert( goit->indexList.size() <= 4);
         out << '.';
         const char fields[] = "xyzw";
         for (int ii = 0; ii < (int)goit->indexList.size(); ii++)
         {
            int val = goit->indexList[ii];
            assert( val >= 0);
            assert( val < 4);
            out << fields[val];
         }
      }
      goit->indexList.clear();
      goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
      goit->generatingCode = true;
      return false;

	case EOpMatrixSwizzle:		   
		// This presently only works for swizzles as rhs operators
		if (node->getRight())
		{
			goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
			goit->generatingCode = false;

			node->getRight()->traverse(goit);

			goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
			goit->generatingCode = true;

			std::vector<int> elements = goit->indexList;
			goit->indexList.clear();
			
			if (elements.size() > 4 || elements.size() < 1) {
				goit->infoSink.info << "Matrix swizzle operations can must contain at least 1 and at most 4 element selectors.";
				return true;
			}

			unsigned column[4] = {0}, row[4] = {0};
			for (unsigned i = 0; i != elements.size(); ++i)
			{
				unsigned val = elements[i];
				column[i] = val % 4;
				row[i] = val / 4;
			}

			bool sameColumn = true;
			for (unsigned i = 1; i != elements.size(); ++i)
				sameColumn &= column[i] == column[i-1];

			static const char* fields = "xyzw";
			
			if (sameColumn)
			{				
				//select column, then swizzle row
				if (node->getLeft())
					node->getLeft()->traverse(goit);
				out << "[" << column[0] << "].";
				
				for (unsigned i = 0; i < elements.size(); ++i)
					out << fields[row[i]];
			}
			else
			{
				// Insert constructor, and dereference individually

				// Might need to account for different types here 
				assert( elements.size() != 1); //should have hit same collumn case
				out << "vec" << elements.size() << "(";
				if (node->getLeft())
					node->getLeft()->traverse(goit);
				out << "[" << column[0] << "].";
				out << fields[row[0]];
				
				for (unsigned i = 1; i < elements.size(); ++i)
				{
					out << ", ";
					if (node->getLeft())
						node->getLeft()->traverse(goit);
					out << "[" << column[i] << "].";
					out << fields[row[i]];
				}
				out << ")";
			}
		}
		return false;

   case EOpAdd:    op = "+"; infix = true; break;
   case EOpSub:    op = "-"; infix = true; break;
   case EOpMul:    op = "*"; infix = true; break;
   case EOpDiv:    op = "/"; infix = true; break;
   case EOpMod:    op = "mod"; infix = false; break;
   case EOpRightShift:  op = "<<"; infix = true;
		   break;
   case EOpLeftShift:   op = ">>"; infix = true; break;
   case EOpAnd:         op = "&"; infix = true; break;
   case EOpInclusiveOr: op = "|"; infix = true; break;
   case EOpExclusiveOr: op = "^"; infix = true; break;
   case EOpEqual:       
      writeComparison ( "==", "equal", node, goit );
      return false;        

   case EOpNotEqual:        
      writeComparison ( "!=", "notEqual", node, goit );
      return false;               

   case EOpLessThan: 
      writeComparison ( "<", "lessThan", node, goit );
      return false;               

   case EOpGreaterThan:
      writeComparison ( ">", "greaterThan", node, goit );
      return false;               

   case EOpLessThanEqual:    
      writeComparison ( "<=", "lessThanEqual", node, goit );
      return false;               


   case EOpGreaterThanEqual: 
      writeComparison ( ">=", "greaterThanEqual", node, goit );
      return false;               


   case EOpVectorTimesScalar: op = "*"; infix = true; break;
   case EOpVectorTimesMatrix: op = "*"; infix = true; break;
   case EOpMatrixTimesVector: op = "*"; infix = true; break;
   case EOpMatrixTimesScalar: op = "*"; infix = true; break;
   case EOpMatrixTimesMatrix: op = "*"; infix = true; break;

   case EOpLogicalOr:  op = "||"; infix = true; break;
   case EOpLogicalXor: op = "^^"; infix = true; break;
   case EOpLogicalAnd: op = "&&"; infix = true; break;
   default: assert(0);
   }

   current->beginStatement();

   if (infix)
   {
	   // special case for swizzled matrix assignment
	   if (node->getOp() == EOpAssign && node->getLeft() && node->getRight()) {
		   TIntermBinary* lval = node->getLeft()->getAsBinaryNode();
		   
		   if (lval && lval->getOp() == EOpMatrixSwizzle) {
			   static const char* vec_swizzles = "xyzw";
			   TIntermTyped* rval = node->getRight();
			   TIntermTyped* lexp = lval->getLeft();
			   
			   goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
			   goit->generatingCode = false;
			   
			   lval->getRight()->traverse(goit);
			   
			   goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
			   goit->generatingCode = true;
			   
			   std::vector<int> swizzles = goit->indexList;
			   goit->indexList.clear();
			   
			   char temp_rval[128];
			   unsigned n_swizzles = swizzles.size();
			   
			   if (n_swizzles > 1) {
				   snprintf(temp_rval, 128, "xlat_swiztemp%d", goit->swizzleAssignTempCounter++);
				   
				   current->beginStatement();
				   out << "vec" << n_swizzles << " " << temp_rval << " = ";
				   rval->traverse(goit);			   
				   current->endStatement();
			   }
			   
			   for (unsigned i = 0; i != n_swizzles; ++i) {
				   unsigned col = swizzles[i] / 4;
				   unsigned row = swizzles[i] % 4;
				   
				   current->beginStatement();
				   lexp->traverse(goit);
				   out << "[" << row << "][" << col << "] = ";
				   if (n_swizzles > 1)
					   out << temp_rval << "." << vec_swizzles[i];
				   else
					   rval->traverse(goit);
				   
				   current->endStatement();
			   }

			   return false;
		   }
	   }

      if (needsParens)
         out << '(';

      if (node->getLeft())
         node->getLeft()->traverse(goit);
      out << ' ' << op << ' ';
      if (node->getRight())
         node->getRight()->traverse(goit);

      if (needsParens)
         out << ')';
   }
   else
   {
      if (assign)
      {		  
         // Need to traverse the left child twice to allow for the assign and the op
         // This is OK, because we know it is an lvalue
         if (node->getLeft())
            node->getLeft()->traverse(goit);

         out << " = " << op << '(';

         if (node->getLeft())
            node->getLeft()->traverse(goit);
         out << ", ";
         if (node->getRight())
            node->getRight()->traverse(goit);

         out << ')';
      }
      else
      {
         out << op << '(';

         if (node->getLeft())
            node->getLeft()->traverse(goit);
         out << ", ";
         if (node->getRight())
            node->getRight()->traverse(goit);

         out << ')';
      }
   }

   return false;
}
Пример #3
0
bool TGlslOutputTraverser::traverseAggregate( bool preVisit, TIntermAggregate *node, TIntermTraverser *it )
{
   TGlslOutputTraverser* goit = static_cast<TGlslOutputTraverser*>(it);
   GlslFunction *current = goit->current;
   std::stringstream& out = current->getActiveOutput();
   int argCount = (int) node->getSequence().size();

   if (node->getOp() == EOpNull)
   {
      goit->infoSink.info << "node is still EOpNull!\n";
      return true;
   }


   switch (node->getOp())
   {
   case EOpSequence:
      if (goit->generatingCode)
      {
		  goit->outputLineDirective (node->getLine());
         TIntermSequence::iterator sit;
         TIntermSequence &sequence = node->getSequence(); 
		 for (sit = sequence.begin(); sit != sequence.end(); ++sit)
		 {
		   goit->outputLineDirective((*sit)->getLine());
		   (*sit)->traverse(it);
		   //out << ";\n";
		   current->endStatement();
		 }
      }
      else
      {
         TIntermSequence::iterator sit;
         TIntermSequence &sequence = node->getSequence(); 
		  for (sit = sequence.begin(); sit != sequence.end(); ++sit)
		  {
		    (*sit)->traverse(it);
		  }
      }

      return false;

   case EOpFunction:
      {
         GlslFunction *func = new GlslFunction( node->getPlainName().c_str(), node->getName().c_str(),
                                                translateType(node->getTypePointer()), goit->m_UsePrecision?node->getPrecision():EbpUndefined,
											   node->getSemantic().c_str(), node->getLine()); 
         if (func->getReturnType() == EgstStruct)
         {
            GlslStruct *s = goit->createStructFromType( node->getTypePointer());
            func->setStruct(s);
         }
         goit->functionList.push_back( func);
         goit->current = func;
         goit->current->beginBlock( false);
         TIntermSequence::iterator sit;
         TIntermSequence &sequence = node->getSequence(); 
		 for (sit = sequence.begin(); sit != sequence.end(); ++sit)
		 {
			 (*sit)->traverse(it);
		 }
         goit->current->endBlock();
         goit->current = goit->global;
         return false;
      }

   case EOpParameters:
      it->visitSymbol = traverseParameterSymbol;
      {
         TIntermSequence::iterator sit;
         TIntermSequence &sequence = node->getSequence(); 
		 for (sit = sequence.begin(); sit != sequence.end(); ++sit)
           (*sit)->traverse(it);
      }
      it->visitSymbol = traverseSymbol;
      return false;

   case EOpConstructFloat: writeFuncCall( "float", node, goit); return false;
   case EOpConstructVec2:  writeFuncCall( "vec2", node, goit); return false;
   case EOpConstructVec3:  writeFuncCall( "vec3", node, goit); return false;
   case EOpConstructVec4:  writeFuncCall( "vec4", node, goit); return false;
   case EOpConstructBool:  writeFuncCall( "bool", node, goit); return false;
   case EOpConstructBVec2: writeFuncCall( "bvec2", node, goit); return false;
   case EOpConstructBVec3: writeFuncCall( "bvec3", node, goit); return false;
   case EOpConstructBVec4: writeFuncCall( "bvec4", node, goit); return false;
   case EOpConstructInt:   writeFuncCall( "int", node, goit); return false;
   case EOpConstructIVec2: writeFuncCall( "ivec2", node, goit); return false;
   case EOpConstructIVec3: writeFuncCall( "ivec3", node, goit); return false;
   case EOpConstructIVec4: writeFuncCall( "ivec4", node, goit); return false;
		   
   case EOpConstructMat2FromMat:
   case EOpConstructMat2:  writeFuncCall( "mat2", node, goit); return false;
		   
   case EOpConstructMat3FromMat:
   case EOpConstructMat3:  writeFuncCall( "mat3", node, goit); return false;
		   
   case EOpConstructMat4:  writeFuncCall( "mat4", node, goit); return false;
   case EOpConstructStruct:  writeFuncCall( node->getTypePointer()->getTypeName(), node, goit); return false;
   case EOpConstructArray:  writeFuncCall( buildArrayConstructorString(*node->getTypePointer()), node, goit); return false;

   case EOpComma:
      {
         TIntermSequence::iterator sit;
         TIntermSequence &sequence = node->getSequence(); 
         for (sit = sequence.begin(); sit != sequence.end(); ++sit)
         {
            (*sit)->traverse(it);
            if ( sit+1 != sequence.end())
               out << ", ";
         }
      }
      return false;

   case EOpFunctionCall:
      current->addCalledFunction(node->getName().c_str());
      writeFuncCall( node->getPlainName(), node, goit);
      return false; 

   case EOpLessThan:         writeFuncCall( "lessThan", node, goit); return false;
   case EOpGreaterThan:      writeFuncCall( "greaterThan", node, goit); return false;
   case EOpLessThanEqual:    writeFuncCall( "lessThanEqual", node, goit); return false;
   case EOpGreaterThanEqual: writeFuncCall( "greaterThanEqual", node, goit); return false;
   case EOpVectorEqual:      writeFuncCall( "equal", node, goit); return false;
   case EOpVectorNotEqual:   writeFuncCall( "notEqual", node, goit); return false;

   case EOpMod:			  writeFuncCall( "mod", node, goit, true); return false;

   case EOpPow:           writeFuncCall( "pow", node, goit, true); return false;

   case EOpAtan2:         writeFuncCall( "atan", node, goit, true); return false;

   case EOpMin:           writeFuncCall( "min", node, goit, true); return false;
   case EOpMax:           writeFuncCall( "max", node, goit, true); return false;
   case EOpClamp:         writeFuncCall( "clamp", node, goit, true); return false;
   case EOpMix:           writeFuncCall( "mix", node, goit, true); return false;
   case EOpStep:          writeFuncCall( "step", node, goit, true); return false;
   case EOpSmoothStep:    writeFuncCall( "smoothstep", node, goit, true); return false;

   case EOpDistance:      writeFuncCall( "distance", node, goit); return false;
   case EOpDot:           writeFuncCall( "dot", node, goit); return false;
   case EOpCross:         writeFuncCall( "cross", node, goit); return false;
   case EOpFaceForward:   writeFuncCall( "faceforward", node, goit); return false;
   case EOpReflect:       writeFuncCall( "reflect", node, goit); return false;
   case EOpRefract:       writeFuncCall( "refract", node, goit); return false;
   case EOpMul:
      {
         //This should always have two arguments
         assert(node->getSequence().size() == 2);
         current->beginStatement();                     

         out << '(';
         node->getSequence()[0]->traverse(goit);
         out << " * ";
         node->getSequence()[1]->traverse(goit);
         out << ')';

         return false;
      }

      //HLSL texture functions
   case EOpTex1D:
      if (argCount == 2)
         writeTex( "texture1D", node, goit);
      else
      {
         current->addLibFunction(EOpTex1DGrad);
         writeTex( "xll_tex1Dgrad", node, goit);
      }
      return false;

   case EOpTex1DProj:     
      writeTex( "texture1DProj", node, goit); 
      return false;

   case EOpTex1DLod:
      current->addLibFunction(EOpTex1DLod);
      writeTex( "xll_tex1Dlod", node, goit); 
      return false;

   case EOpTex1DBias:
      current->addLibFunction(EOpTex1DBias);
      writeTex( "xll_tex1Dbias", node, goit); 
      return false;

   case EOpTex1DGrad:     
      current->addLibFunction(EOpTex1DGrad);
      writeTex( "xll_tex1Dgrad", node, goit); 
      return false;

   case EOpTex2D:
      if (argCount == 2)
         writeTex( "texture2D", node, goit);
      else
      {
         current->addLibFunction(EOpTex2DGrad);
         writeTex( "xll_tex2Dgrad", node, goit);
      }
      return false;

   case EOpTex2DProj:     
      writeTex( "texture2DProj", node, goit);
      return false;

   case EOpTex2DLod:      
      current->addLibFunction(EOpTex2DLod);
      writeTex( "xll_tex2Dlod", node, goit); 
      return false;

   case EOpTex2DBias:  
      current->addLibFunction(EOpTex2DBias);
      writeTex( "xll_tex2Dbias", node, goit); 
      return false;

   case EOpTex2DGrad:  
      current->addLibFunction(EOpTex2DGrad);
      writeTex( "xll_tex2Dgrad", node, goit); 
      return false;

   case EOpTex3D:
      if (argCount == 2)
         writeTex( "texture3D", node, goit);
      else
      {
         current->addLibFunction(EOpTex3DGrad);
         writeTex( "xll_tex3Dgrad", node, goit);            
      }
      return false;

   case EOpTex3DProj:    
      writeTex( "texture3DProj", node, goit); 
      return false;

   case EOpTex3DLod:     
      current->addLibFunction(EOpTex3DLod);
      writeTex( "xll_tex3Dlod", node, goit); 
      return false;

   case EOpTex3DBias:     
      current->addLibFunction(EOpTex3DBias);
      writeTex( "xll_tex3Dbias", node, goit); 
      return false;

   case EOpTex3DGrad:    
      current->addLibFunction(EOpTex3DGrad);
      writeTex( "xll_tex3Dgrad", node, goit); 
      return false;

   case EOpTexCube:
      if (argCount == 2)
         writeTex( "textureCube", node, goit);
      else
      {
         current->addLibFunction(EOpTexCubeGrad);
         writeTex( "xll_texCUBEgrad", node, goit);
      }
      return false;
   case EOpTexCubeProj:   
      writeTex( "textureCubeProj", node, goit); 
      return false;

   case EOpTexCubeLod:    
      current->addLibFunction(EOpTexCubeLod); 
      writeTex( "xll_texCUBElod", node, goit); 
      return false;

   case EOpTexCubeBias:   
      current->addLibFunction(EOpTexCubeBias); 
      writeTex( "xll_texCUBEbias", node, goit); 
      return false;

   case EOpTexCubeGrad:   
      current->addLibFunction(EOpTexCubeGrad);
      writeTex( "xll_texCUBEgrad", node, goit); 
      return false;

   case EOpTexRect:
	   writeTex( "texture2DRect", node, goit);
	   return false;
	   
   case EOpTexRectProj:
	   writeTex( "texture2DRectProj", node, goit);
	   return false;
		   
   case EOpModf:
      current->addLibFunction(EOpModf);
      writeFuncCall( "xll_modf", node, goit);
      break;

   case EOpLdexp:
      current->addLibFunction(EOpLdexp);
      writeFuncCall( "xll_ldexp", node, goit);
      break;

   case EOpSinCos:        
      current->addLibFunction(EOpSinCos);
      writeFuncCall ( "xll_sincos", node, goit);
      break;

   case EOpLit:
      current->addLibFunction(EOpLit);
      writeFuncCall( "xll_lit", node, goit);
      break;

   default: goit->infoSink.info << "Bad aggregation op\n";
   }


   return false;
}