00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright 2003-2006 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 00123 void texd_to_texlod(); 00124 00125 private: 00127 ShTransformer(const ShTransformer& other); 00129 ShTransformer& operator=(const ShTransformer& other); 00130 00131 ShProgramNodePtr m_program; 00132 bool m_changed; 00133 }; 00134 00135 /* A default transformer. 00136 * T can overload any of the methods in ShTransformerParent 00137 * 00138 * - void start(const ShProgramNodePtr&) 00139 * Does whatever initialization may be necessary. Initializes changed() to 00140 * false. 00141 * 00142 * - void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type); 00143 * This is called first and fixes anything that needs to be fixed in the 00144 * variable lists. 00145 * - handleTexList, handleChannelList, handlePaletteList are similar 00146 * 00147 * - bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, const ShCtrlGraphNodePtr& node); 00148 * This performs some kind of per-statement transformation during a dfs 00149 * through the cfg. Returns true iff the transformation has already 00150 * incremented I (or deleted I and moved I to the next element). 00151 * 00152 * - void finish(); 00153 * Does any cleanup necessary afterwards, any other transformations to wrap 00154 * things up. 00155 * 00156 * Note - this allows you to split a set of multipass transformations into 00157 * smaller chunks by chaining transformers together. Have one transformer's 00158 * finish call the next transformer's transform()... 00159 * 00160 * It must also implement this method: 00161 * - bool changed() 00162 * Returns whether this transformer changed anything 00163 * 00164 * @todo range - this sequence of transformations (varlist, statements, finish), 00165 * might not be the right abstraction...it's just matches most of what we have 00166 * used so far - first pass identifies something about the variables, 00167 * second actually fixes the cfg, and final pass does any general stuff 00168 * that doesn't fit in. 00169 */ 00170 template<typename T> 00171 struct ShDefaultTransformer: public T { 00172 // Applies transformation to the given ctrl graph node. 00173 void operator()(const ShCtrlGraphNodePtr& node); 00174 00175 // Applies transformation to the given ShProgram 00176 bool transform(const ShProgramNodePtr& p); 00177 }; 00178 00179 struct ShTransformerParent { 00180 ShTransformerParent() : m_changed(false) {} 00181 void start(const ShProgramNodePtr& program) { m_program = program; } 00182 void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type) {} 00183 void handleTexList(ShProgramNode::TexList &texlist) {} 00184 void handleChannelList(ShProgramNode::ChannelList &chanlist) {} 00185 void handlePaletteList(ShProgramNode::PaletteList &palettelist) {} 00186 00187 bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, const ShCtrlGraphNodePtr& node) { return false; } 00188 void finish() {} 00189 bool changed() 00190 { return m_changed; } 00191 00192 protected: 00193 ShProgramNodePtr m_program; 00194 bool m_changed; 00195 }; 00196 00197 } 00198 00199 #include "ShTransformerImpl.hpp" 00200 00201 #endif
1.4.6