ShTransformer.hpp

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

Generated on Wed Nov 9 15:29:40 2005 for Sh by  doxygen 1.4.5