Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

ShManipulatorImpl.hpp

00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory 00004 // Project administrator: Michael D. McCool 00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa, 00006 // Michael D. McCool 00007 // 00008 // This software is provided 'as-is', without any express or implied 00009 // warranty. In no event will the authors be held liable for any damages 00010 // arising from the use of this software. 00011 // 00012 // Permission is granted to anyone to use this software for any purpose, 00013 // including commercial applications, and to alter it and redistribute it 00014 // freely, subject to the following restrictions: 00015 // 00016 // 1. The origin of this software must not be misrepresented; you must 00017 // not claim that you wrote the original software. If you use this 00018 // software in a product, an acknowledgment in the product documentation 00019 // would be appreciated but is not required. 00020 // 00021 // 2. Altered source versions must be plainly marked as such, and must 00022 // not be misrepresented as being the original software. 00023 // 00024 // 3. This notice may not be removed or altered from any source 00025 // distribution. 00027 #ifndef SHMANIPULATORIMPL_HPP 00028 #define SHMANIPULATORIMPL_HPP 00029 00030 #include <cstdarg> 00031 #include <cassert> 00032 #include <sstream> 00033 #include "ShVariableNode.hpp" 00034 #include "ShError.hpp" 00035 #include "ShDebug.hpp" 00036 #include "ShAlgebra.hpp" 00037 #include "ShManipulator.hpp" 00038 #include "ShInstructions.hpp" 00039 00040 namespace SH { 00041 00042 // TODO figure out a better way... 00043 #define _FIRST -54545454 00044 #define _SECOND -54545453 00045 #define _LAST 54545454 00046 00047 template<typename T> 00048 OffsetRange<T>::OffsetRange() {} 00049 00050 template<typename T> 00051 OffsetRange<T>::OffsetRange( T start, T end ) 00052 : start( start ), end( end ), startOffset( 0 ), endOffset( 0 ) {} 00053 00054 template<typename T> 00055 OffsetRange<T>::OffsetRange( T start, int startOffset, T end, int endOffset ) 00056 : start( start ), end( end ), startOffset( startOffset ), endOffset( endOffset ) {} 00057 00058 template<typename T> 00059 int OffsetRange<T>::absStartIndex( const ShProgramNode::VarList vars ) const { 00060 return absIndex( start, startOffset, vars ); 00061 } 00062 00063 template<typename T> 00064 int OffsetRange<T>::absEndIndex( const ShProgramNode::VarList vars ) const { 00065 return absIndex( end, endOffset, vars ); 00066 } 00067 00068 template<typename T> 00069 std::string OffsetRange<T>::toString() const { 00070 std::ostringstream os; 00071 os << "(" << start << (startOffset >= 0 ? "+" : "" ) << startOffset 00072 << ", " << end << (endOffset >= 0 ? "+" : "" ) << endOffset << ")"; 00073 return os.str(); 00074 } 00075 00076 template<typename T> 00077 ShManipulator<T>::ShManipulator() {} 00078 00079 template<typename T> 00080 ShManipulator<T>::~ShManipulator() { 00081 } 00082 00083 template<typename T> 00084 ShManipulator<T>& ShManipulator<T>::operator()(T i) { 00085 m_ranges.push_back(IndexRange(i, i)); 00086 return *this; 00087 } 00088 00089 template<typename T> 00090 ShManipulator<T>& ShManipulator<T>::operator()(T start, T end) { 00091 m_ranges.push_back(IndexRange(start, end)); 00092 return *this; 00093 } 00094 00095 template<typename T> 00096 ShManipulator<T>& ShManipulator<T>::operator()(const IndexRange &range) { 00097 m_ranges.push_back(range); 00098 return *this; 00099 } 00100 00101 template<typename T> 00102 typename ShManipulator<T>::IndexRangeVector ShManipulator<T>::getRanges() const { 00103 return m_ranges; 00104 } 00105 00106 template<typename T> 00107 std::string ShManipulator<T>::toString() const { 00108 std::ostringstream os; 00109 for(typename IndexRangeVector::const_iterator it = m_ranges.begin(); it != m_ranges.end(); ++it) { 00110 if(it != m_ranges.begin()) os << ", "; 00111 os << it->toString(); 00112 } 00113 return os.str(); 00114 } 00115 00116 /* input permutation */ 00117 template<typename T> 00118 ShProgram operator<<(const ShProgram &p, const ShManipulator<T> &m) { 00119 typedef typename ShManipulator<T>::IndexRangeVector RangeVec; 00120 RangeVec mranges = m.getRanges(); 00121 int i; 00122 00123 ShProgram permuter = SH_BEGIN_PROGRAM() { 00124 /* Make shader outputs from p's inputs 00125 * default output value is zero, so for those that have 00126 * no matching inputs, they become zero outputs */ 00127 std::vector<ShVariable> outputs; 00128 for(ShProgramNode::VarList::const_iterator inIt = p.node()->inputs.begin(); 00129 inIt != p.node()->inputs.end(); ++inIt) { 00130 ShVariable out(ShVariable(new ShVariableNode(SH_OUTPUT, 00131 (*inIt)->size(), (*inIt)->specialType()))); 00132 out.name((*inIt)->name()); 00133 outputs.push_back(out); 00134 } 00135 00136 int size = outputs.size(); 00137 00138 /* Make shader outputs from permuted ranges of inputs */ 00139 std::vector<bool> used(size, false); //mark used inputs 00140 for(typename RangeVec::const_iterator irvIt = mranges.begin(); 00141 irvIt != mranges.end(); ++irvIt) { 00142 int start = irvIt->absStartIndex( p.node()->inputs ); 00143 int end = irvIt->absEndIndex( p.node()->inputs ); 00144 00145 if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue; 00146 if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) { 00147 std::ostringstream os; 00148 os << "Invalid ShManipulator Range " << irvIt->toString() 00149 << " for an ShProgram with output size " << size; 00150 shError(ShAlgebraException(os.str())); 00151 } 00152 00153 for(i = start; i <= end; ++i) { 00154 if(used[i]) { 00155 std::ostringstream os; 00156 os << "Duplicate index " << i << " in range " << irvIt->toString() 00157 << " not allowed for input manipulators"; 00158 shError(ShAlgebraException(os.str())); 00159 } 00160 used[i] = true; 00161 00162 ShVariable input(new ShVariableNode(SH_INPUT, 00163 outputs[i].node()->size(), outputs[i].node()->specialType())); 00164 input.name(outputs[i].name()); 00165 00166 shASN(outputs[i], input); 00167 } 00168 } 00169 } SH_END; 00170 00171 return connect(permuter, p); 00172 } 00173 00174 template<typename T> 00175 ShProgram operator<<(const ShManipulator<T> &m, const ShProgram &p) { 00176 typedef typename ShManipulator<T>::IndexRangeVector RangeVec; 00177 RangeVec mranges = m.getRanges(); 00178 00179 ShProgram permuter = SH_BEGIN_PROGRAM() { 00180 /* Make shader inputs from p's outputs */ 00181 std::vector<ShVariable> inputs; 00182 for(ShProgramNode::VarList::const_iterator outIt = p.node()->outputs.begin(); 00183 outIt != p.node()->outputs.end(); ++outIt) { 00184 ShVariable in(new ShVariableNode(SH_INPUT, (*outIt)->size(), 00185 (*outIt)->specialType())); 00186 in.name((*outIt)->name()); 00187 inputs.push_back(in); 00188 } 00189 00190 int size = inputs.size(); 00191 00192 /* Make shader outputs from permuted ranges of inputs */ 00193 for(typename RangeVec::const_iterator irvIt = mranges.begin(); 00194 irvIt != mranges.end(); ++irvIt) { 00195 int start = irvIt->absStartIndex( p.node()->outputs ); 00196 int end = irvIt->absEndIndex( p.node()->outputs ); 00197 00198 if(start == OFFSET_RANGE_BAD_OFFSET || end == OFFSET_RANGE_BAD_OFFSET ) continue; 00199 if(start == OFFSET_RANGE_BAD_INDEX || end == OFFSET_RANGE_BAD_INDEX ) { 00200 std::ostringstream os; 00201 os << "Invalid ShManipulator Range " << irvIt->toString() << 00202 " for an ShProgram with output size " << size; 00203 shError(ShAlgebraException(os.str())); 00204 } 00205 00206 for(int i = start; i <= end; ++i) { // handles end < start case 00207 ShVariable output(new ShVariableNode(SH_OUTPUT, 00208 inputs[i].node()->size(), inputs[i].node()->specialType())); 00209 output.name( inputs[i].name() ); 00210 00211 shASN(output, inputs[i]); 00212 } 00213 } 00214 } SH_END; 00215 00216 return connect(p, permuter); 00217 } 00218 00219 template<typename T> 00220 ShManipulator<T> shSwizzle(T i0) { 00221 ShManipulator<T> m; 00222 m(i0); 00223 return m; 00224 } 00225 template<typename T> 00226 ShManipulator<T> shSwizzle(T i0, T i1) { 00227 ShManipulator<T> m; 00228 m(i0); m(i1); 00229 return m; 00230 } 00231 template<typename T> 00232 ShManipulator<T> shSwizzle(T i0, T i1, T i2) { 00233 ShManipulator<T> m; 00234 m(i0); m(i1); m(i2); 00235 return m; 00236 } 00237 00238 template<typename T> 00239 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3) { 00240 ShManipulator<T> m; 00241 m(i0); m(i1); m(i2); m(i3); 00242 return m; 00243 } 00244 00245 template<typename T> 00246 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4) { 00247 ShManipulator<T> m; 00248 m(i0); m(i1); m(i2); m(i3); m(i4); 00249 return m; 00250 } 00251 00252 template<typename T> 00253 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5) { 00254 ShManipulator<T> m; 00255 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); 00256 return m; 00257 } 00258 00259 template<typename T> 00260 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6) { 00261 ShManipulator<T> m; 00262 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 00263 return m; 00264 } 00265 00266 template<typename T> 00267 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7) { 00268 ShManipulator<T> m; 00269 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); m(i7); 00270 return m; 00271 } 00272 00273 template<typename T> 00274 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8) { 00275 ShManipulator<T> m; 00276 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 00277 m(i7); m(i8); 00278 return m; 00279 } 00280 00281 template<typename T> 00282 ShManipulator<T> shSwizzle(T i0, T i1, T i2, T i3, T i4, T i5, T i6, T i7, T i8, T i9) { 00283 ShManipulator<T> m; 00284 m(i0); m(i1); m(i2); m(i3); m(i4); m(i5); m(i6); 00285 m(i7); m(i8); m(i9); 00286 return m; 00287 } 00288 00289 template<typename T> 00290 ShManipulator<T> shSwizzle(std::vector<T> indices) { 00291 ShManipulator<T> m; 00292 for(typename std::vector<T>::iterator it = indices.begin(); 00293 it != indices.end(); ++it) { 00294 m(*it); 00295 } 00296 return m; 00297 } 00298 00299 template<typename T> 00300 ShManipulator<T> shRange(T i) { 00301 ShManipulator<T> m; 00302 m(i); 00303 return m; 00304 } 00305 00306 template<typename T> 00307 ShManipulator<T> shRange(T start, T end) { 00308 ShManipulator<T> m; 00309 m(start, end); 00310 return m; 00311 } 00312 00313 template<typename T> 00314 ShManipulator<T> shExtract(T k) { 00315 ShManipulator<T> m; 00316 m(k); 00317 typedef typename ShManipulator<T>::IndexRange Range; 00318 m(Range(k,_FIRST,k,-1)); 00319 m(Range(k,1,k,_LAST)); 00320 return m; 00321 } 00322 00323 template<typename T> 00324 ShManipulator<T> shInsert(T k) { 00325 ShManipulator<T> m; 00326 typedef typename ShManipulator<T>::IndexRange Range; 00327 00328 m(Range(k,_SECOND,k,0)); 00329 m(Range(k,_FIRST,k,_FIRST)); 00330 m(Range(k,1,k,_LAST)); 00331 std::cout << m.toString() << std::endl; 00332 return m; 00333 } 00334 00335 template<typename T> 00336 ShManipulator<T> shDrop(T k) { 00337 ShManipulator<T> m; 00338 typedef typename ShManipulator<T>::IndexRange Range; 00339 m(Range(k,_FIRST,k,-1)); 00340 m(Range(k,1,k,_LAST)); 00341 return m; 00342 } 00343 00344 } 00345 00346 #endif

Generated on Mon Oct 18 14:17:39 2004 for Sh by doxygen 1.3.7