ShTransformer.hpp

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

Generated on Thu Feb 16 14:51:38 2006 for Sh by  doxygen 1.4.6