Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
sat.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
5 * www.openflipper.org *
6 * *
7 *--------------------------------------------------------------------------- *
8 * This file is part of OpenFlipper. *
9 * *
10 * OpenFlipper is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenFlipper is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenFlipper. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36 * *
37 * $Revision: 17080 $ *
38 * $LastChangedBy: moeller $ *
39 * $Date: 2013-07-19 12:58:31 +0200 (Fri, 19 Jul 2013) $ *
40 * *
41 \*===========================================================================*/
42 
43 #pragma once
44 
45 #include <ACG/GL/globjects.hh>
46 
47 #include <QStringList>
48 #include <map>
49 
51 {
52 public:
53 
54  /*
55  width of input texture must be a multiple of _blocksize!!
56  if that's not the case, prepare the input before calling execute().
57  width() will return the expected width, and padInput can do the padding if necessary
58  */
59  PrefixSumPlan(int _w, int _h, GLenum _internalFmt = GL_R32F, int _blocksize = 32);
60  virtual ~PrefixSumPlan();
61 
62 
63 
64  // copy _src to _dst and pad _dst to expected dimension for execute()
65  // this will also initialize _dst with the correct width as necessary
66  // _padWidthAndHeight also pads the height to a multiple of blocksize (good for 2D SAT)
67  bool padInput(ACG::Texture2D* _src, ACG::Texture2D* _dst, bool _padWidthAndHeight);
68 
69 
70  bool execute(ACG::TextureBuffer* _src, ACG::TextureBuffer* _dst);
71  bool execute(ACG::Texture2D* _src, ACG::Texture2D* _dst);
72 
73 
74  // get padded! width
75  int width() const {return width_;}
76  // get height
77  int height() const {return height_;}
78 
79  int blocksize() const {return blocksize_;}
80 
81  // size in bytes of one texel
82  int elemSize() const {return elemSize_;}
83 
84  int paddedDimension(int _dim) const;
85  int paddedBlocksize(int _size) const;
86 
87  const QStringList& macros() const {return macros_;}
88 
89 
90  // debugging stuff
91  void enableDebugOutput() {dbgOutput_ = 1;}
92  void disableDebugOutput() {dbgOutput_ = 0;}
93  bool debugOutputEnabled() {return dbgOutput_ != 0;}
94  void debugSetTransposedInput(int i) {dbgTranposedInput_ = i;}
95 
96  void enableProfiling() {dbgProfile_ = 1;}
97  void disableProfiling() {dbgProfile_ = 0;}
98  bool profilingEnabled() const {return dbgProfile_ != 0;}
99 
100 
101  // compute per row prefixsums on cpu, in-place, data in row-major alignment
102  template<class T>
103  static void executeRowsCPU(int _w, int _h, std::vector<T>& _inout);
104 
105  // compute per column prefixsums on cpu, in-place, data in row-major alignment
106  template<class T>
107  static void executeColsCPU(int _w, int _h, std::vector<T>& _inout);
108 
109 
110  static bool testBuffer(int w, int cmpMem = 1, int fullOutput = 0);
111  static bool test2D(int w, int h, int cmpMem = 1, int fullOutput = 0);
112 
113 private:
114 
115  int width_, height_;
116  int blocksize_;
117  int numWorkGroupsX_;
118  int numWorkGroupsY_;
119 
120  int numBlockScanGroupsX_;
121  int numBlockScanGroupsY_;
122  int numDispatches_;
123 
124  GLenum internalFmt_;
125  // size in bytes of one texel
126  int elemSize_;
127 
128  QStringList macros_;
129 
130  ACG::TextureBuffer blockSums_;
131  ACG::TextureBuffer blockSumsOut_;
132  ACG::Texture2D blockSums2D_;
133  ACG::Texture2D blockSums2DOut_;
134 
135  PrefixSumPlan* blockSumPlan_;
136 
137  // debugging stuff
138  int dbgOutput_;
139  int dbgTranposedInput_;
140  int dbgProfile_;
141 
142 
143  ACG::QueryCounter perfCounter_;
144 
145  static std::map<GLenum, const char*> datatypeMacros_;
146 };
147 
148 
149 
150 
151 class SATPlan
152 {
153 public:
154 
155  SATPlan(int _w, int _h, GLenum _internalFmt = GL_R32F, int _blocksize = 32);
156  virtual ~SATPlan();
157 
158 
159  bool execute(ACG::Texture2D* _src, ACG::Texture2D* _dst);
160 
161 
162  PrefixSumPlan* getRowPlan() const {return rows_;}
163  PrefixSumPlan* getColPlan() const {return cols_;}
164 
165 
166  void enableDebugOutput();
167  void enableProfiling();
168 
169  template<class T>
170  static void executeCPU(int _w, int _h, std::vector<T>& _inout);
171 
172 private:
173 
174  bool transpose(ACG::Texture2D* _src, ACG::Texture2D* _dst);
175 
176 
177  PrefixSumPlan* rows_;
178  PrefixSumPlan* cols_;
179 
180  bool paddingRequired_;
181 
182  ACG::Texture2D paddedInput_;
183  ACG::Texture2D transposedSrc_;
184  ACG::Texture2D transposedDst_;
185  QStringList transposeMacros_;
186  int transposeGroupSize_;
187 
188  ACG::QueryCounter perfCounter_;
189 };
190 
191 
192 
193 
194 
195 template<class T>
196 void PrefixSumPlan::executeRowsCPU( int w, int h, std::vector<T>& _inout )
197 {
198  if (!_inout.empty())
199  {
200  for (int r = 0; r < h; ++r)
201  {
202  int offsetRow = r*w;
203 
204  for (int c = 1; c < w; ++c)
205  {
206  int offsetRd = offsetRow + c-1;
207  int offsetWr = offsetRow + c;
208 
209  T x = _inout[offsetRow];
210  _inout[offsetRow] = _inout[offsetWr];
211 
212  if (offsetRow == offsetRd)
213  _inout[offsetWr] = x;
214  else
215  _inout[offsetWr] = _inout[offsetRd] + x;
216  }
217 
218  // reset first row element to 0
219  memset(&_inout[offsetRow], 0, sizeof(T));
220  }
221  }
222 }
223 
224 template<class T>
225 void PrefixSumPlan::executeColsCPU( int w, int h, std::vector<T>& _inout )
226 {
227  if (!_inout.empty())
228  {
229  for (int c = 0; c < w; ++c)
230  {
231  for (int r = 1; r < h; ++r)
232  {
233  int offsetRd = (r-1)*w + c;
234  int offsetWr = r*w + c;
235 
236  T x = _inout[c];
237  _inout[c] = _inout[offsetWr];
238 
239  if (c == offsetRd)
240  _inout[offsetWr] = x;
241  else
242  _inout[offsetWr] = _inout[offsetRd] + x;
243  }
244  }
245 
246  // reset first column element to 0
247  memset(&_inout[0], 0, sizeof(T) * w);
248  }
249 }
250 
251 
252 
253 template<class T>
254 void SATPlan::executeCPU( int w, int h, std::vector<T>& _inout )
255 {
256  PrefixSumPlan::executeRowsCPU(w,h, _inout);
257  PrefixSumPlan::executeColsCPU(w,h, _inout);
258 }
Definition: sat.hh:151