1a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 2a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// Use of this source code is governed by a BSD-style license that can be 4a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// found in the LICENSE file. 5a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block// 6a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 7a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "compiler/OutputGLSL.h" 8a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block#include "compiler/debug.h" 9a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 10a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blocknamespace 11a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 12a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockTString getTypeName(const TType& type) 13a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 14a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase out; 15a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (type.isMatrix()) 16a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 17a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "mat"; 18a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getNominalSize(); 19a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 20a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (type.isVector()) 21a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 22a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (type.getBasicType()) 23a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 24a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtFloat: out << "vec"; break; 25a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtInt: out << "ivec"; break; 26a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtBool: out << "bvec"; break; 27a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 28a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 29a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getNominalSize(); 30a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 31a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 32a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 33a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (type.getBasicType() == EbtStruct) 34a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getTypeName(); 35a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 36a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getBasicString(); 37a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 38a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return TString(out.c_str()); 39a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 40a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 41a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockTString arrayBrackets(const TType& type) 42a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 43a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(type.isArray()); 44a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase out; 45a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "[" << type.getArraySize() << "]"; 46a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return TString(out.c_str()); 47a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 48a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 49a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool isSingleStatement(TIntermNode* node) { 50a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (const TIntermAggregate* aggregate = node->getAsAggregate()) 51a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 52a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return (aggregate->getOp() != EOpFunction) && 53a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block (aggregate->getOp() != EOpSequence); 54a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 55a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (const TIntermSelection* selection = node->getAsSelectionNode()) 56a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 57a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Ternary operators are usually part of an assignment operator. 58a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // This handles those rare cases in which they are all by themselves. 59a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return selection->usesTernaryOperator(); 60a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 61a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (node->getAsLoopNode()) 62a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 63a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 64a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 65a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 66a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 67a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} // namespace 68a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 69a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve BlockTOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink) 70a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block : TIntermTraverser(true, true, true), 71a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mObjSink(objSink), 72a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaringVariables(false) 73a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 74a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 75a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 76a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr) 77a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 78a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 79a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == PreVisit && preStr) 80a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 81a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << preStr; 82a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 83a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (visit == InVisit && inStr) 84a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 85a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << inStr; 86a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 87a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (visit == PostVisit && postStr) 88a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 89a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << postStr; 90a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 91a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 92a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 93a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::writeVariableType(const TType& type) 94a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 95a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 96a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TQualifier qualifier = type.getQualifier(); 97a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // TODO(alokp): Validate qualifier for variable declarations. 98a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) 99a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getQualifierString() << " "; 100a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 101a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Declare the struct if we have not done so already. 102a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if ((type.getBasicType() == EbtStruct) && 103a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end())) 104a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 105a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "struct " << type.getTypeName() << "{\n"; 106a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TTypeList* structure = type.getStruct(); 107a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(structure != NULL); 108a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (size_t i = 0; i < structure->size(); ++i) 109a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 110a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TType* fieldType = (*structure)[i].type; 111a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(fieldType != NULL); 112a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << getTypeName(*fieldType) << " " << fieldType->getFieldName(); 113a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (fieldType->isArray()) 114a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << arrayBrackets(*fieldType); 115a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ";\n"; 116a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 117a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "}"; 118a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaredStructs.insert(type.getTypeName()); 119a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 120a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 121a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 122a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << getTypeName(type); 123a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 124a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 125a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 126a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::writeFunctionParameters(const TIntermSequence& args) 127a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 128a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 129a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (TIntermSequence::const_iterator iter = args.begin(); 130a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block iter != args.end(); ++iter) 131a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 132a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TIntermSymbol* arg = (*iter)->getAsSymbolNode(); 133a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(arg != NULL); 134a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 135a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TType& type = arg->getType(); 136a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TQualifier qualifier = type.getQualifier(); 137a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // TODO(alokp): Validate qualifier for function arguments. 138a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) 139a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getQualifierString() << " "; 140a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 141a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << getTypeName(type); 142a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 143a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TString& name = arg->getSymbol(); 144a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (!name.empty()) 145a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << " " << name; 146a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (type.isArray()) 147a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << arrayBrackets(type); 148a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 149a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Put a comma if this is not the last argument. 1505abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (iter != args.end() - 1) 151a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ", "; 152a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 153a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 154a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 155a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockconst ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type, 156a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const ConstantUnion* pConstUnion) 157a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 158a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 159a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 160a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (type.getBasicType() == EbtStruct) 161a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 162a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getTypeName() << "("; 163a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TTypeList* structure = type.getStruct(); 164a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(structure != NULL); 165a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (size_t i = 0; i < structure->size(); ++i) 166a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 167a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TType* fieldType = (*structure)[i].type; 168a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(fieldType != NULL); 169a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block pConstUnion = writeConstantUnion(*fieldType, pConstUnion); 170a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (i != structure->size() - 1) out << ", "; 171a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 172a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")"; 173a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 174a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 175a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 176a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block int size = type.getObjectSize(); 177a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block bool writeType = size > 1; 178a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (writeType) out << getTypeName(type) << "("; 179a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (int i = 0; i < size; ++i, ++pConstUnion) 180a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 181a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (pConstUnion->getType()) 182a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 183a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtFloat: out << pConstUnion->getFConst(); break; 184a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtInt: out << pConstUnion->getIConst(); break; 185a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EbtBool: out << pConstUnion->getBConst(); break; 186a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 187a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 188a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (i != size - 1) out << ", "; 189a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 190a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (writeType) out << ")"; 191a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 192a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return pConstUnion; 193a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 194a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 195a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::visitSymbol(TIntermSymbol* node) 196a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 197a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 198a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << node->getSymbol(); 199a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 200a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (mDeclaringVariables && node->getType().isArray()) 201a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << arrayBrackets(node->getType()); 202a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 203a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 204a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::visitConstantUnion(TIntermConstantUnion* node) 205a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 206a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeConstantUnion(node->getType(), node->getUnionArrayPointer()); 207a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 208a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 209a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node) 210a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 211a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block bool visitChildren = true; 212a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 213a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOp()) 214a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 215a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpInitialize: 216a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == InVisit) 217a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 218a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << " = "; 219a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // RHS of initialize is not being declared. 220a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaringVariables = false; 221a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 222a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 223a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break; 224a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break; 225a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break; 226a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break; 227a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Notice the fall-through. 228a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMulAssign: 229a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorTimesMatrixAssign: 230a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorTimesScalarAssign: 231a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMatrixTimesScalarAssign: 232a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMatrixTimesMatrixAssign: 233a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeTriplet(visit, "(", " *= ", ")"); 234a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 235a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 236a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpIndexDirect: 237a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpIndexIndirect: 238a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeTriplet(visit, NULL, "[", "]"); 239a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 240a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpIndexDirectStruct: 241a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == InVisit) 242a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 243a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "."; 244a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // TODO(alokp): ASSERT 245a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << node->getType().getFieldName(); 246a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 247a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 248a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 249a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorSwizzle: 250a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == InVisit) 251a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 252a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "."; 253a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermAggregate* rightChild = node->getRight()->getAsAggregate(); 254a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermSequence& sequence = rightChild->getSequence(); 255a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit) 256a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 257a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermConstantUnion* element = (*sit)->getAsConstantUnion(); 258a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(element->getBasicType() == EbtInt); 259a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(element->getNominalSize() == 1); 260a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const ConstantUnion& data = element->getUnionArrayPointer()[0]; 261a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(data.getType() == EbtInt); 262a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (data.getIConst()) 263a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 264a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 0: out << "x"; break; 265a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 1: out << "y"; break; 266a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 2: out << "z"; break; 267a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 3: out << "w"; break; 268a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 269a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 270a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 271a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 272a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 273a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 274a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 275a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break; 276a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSub: writeTriplet(visit, "(", " - ", ")"); break; 277a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMul: writeTriplet(visit, "(", " * ", ")"); break; 278a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break; 279a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMod: UNIMPLEMENTED(); break; 280a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break; 281a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break; 282a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break; 283a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break; 284a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break; 285a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break; 286a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 287a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Notice the fall-through. 288a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorTimesScalar: 289a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorTimesMatrix: 290a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMatrixTimesVector: 291a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMatrixTimesScalar: 292a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMatrixTimesMatrix: 293a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeTriplet(visit, "(", " * ", ")"); 294a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 295a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 296a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break; 297a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break; 298a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break; 299a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 300a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 301a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 302a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return visitChildren; 303a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 304a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 305a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node) 306a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 307a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOp()) 308a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 309a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break; 310a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorLogicalNot: writeTriplet(visit, "not(", NULL, ")"); break; 311a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLogicalNot: writeTriplet(visit, "(!", NULL, ")"); break; 312a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 313a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPostIncrement: writeTriplet(visit, "(", NULL, "++)"); break; 314a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPostDecrement: writeTriplet(visit, "(", NULL, "--)"); break; 315a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPreIncrement: writeTriplet(visit, "(++", NULL, ")"); break; 316a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPreDecrement: writeTriplet(visit, "(--", NULL, ")"); break; 317a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 318a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvIntToBool: 319a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvFloatToBool: 320a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOperand()->getType().getNominalSize()) 321a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 322a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 1: writeTriplet(visit, "bool(", NULL, ")"); break; 323a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 2: writeTriplet(visit, "bvec2(", NULL, ")"); break; 324a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 3: writeTriplet(visit, "bvec3(", NULL, ")"); break; 325a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 4: writeTriplet(visit, "bvec4(", NULL, ")"); break; 326a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 327a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 328a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 329a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvBoolToFloat: 330a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvIntToFloat: 331a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOperand()->getType().getNominalSize()) 332a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 333a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 1: writeTriplet(visit, "float(", NULL, ")"); break; 334a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 2: writeTriplet(visit, "vec2(", NULL, ")"); break; 335a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 3: writeTriplet(visit, "vec3(", NULL, ")"); break; 336a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 4: writeTriplet(visit, "vec4(", NULL, ")"); break; 337a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 338a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 339a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 340a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvFloatToInt: 341a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConvBoolToInt: 342a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOperand()->getType().getNominalSize()) 343a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 344a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 1: writeTriplet(visit, "int(", NULL, ")"); break; 345a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 2: writeTriplet(visit, "ivec2(", NULL, ")"); break; 346a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 3: writeTriplet(visit, "ivec3(", NULL, ")"); break; 347a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case 4: writeTriplet(visit, "ivec4(", NULL, ")"); break; 348a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); 349a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 350a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 351a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 352a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpRadians: writeTriplet(visit, "radians(", NULL, ")"); break; 353a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDegrees: writeTriplet(visit, "degrees(", NULL, ")"); break; 354a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSin: writeTriplet(visit, "sin(", NULL, ")"); break; 355a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpCos: writeTriplet(visit, "cos(", NULL, ")"); break; 356a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpTan: writeTriplet(visit, "tan(", NULL, ")"); break; 357a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAsin: writeTriplet(visit, "asin(", NULL, ")"); break; 358a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAcos: writeTriplet(visit, "acos(", NULL, ")"); break; 359a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAtan: writeTriplet(visit, "atan(", NULL, ")"); break; 360a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 361a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpExp: writeTriplet(visit, "exp(", NULL, ")"); break; 362a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLog: writeTriplet(visit, "log(", NULL, ")"); break; 363a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpExp2: writeTriplet(visit, "exp2(", NULL, ")"); break; 364a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLog2: writeTriplet(visit, "log2(", NULL, ")"); break; 365a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSqrt: writeTriplet(visit, "sqrt(", NULL, ")"); break; 366a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpInverseSqrt: writeTriplet(visit, "inversesqrt(", NULL, ")"); break; 367a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 368a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAbs: writeTriplet(visit, "abs(", NULL, ")"); break; 369a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSign: writeTriplet(visit, "sign(", NULL, ")"); break; 370a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpFloor: writeTriplet(visit, "floor(", NULL, ")"); break; 371a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpCeil: writeTriplet(visit, "ceil(", NULL, ")"); break; 372a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpFract: writeTriplet(visit, "fract(", NULL, ")"); break; 373a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 374a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLength: writeTriplet(visit, "length(", NULL, ")"); break; 375a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpNormalize: writeTriplet(visit, "normalize(", NULL, ")"); break; 376a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 377ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case EOpDFdx: writeTriplet(visit, "dFdx(", NULL, ")"); break; 378ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case EOpDFdy: writeTriplet(visit, "dFdy(", NULL, ")"); break; 379ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch case EOpFwidth: writeTriplet(visit, "fwidth(", NULL, ")"); break; 380ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 381a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAny: writeTriplet(visit, "any(", NULL, ")"); break; 382a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAll: writeTriplet(visit, "all(", NULL, ")"); break; 383a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 384a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 385a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 386a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 387a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 388a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 389a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 390a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitSelection(Visit visit, TIntermSelection* node) 391a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 392a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 393a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 394a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (node->usesTernaryOperator()) 395a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 396a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Notice two brackets at the beginning and end. The outer ones 397a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // encapsulate the whole ternary expression. This preserves the 398a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // order of precedence when ternary expressions are used in a 399a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // compound expression, i.e., c = 2 * (a < b ? 1 : 2). 400a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "(("; 401a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->getCondition()->traverse(this); 402a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ") ? ("; 403a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->getTrueBlock()->traverse(this); 404a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ") : ("; 405a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->getFalseBlock()->traverse(this); 406a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "))"; 407a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 408a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 409a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 410a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "if ("; 411a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->getCondition()->traverse(this); 412a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")\n"; 413a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 414a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block incrementDepth(); 415a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitCodeBlock(node->getTrueBlock()); 416a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 417a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (node->getFalseBlock()) 418a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 419a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "else\n"; 420a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitCodeBlock(node->getFalseBlock()); 421a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 422a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block decrementDepth(); 423a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 424a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 425a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 426a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 427a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node) 428a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 429a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block bool visitChildren = true; 430a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 431a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getOp()) 432a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 433a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSequence: { 434a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Scope the sequences except when at the global scope. 435a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (depth > 0) out << "{\n"; 436a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 437a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block incrementDepth(); 438a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TIntermSequence& sequence = node->getSequence(); 439a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block for (TIntermSequence::const_iterator iter = sequence.begin(); 440a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block iter != sequence.end(); ++iter) 441a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 442a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermNode* node = *iter; 443a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(node != NULL); 444a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->traverse(this); 445a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 446a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (isSingleStatement(node)) 447a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ";\n"; 448a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 449a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block decrementDepth(); 450a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 451a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Scope the sequences except when at the global scope. 452a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (depth > 0) out << "}\n"; 453a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 454a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 455a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 456a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPrototype: { 457a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Function declaration. 458a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(visit == PreVisit); 459a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TString returnType = getTypeName(node->getType()); 460a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << returnType << " " << node->getName(); 461a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 462a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "("; 463a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeFunctionParameters(node->getSequence()); 464a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")"; 465a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 466a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 467a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 468a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 469a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpFunction: { 470a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Function definition. 471a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(visit == PreVisit); 472a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TString returnType = getTypeName(node->getType()); 473a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TString functionName = TFunction::unmangleName(node->getName()); 474a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << returnType << " " << functionName; 475a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 476a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block incrementDepth(); 477a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Function definition node contains one or two children nodes 478a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // representing function parameters and function body. The latter 479a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // is not present in case of empty function bodies. 480a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TIntermSequence& sequence = node->getSequence(); 481a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT((sequence.size() == 1) || (sequence.size() == 2)); 482a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermSequence::const_iterator seqIter = sequence.begin(); 483a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 484a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Traverse function parameters. 485a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermAggregate* params = (*seqIter)->getAsAggregate(); 486a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(params != NULL); 487a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(params->getOp() == EOpParameters); 488a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block params->traverse(this); 489a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 490a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Traverse function body. 491a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TIntermAggregate* body = ++seqIter != sequence.end() ? 492a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block (*seqIter)->getAsAggregate() : NULL; 493a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitCodeBlock(body); 494a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block decrementDepth(); 495a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 496a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Fully processed; no need to visit children. 497a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 498a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 499a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 500a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpFunctionCall: 501a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Function call. 502a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == PreVisit) 503a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 504a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TString functionName = TFunction::unmangleName(node->getName()); 505a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << functionName << "("; 506a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 507a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (visit == InVisit) 508a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 509a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ", "; 510a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 511a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 512a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 513a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")"; 514a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 515a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 516a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpParameters: { 517a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Function parameters. 518a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(visit == PreVisit); 519a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "("; 520a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeFunctionParameters(node->getSequence()); 521a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")"; 522a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitChildren = false; 523a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 524a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 525a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDeclaration: { 526a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Variable declaration. 527a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == PreVisit) 528a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 529a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TIntermSequence& sequence = node->getSequence(); 530a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TIntermTyped* variable = sequence.front()->getAsTyped(); 531a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block writeVariableType(variable->getType()); 532a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << " "; 533a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaringVariables = true; 534a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 535a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (visit == InVisit) 536a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 537a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ", "; 538a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaringVariables = true; 539a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 540a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 541a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 542a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block mDeclaringVariables = false; 543a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 544a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 545a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 546a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; 547a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; 548a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; 549a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break; 550a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break; 551a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break; 552a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break; 553a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break; 554a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break; 555a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break; 556a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break; 557a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break; 558a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break; 559a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break; 560a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break; 561a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpConstructStruct: 562a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (visit == PreVisit) 563a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 564a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block const TType& type = node->getType(); 565a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block ASSERT(type.getBasicType() == EbtStruct); 566a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << type.getTypeName() << "("; 567a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 568a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else if (visit == InVisit) 569a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 570a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ", "; 571a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 572a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 573a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 574a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")"; 575a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 576a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block break; 577a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 578a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLessThan: writeTriplet(visit, "lessThan(", ", ", ")"); break; 579a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpGreaterThan: writeTriplet(visit, "greaterThan(", ", ", ")"); break; 580a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpLessThanEqual: writeTriplet(visit, "lessThanEqual(", ", ", ")"); break; 581a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpGreaterThanEqual: writeTriplet(visit, "greaterThanEqual(", ", ", ")"); break; 582a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorEqual: writeTriplet(visit, "equal(", ", ", ")"); break; 583a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpVectorNotEqual: writeTriplet(visit, "notEqual(", ", ", ")"); break; 584a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break; 585a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 586a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMod: writeTriplet(visit, "mod(", ", ", ")"); break; 587a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpPow: writeTriplet(visit, "pow(", ", ", ")"); break; 588a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpAtan: writeTriplet(visit, "atan(", ", ", ")"); break; 589a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMin: writeTriplet(visit, "min(", ", ", ")"); break; 590a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMax: writeTriplet(visit, "max(", ", ", ")"); break; 591a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpClamp: writeTriplet(visit, "clamp(", ", ", ")"); break; 592a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMix: writeTriplet(visit, "mix(", ", ", ")"); break; 593a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpStep: writeTriplet(visit, "step(", ", ", ")"); break; 594a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpSmoothStep: writeTriplet(visit, "smoothstep(", ", ", ")"); break; 595a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 596a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDistance: writeTriplet(visit, "distance(", ", ", ")"); break; 597a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpDot: writeTriplet(visit, "dot(", ", ", ")"); break; 598a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpCross: writeTriplet(visit, "cross(", ", ", ")"); break; 599a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpFaceForward: writeTriplet(visit, "faceforward(", ", ", ")"); break; 600a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpReflect: writeTriplet(visit, "reflect(", ", ", ")"); break; 601a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpRefract: writeTriplet(visit, "refract(", ", ", ")"); break; 602a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpMul: writeTriplet(visit, "matrixCompMult(", ", ", ")"); break; 603a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 604a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 605a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 606a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return visitChildren; 607a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 608a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 609a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node) 610a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 611a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase& out = objSink(); 612a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 613a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block incrementDepth(); 614a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Loop header. 615ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch TLoopType loopType = node->getType(); 616ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (loopType == ELoopFor) // for loop 617a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 618a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "for ("; 619a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (node->getInit()) 620a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->getInit()->traverse(this); 621a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "; "; 622a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 623ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (node->getCondition()) 624ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch node->getCondition()->traverse(this); 625a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "; "; 626a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 627ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (node->getExpression()) 628ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch node->getExpression()->traverse(this); 629ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch out << ")\n"; 630ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 631ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch else if (loopType == ELoopWhile) // while loop 632ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch { 633ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch out << "while ("; 634ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(node->getCondition() != NULL); 635ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch node->getCondition()->traverse(this); 636a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ")\n"; 637a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 638a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else // do-while loop 639a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 640ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(loopType == ELoopDoWhile); 641a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "do\n"; 642a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 643a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 644a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Loop body. 645a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block visitCodeBlock(node->getBody()); 646a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 647a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Loop footer. 648ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (loopType == ELoopDoWhile) // do-while loop 649a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 650a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "while ("; 651ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch ASSERT(node->getCondition() != NULL); 652ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch node->getCondition()->traverse(this); 653a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ");\n"; 654a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 655a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block decrementDepth(); 656a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 657a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // No need to visit children. They have been already processed in 658a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // this function. 659a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return false; 660a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 661a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 662a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockbool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node) 663a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block{ 664a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block switch (node->getFlowOp()) 665a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 666a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break; 667a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break; 668a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break; 669a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break; 670a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block default: UNREACHABLE(); break; 671a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 672a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 673a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block return true; 674a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 675a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block 676a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Blockvoid TOutputGLSL::visitCodeBlock(TIntermNode* node) { 677a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block TInfoSinkBase &out = objSink(); 678a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (node != NULL) 679a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 680a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block node->traverse(this); 681a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // Single statements not part of a sequence need to be terminated 682a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block // with semi-colon. 683a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block if (isSingleStatement(node)) 684a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << ";\n"; 685a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 686a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block else 687a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block { 688a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block out << "{\n}\n"; // Empty code block. 689a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block } 690a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579Steve Block} 691