HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CE_BufferDevice.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CE_BufferDevice.h ( CE Library, C++)
7  *
8  * COMMENTS: Simple buffer class that works with CE_MemoryPool.
9  */
10 
11 #ifndef __CE_BufferDevice__
12 #define __CE_BufferDevice__
13 
14 #include "CE_Context.h"
15 #include "CE_Tracing.h"
16 
17 template <typename T>
19 {
20 public:
21 
22  typedef T value_type;
23 
24  /// Empty buffer constructor.
26 
27  /// Allocated an uninitialized buffer of specified size (if > 0).
29  {
30  if (size > 0)
31  init(size);
32  else
33  mySize = size;
34  }
35 
36  /// Initialize from a raw cl::Buffer, which this object now owns.
37  /// If size is not provided, calc from the buffer size and type.
38  /// The input cl::Buffer is empty after this call.
41  {
42  if (mySize < 0)
43  mySize = buf.getInfo<CL_MEM_SIZE>() / sizeof(T);
44  UT_ASSERT(mySize * sizeof(T) == buf.getInfo<CL_MEM_SIZE>());
45  buf = cl::Buffer();
46  }
47 
48  /// No copy constructor.
49  CE_BufferDevice(const CE_BufferDevice<T> &b) = delete;
50 
51  // Move constructor.
53  {
54  releaseBuffer();
55  initInternal(b.size(), false);
56  myBuffer = b.myBuffer;
57  b.myBuffer = cl::Buffer();
58  b.init(0);
59  }
60 
62 
63  /// Release and return the underlying buffer without deleting,
64  /// after which this object is empty (similar to unique_ptr).
66  {
67  cl::Buffer tmp = myBuffer;
68  myBuffer = cl::Buffer();
69  init(0);
70  return tmp;
71  }
72 
73  /// Reset to own the provided raw cl::Buffer.
74  /// If size is not provided, calc from the buffer size and type.
75  /// The input cl::Buffer is empty after this call.
76  void reset(cl::Buffer &&buf, exint size = -1)
77  {
78  releaseBuffer();
79  myBuffer = buf;
80  mySize = size;
81  if (mySize < 0)
82  mySize = buf.getInfo<CL_MEM_SIZE>() / sizeof(T);
83  UT_ASSERT(mySize * sizeof(T) == buf.getInfo<CL_MEM_SIZE>());
84  buf = cl::Buffer();
85  }
86 
87  /// Initialize to given size.
88  /// NOTE- values are undefined.
89  void init(exint size);
90 
91  /// Initialize from a UT_Array. If len >= 0, only len elements are copied.
92  void initFromArray(const UT_Array<T> &src, exint len = -1,
93  bool block = true);
94 
95  /// Resize the provided UT_Array to fit and copy this vector's data there.
96  /// If len >= 0 then only len elements are copied.
97  void matchAndCopyToArray(UT_Array<T> &dst, exint len = -1,
98  bool block = true) const;
99 
100  /// Initialize from raw data block of T elements of length nelem.
101  void initFromData(const T *data, exint nelem, bool block = true);
102 
103  /// Returns the buffer length.
104  exint size() const { return mySize; }
105 
106  /// Returns true iff there are no occupied elements in the buffer.
107  bool isEmpty() const { return mySize == 0; }
108 
109  /// Returns the underlying OpenCL buffer.
110  /// Note: This is meant for directly passing to OpenCL functions.
111  /// holding ownership over long times.
112  const cl::Buffer &buffer() const { return myBuffer; }
113 
114  /// Copy from the input buffer. If len >= 0, only len elements are copied.
115  /// NOTE: This object must already be initialized to a buffer of
116  /// sufficient size.
117  void copyFrom(const CE_BufferDevice<T> &b, exint len = -1);
118 
120  {
121  UTswap(a.myBuffer, b.myBuffer);
122  UTswap(a.mySize, b.mySize);
123  }
124 
125 protected:
126 
127  void initInternal(exint size, bool doalloc=true);
128 
129  const cl::Buffer &allocBuffer() const;
130 
131  void releaseBuffer();
132 
135 };
136 
137 template <typename T>
138 void
140 {
141  releaseBuffer();
142  mySize = size;
143  if (mySize > 0 && doalloc)
144  allocBuffer();
145 }
146 
147 template <typename T>
148 void
150 {
151  initInternal(size, true);
152 }
153 
154 template <typename T>
155 void
157 {
158  utZoneScopedFlag(CL_MEMORY);
159  size_t size = src.size();
160  // len < 0 (the default) indicates copy the whole array.
161  UT_ASSERT(len < 0 || len <= size);
162  if (len >= 0 && len <= size)
163  size = len;
164  init(size);
165  if (!size)
166  return;
167  size_t totalsize = size * sizeof(T);
168  CE_Context *context = CE_Context::getContext();
169  context->writeBuffer(myBuffer, totalsize, src.data(), blocking);
170 }
171 
172 template <typename T>
173 void
175  bool blocking) const
176 {
177  utZoneScopedFlag(CL_MEMORY);
178  size_t size = mySize;
179  // len < 0 (the default) indicates copy the whole array.
180  UT_ASSERT(len < 0 || len <= size);
181  if (len >= 0 && len <= size)
182  size = len;
183  dst.setSizeNoInit(size);
184  if (size == 0)
185  return;
186  CE_Context *context = CE_Context::getContext();
187  size_t totalsize = size * sizeof(T);
188  context->readBuffer(myBuffer, totalsize, dst.data(), blocking);
189 }
190 
191 template <typename T>
192 void
193 CE_BufferDevice<T>::initFromData(const T *data, exint nelem, bool blocking)
194 {
195  utZoneScopedFlag(CL_MEMORY);
196  init(nelem);
197  if (!nelem)
198  return;
199  size_t totalsize = nelem * sizeof(T);
200  CE_Context *context = CE_Context::getContext();
201  context->writeBuffer(myBuffer, totalsize, data, blocking);
202 }
203 
204 template <typename T>
205 const cl::Buffer&
207 {
208  UT_ASSERT(mySize > 0);
209  CE_Context *context = CE_Context::getContext();
210  myBuffer = context->allocBuffer(mySize * sizeof(T));
211  return myBuffer;
212 }
213 
214 template <typename T>
215 void
217 {
218  // This is a no-op for a null buffer.
219  CE_Context::getContext()->releaseBuffer(std::move(myBuffer));
220  myBuffer = cl::Buffer();
221 }
222 
223 template <typename T>
224 void
226 {
227  CE_Context *context = CE_Context::getContext();
228  size_t size = v.size();
229  // len < 0 (the default) indicates copy the whole array.
230  UT_ASSERT(len < 0 || len <= size);
231  if (len >= 0)
232  size = len;
233  // Make sure we are allocated and large enough for the copy.
234  UT_ASSERT(myBuffer() && size <= mySize);
235  size_t totalsize = size * sizeof(T);
236  context->copyBuffer(v.buffer(), myBuffer, totalsize);
237 }
238 
240 
241 #endif
CE_BufferDevice(CE_BufferDevice< T > &&b) noexcept
void init(exint size)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
void reset(cl::Buffer &&buf, exint size=-1)
void UTswap(T &a, T &b)
Definition: UT_Swap.h:35
const GLdouble * v
Definition: glcorearb.h:837
void setSizeNoInit(exint newsize)
Definition: UT_Array.h:702
void initFromArray(const UT_Array< T > &src, exint len=-1, bool block=true)
Initialize from a UT_Array. If len >= 0, only len elements are copied.
int64 exint
Definition: SYS_Types.h:125
void releaseBuffer(cl::Buffer &&buf, bool use_pool=true)
Release the specified buffer, possibly to the CE_MemoryPool.
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
void copyFrom(const CE_BufferDevice< T > &b, exint len=-1)
exint size() const
Returns the buffer length.
void initInternal(exint size, bool doalloc=true)
exint size() const
Definition: UT_Array.h:653
cl::Buffer myBuffer
static CE_Context * getContext(bool gl_shared=true, bool shared_fallback=true)
void readBuffer(const cl::Buffer &buf, size_t size, void *p, bool blocking=true, size_t offset=0)
Read the specified number of bytes from the buffer.
void initFromData(const T *data, exint nelem, bool block=true)
Initialize from raw data block of T elements of length nelem.
#define utZoneScopedFlag(F)
Definition: UT_Tracing.h:205
CE_BufferDevice(cl::Buffer &&buf, exint size=-1)
cl::Buffer allocBuffer(int64 size, bool use_pool=true, bool read=true, bool write=true, uint32 ogl_bind=SYS_UINT32_MAX)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
CE_BufferDevice()
Empty buffer constructor.
friend void swap(CE_BufferDevice< T > &a, CE_BufferDevice< T > &b)
GLsizeiptr size
Definition: glcorearb.h:664
GLenum GLenum dst
Definition: glcorearb.h:1793
T * data()
Definition: UT_Array.h:849
const cl::Buffer & allocBuffer() const
Memory buffer interface.
Definition: cl.hpp:1867
const cl::Buffer & buffer() const
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
#define CL_MEM_SIZE
Definition: cl.h:624
bool isEmpty() const
Returns true iff there are no occupied elements in the buffer.
CE_BufferDevice(exint size)
Allocated an uninitialized buffer of specified size (if > 0).
Definition: format.h:1821
cl::Buffer release()
void copyBuffer(const cl::Buffer &src, const cl::Buffer &dst, size_t size, size_t src_offset=0, size_t dst_offset=0)
void matchAndCopyToArray(UT_Array< T > &dst, exint len=-1, bool block=true) const
GLenum src
Definition: glcorearb.h:1793