Developer Documentation
GPUCacheOptimizer.hh
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 #ifndef ACG_GPU_CACHE_OPT_HH
43 #define ACG_GPU_CACHE_OPT_HH
44 
45 
46 //== INCLUDES =================================================================
47 
48 #include <ACG/Config/ACGDefines.hh>
49 
50 //== FORWARDDECLARATIONS ======================================================
51 
52 //== NAMESPACES ===============================================================
53 
54 namespace ACG {
55 
56 //== CLASS DEFINITION =========================================================
57 
58 
64 class ACGDLLEXPORT GPUCacheOptimizer
65 {
66 private:
67  // copy ops are private to prevent copying
68  GPUCacheOptimizer(const GPUCacheOptimizer&); // no implementation
69  GPUCacheOptimizer& operator=(const GPUCacheOptimizer&); // no implementation
70 public:
71 
81  GPUCacheOptimizer(unsigned int NumTris, unsigned int NumVerts, unsigned int IndexSize, const void* pIndices);
82  virtual ~GPUCacheOptimizer(void);
83 
84 
92  const unsigned int* GetTriangleMap() const {return m_pTriMap;}
93 
102  void WriteIndexBuffer(unsigned int DstIndexSize, void* pDst);
103 
104 
120  static void OptimizeVertices(unsigned int NumTris, unsigned int NumVerts, unsigned int IndexSize,
121  const void* pIndices, unsigned int* pVertMap);
122  // this function is declared static to be able to operate on the whole model
123  // instead of just a subset of it
124  // example use:
125  // - optimize triangle list per material group
126  // - optimize vertex buffer on whole mesh independently of material subsets
127 
128 
150  static void RemapVertices(unsigned int NumTris, unsigned int NumVerts, const unsigned int* pVertMap,
151  unsigned int IndexSize, void* pInOutIndices, unsigned int VertexStride, void* pInOutVertices);
152 
153 
157  unsigned int ComputeNumberOfVertexTransformations(unsigned int VertexCacheSize = 16);
158 
163  float ComputeACMR(unsigned int VertexCacheSize = 16);
164 
171  float ComputeATVR(unsigned int VertexCacheSize = 16);
172 
173 protected:
174  // look up m_pIndices w.r.t. index size at location 'i'
175  unsigned int GetIndex(unsigned int i) const;
176 
177  static unsigned int GetIndex(unsigned int i, unsigned int IndexSize, const void* pIB);
178  static void SetIndex(unsigned int i, unsigned int val, unsigned int IndexSize, void* pIB);
179 
180  virtual void MakeAbstract() = 0;
181 
182 protected:
183 
184 
185  unsigned int m_NumVerts;
186  unsigned int m_NumTris;
187 
192  unsigned int* m_pTriMap;
193 
194 private:
195  unsigned int m_IndexSize;
196  const void* m_pIndices;
197 
198 
199  unsigned int m_NumTransformations;
200 
201 
202 protected:
207  struct Opt_Vertex
208  {
209  // Opt_Vertex(): iCachePos(-1), fScore(0.0f), iNumTrisTotal(0), iNumTrisLeft(0), pTris(0) {}
210  // ~Opt_Vertex() {delete [] pTris;}
211 
212  int iCachePos;
213  float fScore;
218  unsigned int* pTris;
219 
221  void FindScore(unsigned int MaxSizeVertexCache);
222 
223  void RemoveTriFromList(unsigned int tri);
224  };
225 
226  struct Opt_Tris
227  {
228  Opt_Tris() : bAdded(0), fScore(0.0f)
229  { v[0] = v[1] = v[2] = 0xDEADBEEF;}
230 
231  int bAdded;
233  float fScore;
235  unsigned int v[3];
236 
237  inline void FindScore(const Opt_Vertex* pVertices)
238  {
239  fScore = 0.0f;
240  for (int i = 0; i < 3; ++i)
241  fScore += pVertices[v[i]].fScore;
242  }
243  };
244 };
245 
247 
254 class ACGDLLEXPORT GPUCacheOptimizerTipsify : public GPUCacheOptimizer
255 {
256 public:
257 
266  GPUCacheOptimizerTipsify(unsigned int CacheSize,
267  unsigned int NumTris,
268  unsigned int NumVerts,
269  unsigned int IndexSize,
270  const void* pIndices);
271 
272 private:
273 
274  void MakeAbstract(){}
275 
277  struct RingStack
278  {
279  private:
280  unsigned int* pStack;
281  unsigned int uiStart, uiLen;
282  unsigned int uiSize;
283 
284  inline unsigned int pos(unsigned int i) const
285  {
286  unsigned int t = uiStart + i;
287  if (t >= uiLen) t -= uiLen;
288  return t;
289  }
290 
291  public:
292  explicit RingStack(unsigned int _uiSize) :
293  uiStart(0),
294  uiLen(0),
295  uiSize(_uiSize)
296  {
297  pStack = new unsigned int[uiSize];
298  }
299 
300  RingStack(const RingStack& _other)
301  {
302  // Copy meta data
303  uiSize = _other.uiSize;
304  uiLen = _other.uiLen;
305  uiStart = _other.uiStart;
306 
307  // Create empty storage
308  pStack = new unsigned int[uiSize];
309 
310  // Copy storage from original to current storage
311  for (unsigned int i = 0 ; i < uiSize; ++i )
312  pStack[i] = _other.pStack[i];
313 
314  }
315 
316  ~RingStack() {delete [] pStack;}
317 
318  unsigned int length() const {return uiLen;}
319  unsigned int size() const {return uiSize;}
320 
321  inline void push(unsigned int v)
322  {
323  if (uiLen == uiSize)
324  {
325  pStack[uiStart++] = v;
326  if (uiStart == uiSize) uiStart = 0;
327  }
328  else
329  pStack[pos(uiLen++)] = v; // pos(uiLen) gives the index of the last element + 1
330  }
331 
332  inline unsigned int pop()
333  {
334  if (uiSize && uiLen) return pStack[pos(--uiLen)];
335  return 0xFFFFFFFF;
336  }
337  };
338 };
339 
344 class ACGDLLEXPORT GPUCacheEfficiencyTester : public GPUCacheOptimizer
345 {
346 public:
347  GPUCacheEfficiencyTester(unsigned int NumTris, unsigned int NumVerts, unsigned int IndexSize, const void* pIndices);
348 
349 private:
350  void MakeAbstract(){}
351 };
352 
353 
354 
355 //=============================================================================
356 } // namespace ACG
357 //=============================================================================
358 #endif // ACG_GPU_CACHE_OPT_HH defined
359 //=============================================================================
360 
const unsigned int * GetTriangleMap() const
Retrieves the map from dst triangle to src triangle. how to remap: for each triangle t in DstTriBuffe...
Namespace providing different geometric functions concerning angles.
unsigned int size() const
reserved stack size i.e. maximum length
int iNumTrisTotal
tris using this vertex
int iNumTrisLeft
tris left to add to final result
float fScore
sum of scores of vertices
Simple and fast fixed size stack used in tipsify implementation.
unsigned int length() const
current stack length