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_ArrayView.h"
15 #include "CE_Context.h"
16 #include "CE_Tracing.h"
17 #include <SYS/SYS_Inline.h>
18 #include <SYS/SYS_TypeTraits.h>
19 
20 template <typename T>
21 class CE_BufferDevice
22 {
23 public:
24 
25  typedef T value_type;
26 
27  /// Empty buffer constructor.
28  CE_BufferDevice() { mySize = 0; }
29 
30  /// Allocated an uninitialized buffer of specified size (if > 0).
32  {
33  if (size > 0)
34  init(size);
35  else
36  mySize = size;
37  }
38 
39  /// Initialize from a raw cl::Buffer, which this object now owns.
40  /// If size is not provided, calc from the buffer size and type.
41  /// The input cl::Buffer is empty after this call.
43  myBuffer(buf), mySize(size)
44  {
45  if (buf())
46  {
47  if (mySize < 0)
48  mySize = buf.getInfo<CL_MEM_SIZE>() / sizeof(T);
49  UT_ASSERT(mySize * sizeof(T) == buf.getInfo<CL_MEM_SIZE>());
50  }
51  else
52  {
53  UT_ASSERT(mySize <= 0);
54  mySize = 0;
55  }
56  buf = cl::Buffer();
57  }
58 
59  /// No copy constructor.
60  CE_BufferDevice(const CE_BufferDevice<T> &b) = delete;
61 
62  // Move constructor.
64  {
65  releaseBuffer();
66  initInternal(b.size(), false);
67  myBuffer = b.myBuffer;
68  b.myBuffer = cl::Buffer();
69  b.init(0);
70  }
71 
72  ~CE_BufferDevice() { releaseBuffer(); }
73 
74  // Reinterpret this buffer as a fixed array of the given type.
75  // Note: it's unsafe to use this view after the buffer has been reallocated.
76  // The array type must be numeric. @see CE_ArrayView the supported types.
77  template <typename V>
79  {
80  if constexpr (SYS_IsSame_v<T, V>)
81  return CE_ArrayView<T>(*this);
82 
83  exint bytes = size() * sizeof(T);
84  if (bytes % sizeof(V))
85  {
86  UT_ASSERT(!"Buffer does not fit evenly into reinterpreted type. "
87  "Array view was shortened!");
88  }
89 
90  return CE_ArrayView<V>(buffer(), bytes / sizeof(V));
91  }
92 
93  template <typename V>
94  const CE_ArrayView<V> arrayView() const
95  {
96  return SYSconst_cast(this)->template arrayView<V>();
97  }
98 
99  /// Release and return the underlying buffer without deleting,
100  /// after which this object is empty (similar to unique_ptr).
102  {
103  cl::Buffer tmp = myBuffer;
104  myBuffer = cl::Buffer();
105  init(0);
106  return tmp;
107  }
108 
109  /// Reset to own the provided raw cl::Buffer.
110  /// If size is not provided, calc from the buffer size and type.
111  /// The input cl::Buffer is empty after this call.
112  void reset(cl::Buffer &&buf, exint size = -1)
113  {
114  releaseBuffer();
115  myBuffer = buf;
116  mySize = size;
117  if (buf())
118  {
119  if (mySize < 0)
120  mySize = buf.getInfo<CL_MEM_SIZE>() / sizeof(T);
121  UT_ASSERT(mySize * sizeof(T) == buf.getInfo<CL_MEM_SIZE>());
122  }
123  else
124  {
125  UT_ASSERT(mySize <= 0);
126  mySize = 0;
127  }
128  buf = cl::Buffer();
129  }
130 
131  /// Initialize to given size.
132  /// NOTE- values are undefined.
133  void init(exint size);
134 
135  /// Initialize from a UT_Array. If len >= 0, only len elements are copied.
136  void initFromArray(const UT_Array<T> &src, exint len = -1,
137  bool block = true);
138 
139  /// Resize the provided UT_Array to fit and copy this vector's data there.
140  /// If len >= 0 then only len elements are copied.
141  void matchAndCopyToArray(UT_Array<T> &dst, exint len = -1,
142  bool block = true) const;
143 
144  /// Initialize from raw data block of T elements of length nelem.
145  void initFromData(const T *data, exint nelem, bool block = true);
146 
147  /// Returns the buffer length.
148  exint size() const { return mySize; }
149 
150  /// Returns true iff there are no occupied elements in the buffer.
151  bool isEmpty() const { return mySize == 0; }
152 
153  /// Returns the underlying OpenCL buffer.
154  /// Note: This is meant for directly passing to OpenCL functions.
155  /// holding ownership over long times.
156  const cl::Buffer &buffer() const { return myBuffer; }
157 
158  /// Copy from the input buffer. If len >= 0, only len elements are copied.
159  /// NOTE: This object must already be initialized to a buffer of
160  /// sufficient size.
161  void copyFrom(const CE_BufferDevice<T> &b, exint len = -1);
162 
164  {
165  UTswap(a.myBuffer, b.myBuffer);
166  UTswap(a.mySize, b.mySize);
167  }
168 
169 private:
170 
171  void initInternal(exint size, bool doalloc=true);
172 
173  const cl::Buffer &allocBuffer() const;
174 
175  void releaseBuffer();
176 
177  mutable cl::Buffer myBuffer;
178  exint mySize;
179 };
180 
181 template <typename T>
182 SYS_FORCE_INLINE void
184 {
185  releaseBuffer();
186  mySize = size;
187  if (mySize > 0 && doalloc)
188  allocBuffer();
189 }
190 
191 // Some of these methods *MUST* be forced inline to avoid windows MSVC/clang
192 // bugs that result in linker errors about multiply-defined symbols found on
193 // Opt/Release builds.
194 template <typename T>
195 SYS_FORCE_INLINE void
197 {
198  initInternal(size, true);
199 }
200 
201 template <typename T>
202 void
204 {
205  utZoneScopedFlag(CL_MEMORY);
206  size_t size = src.size();
207  // len < 0 (the default) indicates copy the whole array.
208  UT_ASSERT(len < 0 || len <= size);
209  if (len >= 0 && len <= size)
210  size = len;
211  init(size);
212  if (!size)
213  return;
214  size_t totalsize = size * sizeof(T);
215  CE_Context *context = CE_Context::getContext();
216  context->writeBuffer(myBuffer, totalsize, src.data(), blocking);
217 }
218 
219 template <typename T>
220 void
222  bool blocking) const
223 {
224  utZoneScopedFlag(CL_MEMORY);
225  size_t size = mySize;
226  // len < 0 (the default) indicates copy the whole array.
227  UT_ASSERT(len < 0 || len <= size);
228  if (len >= 0 && len <= size)
229  size = len;
230  dst.setSizeNoInit(size);
231  if (size == 0)
232  return;
233  CE_Context *context = CE_Context::getContext();
234  size_t totalsize = size * sizeof(T);
235  context->readBuffer(myBuffer, totalsize, dst.data(), blocking);
236 }
237 
238 template <typename T>
239 void
240 CE_BufferDevice<T>::initFromData(const T *data, exint nelem, bool blocking)
241 {
242  utZoneScopedFlag(CL_MEMORY);
243  init(nelem);
244  if (!nelem)
245  return;
246  size_t totalsize = nelem * sizeof(T);
247  CE_Context *context = CE_Context::getContext();
248  context->writeBuffer(myBuffer, totalsize, data, blocking);
249 }
250 
251 template <typename T>
254 {
255  UT_ASSERT(mySize > 0);
256  CE_Context *context = CE_Context::getContext();
257  myBuffer = context->allocBuffer(mySize * sizeof(T));
258  return myBuffer;
259 }
260 
261 template <typename T>
262 SYS_FORCE_INLINE void
264 {
265  // This is a no-op for a null buffer.
266  CE_Context::getContext()->releaseBuffer(std::move(myBuffer));
267  myBuffer = cl::Buffer();
268 }
269 
270 template <typename T>
271 void
273 {
274  CE_Context *context = CE_Context::getContext();
275  size_t size = v.size();
276  // len < 0 (the default) indicates copy the whole array.
277  UT_ASSERT(len < 0 || len <= size);
278  if (len >= 0)
279  size = len;
280  // Make sure we are allocated and large enough for the copy.
281  UT_ASSERT(myBuffer() && size <= mySize);
282  size_t totalsize = size * sizeof(T);
283  context->copyBuffer(v.buffer(), myBuffer, totalsize);
284 }
285 
287 
299 
300 #endif
CE_BufferDevice(CE_BufferDevice< T > &&b) noexcept
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:719
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
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.
exint size() const
Definition: UT_Array.h:667
void init(exint size)
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 SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define utZoneScopedFlag(F)
Definition: UT_Tracing.h:215
CE_BufferDevice(cl::Buffer &&buf, exint size=-1)
const CE_ArrayView< V > arrayView() const
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:866
CE_ArrayView< V > arrayView()
Memory buffer interface.
Definition: cl.hpp:1867
CE_EXTERN_TEMPLATE(CE_BufferDevice< uint8 >)
const cl::Buffer & buffer() const
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
#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)
Definition: format.h:4365
void matchAndCopyToArray(UT_Array< T > &dst, exint len=-1, bool block=true) const
GLenum src
Definition: glcorearb.h:1793