00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright 2003-2005 Serious Hack Inc. 00004 // 00005 // This software is provided 'as-is', without any express or implied 00006 // warranty. In no event will the authors be held liable for any damages 00007 // arising from the use of this software. 00008 // 00009 // Permission is granted to anyone to use this software for any purpose, 00010 // including commercial applications, and to alter it and redistribute it 00011 // freely, subject to the following restrictions: 00012 // 00013 // 1. The origin of this software must not be misrepresented; you must 00014 // not claim that you wrote the original software. If you use this 00015 // software in a product, an acknowledgment in the product documentation 00016 // would be appreciated but is not required. 00017 // 00018 // 2. Altered source versions must be plainly marked as such, and must 00019 // not be misrepresented as being the original software. 00020 // 00021 // 3. This notice may not be removed or altered from any source 00022 // distribution. 00024 #ifndef SHTRANSFORMER_HPP 00025 #define SHTRANSFORMER_HPP 00026 00027 #include "ShDllExport.hpp" 00028 #include "ShBackend.hpp" 00029 #include "ShProgram.hpp" 00030 #include "ShCtrlGraph.hpp" 00031 #include "ShInternals.hpp" 00032 #include "ShVariableType.hpp" 00033 00034 namespace SH { 00035 00049 class 00050 SH_DLLEXPORT ShTransformer { 00051 public: 00052 ShTransformer(const ShProgramNodePtr& program); 00053 ShTransformer::~ShTransformer(); 00054 bool changed(); //< returns true iff one of the transformations changed the shader 00055 00066 typedef std::vector<ShVariableNodePtr> VarNodeVec; 00067 typedef std::map<ShVariableNodePtr, VarNodeVec> VarSplitMap; 00068 friend struct VariableSplitter; 00069 friend struct StatementSplitter; 00070 void splitTuples(int maxTuple, VarSplitMap &splits); 00072 00082 friend struct InputOutputConvertor; 00083 void convertInputOutput(); 00085 00091 void convertTextureLookups(); 00093 00094 typedef std::map<ShValueType, ShValueType> ValueTypeMap; 00105 void convertToFloat(ValueTypeMap &typeMap); 00106 00107 //@todo use dependent uniforms in conversion and spliting functions 00108 //instead of separate VarSplitMaps and ShVarMaps 00109 00112 void stripDummyOps(); 00113 00114 private: 00116 ShTransformer(const ShTransformer& other); 00118 ShTransformer& operator=(const ShTransformer& other); 00119 00120 ShProgramNodePtr m_program; 00121 bool m_changed; 00122 }; 00123 00124 /* A default transformer. 00125 * T can overload any of the methods in ShTransformerParent 00126 * 00127 * - void start(ShProgramNodePtr) 00128 * Does whatever initialization may be necessary. Initializes changed() to 00129 * false. 00130 * 00131 * - void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type); 00132 * This is called first and fixes anything that needs to be fixed in the 00133 * variable lists. 00134 * - handleTexList, handleChannelList, handlePaletteList are similar 00135 * 00136 * - bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, ShCtrlGraphNodePtr node); 00137 * This performs some kind of per-statement transformation during a dfs 00138 * through the cfg. Returns true iff the transformation has already 00139 * incremented I (or deleted I and moved I to the next element). 00140 * 00141 * - void finish(); 00142 * Does any cleanup necessary afterwards, any other transformations to wrap 00143 * things up. 00144 * 00145 * Note - this allows you to split a set of multipass transformations into 00146 * smaller chunks by chaining transformers together. Have one transformer's 00147 * finish call the next transformer's transform()... 00148 * 00149 * It must also implement this method: 00150 * - bool changed() 00151 * Returns whether this transformer changed anything 00152 * 00153 * @todo range - this sequence of transformations (varlist, statements, finish), 00154 * might not be the right abstraction...it's just matches most of what we have 00155 * used so far - first pass identifies something about the variables, 00156 * second actually fixes the cfg, and final pass does any general stuff 00157 * that doesn't fit in. 00158 */ 00159 template<typename T> 00160 struct ShDefaultTransformer: public T { 00161 // Applies transformation to the given ctrl graph node. 00162 void operator()(ShCtrlGraphNodePtr node); 00163 00164 // Applies transformation to the given ShProgram 00165 bool transform(ShProgramNodePtr p); 00166 }; 00167 00168 struct ShTransformerParent { 00169 ShTransformerParent() : m_changed(false) {} 00170 void start(ShProgramNodePtr program) { m_program = program; } 00171 void handleVarList(ShProgramNode::VarList &varlist, ShBindingType type) {} 00172 void handleTexList(ShProgramNode::TexList &texlist) {} 00173 void handleChannelList(ShProgramNode::ChannelList &chanlist) {} 00174 void handlePaletteList(ShProgramNode::PaletteList &palettelist) {} 00175 00176 bool handleStmt(ShBasicBlock::ShStmtList::iterator &I, ShCtrlGraphNodePtr node) { return false; } 00177 void finish() {} 00178 bool changed() 00179 { return m_changed; } 00180 00181 protected: 00182 ShProgramNodePtr m_program; 00183 bool m_changed; 00184 }; 00185 00186 } 00187 00188 #include "ShTransformerImpl.hpp" 00189 00190 #endif
1.4.2