00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright 2003-2005 Serious Hack Inc. 00004 // 00005 // This library is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This library is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this library; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00018 // MA 02110-1301, USA 00020 #ifndef SHTRANSFORMER_HPP 00021 #define SHTRANSFORMER_HPP 00022 00023 #include "ShDllExport.hpp" 00024 #include "ShBackend.hpp" 00025 #include "ShProgram.hpp" 00026 #include "ShCtrlGraph.hpp" 00027 #include "ShInternals.hpp" 00028 #include "ShVariableType.hpp" 00029 00030 namespace SH { 00031 00045 class 00046 SH_DLLEXPORT ShTransformer { 00047 public: 00048 ShTransformer(const ShProgramNodePtr& program); 00049 ~ShTransformer(); 00050 bool changed(); //< returns true iff one of the transformations changed the shader 00051 00062 typedef std::vector<ShVariableNodePtr> VarNodeVec; 00063 typedef std::map<ShVariableNodePtr, VarNodeVec> VarSplitMap; 00064 friend struct VariableSplitter; 00065 friend struct StatementSplitter; 00066 void splitTuples(int maxTuple, VarSplitMap &splits); 00068 00081 friend struct InputOutputConvertor; 00082 void convertInputOutput(ShVarTransformMap *varTransMap = 0); 00084 00090 void convertTextureLookups(); 00092 00093 typedef std::map<ShValueType, ShValueType> ValueTypeMap; 00104 void convertToFloat(ValueTypeMap &typeMap); 00105 00106 //@todo use dependent uniforms in conversion and spliting functions 00107 //instead of separate VarSplitMaps and ShVarMaps 00108 00111 void stripDummyOps(); 00112 00115 void expand_atan2(); 00116 00119 void expand_inverse_hyperbolic(); 00120 00121 private: 00123 ShTransformer(const ShTransformer& other); 00125 ShTransformer& operator=(const ShTransformer& other); 00126 00127 ShProgramNodePtr m_program; 00128 bool m_changed; 00129 }; 00130 00131 /* A default transformer. 00132 * T can overload any of the methods in ShTransformerParent 00133 * 00134 * - void start(ShProgramNodePtr) 00135 * Does whatever initialization may be necessary. Initializes changed() to 00136 * false. 00137 * 00138 * - void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type); 00139 * This is called first and fixes anything that needs to be fixed in the 00140 * variable lists. 00141 * - handleTexList, handleChannelList, handlePaletteList are similar 00142 * 00143 * - bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, ShCtrlGraphNodePtr node); 00144 * This performs some kind of per-statement transformation during a dfs 00145 * through the cfg. Returns true iff the transformation has already 00146 * incremented I (or deleted I and moved I to the next element). 00147 * 00148 * - void finish(); 00149 * Does any cleanup necessary afterwards, any other transformations to wrap 00150 * things up. 00151 * 00152 * Note - this allows you to split a set of multipass transformations into 00153 * smaller chunks by chaining transformers together. Have one transformer's 00154 * finish call the next transformer's transform()... 00155 * 00156 * It must also implement this method: 00157 * - bool changed() 00158 * Returns whether this transformer changed anything 00159 * 00160 * @todo range - this sequence of transformations (varlist, statements, finish), 00161 * might not be the right abstraction...it's just matches most of what we have 00162 * used so far - first pass identifies something about the variables, 00163 * second actually fixes the cfg, and final pass does any general stuff 00164 * that doesn't fit in. 00165 */ 00166 template<typename T> 00167 struct ShDefaultTransformer: public T { 00168 // Applies transformation to the given ctrl graph node. 00169 void operator()(ShCtrlGraphNodePtr node); 00170 00171 // Applies transformation to the given ShProgram 00172 bool transform(ShProgramNodePtr p); 00173 }; 00174 00175 struct ShTransformerParent { 00176 ShTransformerParent() : m_changed(false) {} 00177 void start(ShProgramNodePtr program) { m_program = program; } 00178 void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type) {} 00179 void handleTexList(ShProgramNode::TexList &texlist) {} 00180 void handleChannelList(ShProgramNode::ChannelList &chanlist) {} 00181 void handlePaletteList(ShProgramNode::PaletteList &palettelist) {} 00182 00183 bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, ShCtrlGraphNodePtr node) { return false; } 00184 void finish() {} 00185 bool changed() 00186 { return m_changed; } 00187 00188 protected: 00189 ShProgramNodePtr m_program; 00190 bool m_changed; 00191 }; 00192 00193 } 00194 00195 #include "ShTransformerImpl.hpp" 00196 00197 #endif
1.4.5