Kinetic Visualization
 All Classes Functions Variables Pages
CudaArray.h
1 #pragma once
2 #include "common.hpp"
3 
4 template <class T>
5 class CudaArray
6 {
7 public:
11  CudaArray(void) : m_length(0), m_host(0), m_read_buffer(0), m_write_buffer(1), setmemdev(0)
12  {
13  m_dev = new T*[2];
14  m_dev[0] = 0;
15  m_dev[1] = 0;
16 
17  m_vbo = new unsigned int[2];
18  m_vbo[0] = 0;
19  m_vbo[1] = 0;
20 
21  m_cuda_vbo[0] = 0;
22  m_cuda_vbo[1] = 0;
23  }
24 
28  ~CudaArray(void)
29  {
30  std::cout << "Delete CudaArray begin" << std::endl;
31  delete[] m_host;
32  m_host = 0;
33 
34  std::cout << "Delete Buffer" << std::endl;
35  if(m_use_vbo)
36  {
37  cutilSafeCall(cudaGraphicsUnregisterResource(m_cuda_vbo[0]));
38  glDeleteBuffers(1, &m_vbo[0]);
39  m_vbo[0] = 0;
40  }
41  else
42  {
43  if(setmemdev) cutilSafeCall(cudaFree(m_dev[0]));;
44  }
45 
46  std::cout << "Delete PingPong Buffer" << std::endl;
47  if(m_pingpong)
48  {
49  if(m_use_vbo)
50  {
51  cutilSafeCall(cudaGraphicsUnregisterResource(m_cuda_vbo[1]));
52  glDeleteBuffers(1, &m_vbo[1]);
53  m_vbo[1] = 0;
54  }
55  else
56  {
57  if(setmemdev) cutilSafeCall(cudaFree(m_dev[1]));
58  }
59  }
60 
61  if(m_use_vbo)
62  {
63  delete[] m_cuda_vbo;
64  delete[] m_vbo;
65  }
66  else
67  {
68  delete[] m_dev;
69  }
70 
71  std::cout << "Delete CudaArray end" << std::endl;
72  }
73 
80  void CreateBuffer(size_t size, bool vbo=false, bool pingpong=false)
81  {
82  m_length = size;
83  m_use_vbo = vbo;
84  m_pingpong = pingpong;
85 
86  if(pingpong) m_write_buffer = 1;
87 
88  SetMemHost();
89 
90  if(m_use_vbo) SetMemVBO();
91  else SetMemDev();
92  };
93 
94  /*
95  * Returns Length of Buffer
96  * @param Length of Buffer
97  */
98  unsigned int GetLength()
99  {
100  return m_length;
101  };
102 
107  GLuint CreateVBO(size_t size)
108  {
109  GLuint tmp_vbo;
110  glGenBuffers(1, &tmp_vbo);
111  glBindBuffer(GL_ARRAY_BUFFER, tmp_vbo);
112  glBufferData(GL_ARRAY_BUFFER, size, m_host, GL_DYNAMIC_DRAW);
113  glBindBuffer(GL_ARRAY_BUFFER, 0);
114 
115  return tmp_vbo;
116  };
117 
121  void BindVBO()
122  {
123  if(m_vbo[0])
124  {
125  cutilSafeCall(cudaGraphicsMapResources(1, &m_cuda_vbo[0], 0));
126  size_t num_bytes;
127  cutilSafeCall(cudaGraphicsResourceGetMappedPointer((void **)&m_dev[0], &num_bytes, m_cuda_vbo[0]));
128  }
129  if(m_pingpong && m_vbo[1])
130  {
131  cutilSafeCall(cudaGraphicsMapResources(1, &m_cuda_vbo[1], 0));
132  size_t num_bytes;
133  cutilSafeCall(cudaGraphicsResourceGetMappedPointer((void **)&m_dev[1], &num_bytes, m_cuda_vbo[1]));
134  }
135  };
136 
140  void UnbindVBO()
141  {
142  if(m_vbo[0])
143  {
144  cutilSafeCall(cudaGraphicsUnmapResources(1, &m_cuda_vbo[0], 0));
145  m_dev[0] = 0;
146  }
147 
148  if(m_pingpong && m_vbo[1])
149  {
150  cutilSafeCall(cudaGraphicsUnmapResources(1, &m_cuda_vbo[1], 0));
151  m_dev[1] = 0;
152  }
153  };
154 
159  T* GetDevRead(){ return m_dev[m_read_buffer]; };
164  T* GetDevWrite(){ return m_dev[m_write_buffer]; };
165 
170  unsigned int GetDevReadVBO(){ return m_vbo[m_read_buffer]; };
175  unsigned int GetDevWriteVBO(){ return m_vbo[m_write_buffer]; };
176 
181  T* GetHost(){ return m_host; }
182 
183  void SetHost(T* tmp, unsigned int length)
184  {
185  m_host = tmp;
186  m_length = length;
187  }
188 
192  void Swap() { std::swap(m_read_buffer, m_write_buffer); }
193 
197  void SetMemVBO()
198  {
199  m_vbo[0] = CreateVBO(m_length*sizeof(T));
200  cutilSafeCall(cudaGraphicsGLRegisterBuffer(&m_cuda_vbo[0], m_vbo[0], cudaGraphicsMapFlagsNone));
201 
202  if(m_pingpong)
203  {
204  m_vbo[1] = CreateVBO(m_length*sizeof(T));
205  cutilSafeCall(cudaGraphicsGLRegisterBuffer(&m_cuda_vbo[1], m_vbo[1], cudaGraphicsMapFlagsNone));
206  }
207  };
208 
212  void SetMemHost()
213  {
214  m_host = (T *) new T[m_length];
215  };
216 
220  void SetMemDev()
221  {
222  setmemdev = true;
223  size_t size = m_length*sizeof(T);
224 
225  cutilSafeCall(cudaMalloc((void **) &m_dev[0], size));
226  if (m_pingpong) cutilSafeCall(cudaMalloc((void **) &m_dev[1], size));
227 
228  };
229 
234  void SetVBO(unsigned int id1)
235  {
236  m_vbo[0] = id1;
237  };
238 
244  void SetVBO(unsigned int id1, unsigned int id2)
245  {
246  m_vbo[0] = id1;
247  m_vbo[1] = id2;
248  };
249 
257  void Copy(bool tohost, unsigned int start, unsigned int count, bool use_write_buffer = false)
258  {
259  if(use_write_buffer)
260  {
261  BindVBO();
262  if(tohost) cutilSafeCall(cudaMemcpy((void *) (m_host + start), (void *) (m_dev[m_write_buffer] + start), count*sizeof(T), cudaMemcpyDeviceToHost));
263  else cutilSafeCall(cudaMemcpy((void *) (m_dev[m_write_buffer] + start), (void *) (m_host + start), count*sizeof(T), cudaMemcpyHostToDevice));
264  UnbindVBO();
265  }
266  else
267  {
268  BindVBO();
269  if(tohost) cutilSafeCall(cudaMemcpy((void *) (m_host + start), (void *) (m_dev[m_read_buffer] + start), count*sizeof(T), cudaMemcpyDeviceToHost));
270  else cutilSafeCall(cudaMemcpy((void *) (m_dev[m_read_buffer] + start), (void *) (m_host + start), count*sizeof(T), cudaMemcpyHostToDevice));
271  UnbindVBO();
272  }
273  };
274 
280  void Debug(unsigned int start, unsigned int count)
281  {
282  if(count == 0) count = m_length;
283 
284  Copy(true, 0, count);
285 
286  //unsigned int maxindex = 128*128*128;
287  for(unsigned int i=start; i<(start+count); i++)
288  {
289  //if(abs(m_host[i].x+m_host[i].y+m_host[i].z) > 0.0) printf("(%f) (%f) (%f) \n", m_host[i].x, m_host[i].y, m_host[i].z );
290  //if(m_host[i].w >= 0.0) printf("(%.4f) (%.4f) (%.4f) (%.4f) \n", m_host[i].x, m_host[i].y, m_host[i].z, m_host[i].w );
291  unsigned int tmp = m_host[i];
292  if(tmp < 0xffffffff)printf("%d \n", m_host[i]);
293  //if( m_host[i] < maxindex) printf("%d \n", m_host[i]);
294  }
295  };
296 
297 private:
298  unsigned int m_length;
299 
300  bool m_pingpong;
301  bool m_use_vbo;
302 
303  unsigned int m_read_buffer;
304  unsigned int m_write_buffer;
305 
306  unsigned int* m_vbo;
307  T** m_dev;
308  T* m_host;
309 
310  struct cudaGraphicsResource *m_cuda_vbo[2];
311 
312  bool setmemdev;
313 };
314