• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #ifndef _typeWrappers_h
17 #define _typeWrappers_h
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #if !defined(_WIN32)
23 #include <sys/mman.h>
24 #endif
25 
26 #include "compat.h"
27 #include <stdio.h>
28 #include "mt19937.h"
29 #include "errorHelpers.h"
30 #include "kernelHelpers.h"
31 
32 /* cl_context wrapper */
33 
34 class clContextWrapper {
35 public:
clContextWrapper()36     clContextWrapper() { mContext = NULL; }
clContextWrapper(cl_context program)37     clContextWrapper(cl_context program) { mContext = program; }
~clContextWrapper()38     ~clContextWrapper()
39     {
40         if (mContext != NULL) clReleaseContext(mContext);
41     }
42 
43     clContextWrapper &operator=(const cl_context &rhs)
44     {
45         mContext = rhs;
46         return *this;
47     }
cl_context()48     operator cl_context() const { return mContext; }
49 
50     cl_context *operator&() { return &mContext; }
51 
52     bool operator==(const cl_context &rhs) { return mContext == rhs; }
53 
54 protected:
55     cl_context mContext;
56 };
57 
58 /* cl_program wrapper */
59 
60 class clProgramWrapper {
61 public:
clProgramWrapper()62     clProgramWrapper() { mProgram = NULL; }
clProgramWrapper(cl_program program)63     clProgramWrapper(cl_program program) { mProgram = program; }
~clProgramWrapper()64     ~clProgramWrapper()
65     {
66         if (mProgram != NULL) clReleaseProgram(mProgram);
67     }
68 
69     clProgramWrapper &operator=(const cl_program &rhs)
70     {
71         mProgram = rhs;
72         return *this;
73     }
cl_program()74     operator cl_program() const { return mProgram; }
75 
76     cl_program *operator&() { return &mProgram; }
77 
78     bool operator==(const cl_program &rhs) { return mProgram == rhs; }
79 
80 protected:
81     cl_program mProgram;
82 };
83 
84 /* cl_kernel wrapper */
85 
86 class clKernelWrapper {
87 public:
clKernelWrapper()88     clKernelWrapper() { mKernel = NULL; }
clKernelWrapper(cl_kernel kernel)89     clKernelWrapper(cl_kernel kernel) { mKernel = kernel; }
~clKernelWrapper()90     ~clKernelWrapper()
91     {
92         if (mKernel != NULL) clReleaseKernel(mKernel);
93     }
94 
95     clKernelWrapper &operator=(const cl_kernel &rhs)
96     {
97         mKernel = rhs;
98         return *this;
99     }
cl_kernel()100     operator cl_kernel() const { return mKernel; }
101 
102     cl_kernel *operator&() { return &mKernel; }
103 
104     bool operator==(const cl_kernel &rhs) { return mKernel == rhs; }
105 
106 protected:
107     cl_kernel mKernel;
108 };
109 
110 /* cl_mem (stream) wrapper */
111 
112 class clMemWrapper {
113 public:
clMemWrapper()114     clMemWrapper() { mMem = NULL; }
clMemWrapper(cl_mem mem)115     clMemWrapper(cl_mem mem) { mMem = mem; }
~clMemWrapper()116     ~clMemWrapper()
117     {
118         if (mMem != NULL) clReleaseMemObject(mMem);
119     }
120 
121     clMemWrapper &operator=(const cl_mem &rhs)
122     {
123         mMem = rhs;
124         return *this;
125     }
cl_mem()126     operator cl_mem() const { return mMem; }
127 
128     cl_mem *operator&() { return &mMem; }
129 
130     bool operator==(const cl_mem &rhs) { return mMem == rhs; }
131 
132 protected:
133     cl_mem mMem;
134 };
135 
136 class clProtectedImage {
137 public:
clProtectedImage()138     clProtectedImage()
139     {
140         image = NULL;
141         backingStore = NULL;
142     }
143     clProtectedImage(cl_context context, cl_mem_flags flags,
144                      const cl_image_format *fmt, size_t width,
145                      cl_int *errcode_ret);
146     clProtectedImage(cl_context context, cl_mem_flags flags,
147                      const cl_image_format *fmt, size_t width, size_t height,
148                      cl_int *errcode_ret);
149     clProtectedImage(cl_context context, cl_mem_flags flags,
150                      const cl_image_format *fmt, size_t width, size_t height,
151                      size_t depth, cl_int *errcode_ret);
152     clProtectedImage(cl_context context, cl_mem_object_type imageType,
153                      cl_mem_flags flags, const cl_image_format *fmt,
154                      size_t width, size_t height, size_t depth,
155                      size_t arraySize, cl_int *errcode_ret);
~clProtectedImage()156     ~clProtectedImage()
157     {
158         if (image != NULL) clReleaseMemObject(image);
159 
160 #if defined(__APPLE__)
161         if (backingStore) munmap(backingStore, backingStoreSize);
162 #endif
163     }
164 
165     cl_int Create(cl_context context, cl_mem_flags flags,
166                   const cl_image_format *fmt, size_t width);
167     cl_int Create(cl_context context, cl_mem_flags flags,
168                   const cl_image_format *fmt, size_t width, size_t height);
169     cl_int Create(cl_context context, cl_mem_flags flags,
170                   const cl_image_format *fmt, size_t width, size_t height,
171                   size_t depth);
172     cl_int Create(cl_context context, cl_mem_object_type imageType,
173                   cl_mem_flags flags, const cl_image_format *fmt, size_t width,
174                   size_t height, size_t depth, size_t arraySize);
175 
176     clProtectedImage &operator=(const cl_mem &rhs)
177     {
178         image = rhs;
179         backingStore = NULL;
180         return *this;
181     }
cl_mem()182     operator cl_mem() { return image; }
183 
184     cl_mem *operator&() { return &image; }
185 
186     bool operator==(const cl_mem &rhs) { return image == rhs; }
187 
188 protected:
189     void *backingStore;
190     size_t backingStoreSize;
191     cl_mem image;
192 };
193 
194 /* cl_command_queue wrapper */
195 class clCommandQueueWrapper {
196 public:
clCommandQueueWrapper()197     clCommandQueueWrapper() { mMem = NULL; }
clCommandQueueWrapper(cl_command_queue mem)198     clCommandQueueWrapper(cl_command_queue mem) { mMem = mem; }
~clCommandQueueWrapper()199     ~clCommandQueueWrapper()
200     {
201         if (mMem != NULL)
202         {
203             clReleaseCommandQueue(mMem);
204         }
205     }
206 
207     clCommandQueueWrapper &operator=(const cl_command_queue &rhs)
208     {
209         mMem = rhs;
210         return *this;
211     }
cl_command_queue()212     operator cl_command_queue() const { return mMem; }
213 
214     cl_command_queue *operator&() { return &mMem; }
215 
216     bool operator==(const cl_command_queue &rhs) { return mMem == rhs; }
217 
218 protected:
219     cl_command_queue mMem;
220 };
221 
222 /* cl_sampler wrapper */
223 class clSamplerWrapper {
224 public:
clSamplerWrapper()225     clSamplerWrapper() { mMem = NULL; }
clSamplerWrapper(cl_sampler mem)226     clSamplerWrapper(cl_sampler mem) { mMem = mem; }
~clSamplerWrapper()227     ~clSamplerWrapper()
228     {
229         if (mMem != NULL) clReleaseSampler(mMem);
230     }
231 
232     clSamplerWrapper &operator=(const cl_sampler &rhs)
233     {
234         mMem = rhs;
235         return *this;
236     }
cl_sampler()237     operator cl_sampler() const { return mMem; }
238 
239     cl_sampler *operator&() { return &mMem; }
240 
241     bool operator==(const cl_sampler &rhs) { return mMem == rhs; }
242 
243 protected:
244     cl_sampler mMem;
245 };
246 
247 /* cl_event wrapper */
248 class clEventWrapper {
249 public:
clEventWrapper()250     clEventWrapper() { mMem = NULL; }
clEventWrapper(cl_event mem)251     clEventWrapper(cl_event mem) { mMem = mem; }
~clEventWrapper()252     ~clEventWrapper()
253     {
254         if (mMem != NULL) clReleaseEvent(mMem);
255     }
256 
257     clEventWrapper &operator=(const cl_event &rhs)
258     {
259         mMem = rhs;
260         return *this;
261     }
cl_event()262     operator cl_event() const { return mMem; }
263 
264     cl_event *operator&() { return &mMem; }
265 
266     bool operator==(const cl_event &rhs) { return mMem == rhs; }
267 
268 protected:
269     cl_event mMem;
270 };
271 
272 /* Generic protected memory buffer, for verifying access within bounds */
273 class clProtectedArray {
274 public:
275     clProtectedArray();
276     clProtectedArray(size_t sizeInBytes);
277     virtual ~clProtectedArray();
278 
279     void Allocate(size_t sizeInBytes);
280 
281     operator void *() { return (void *)mValidBuffer; }
282     operator const void *() const { return (const void *)mValidBuffer; }
283 
284 protected:
285     char *mBuffer;
286     char *mValidBuffer;
287     size_t mRealSize, mRoundedSize;
288 };
289 
290 class RandomSeed {
291 public:
RandomSeed(cl_uint seed)292     RandomSeed(cl_uint seed)
293     {
294         if (seed) log_info("(seed = %10.10u) ", seed);
295         mtData = init_genrand(seed);
296     }
~RandomSeed()297     ~RandomSeed()
298     {
299         if (gReSeed) gRandomSeed = genrand_int32(mtData);
300         free_mtdata(mtData);
301     }
302 
MTdata()303     operator MTdata() { return mtData; }
304 
305 protected:
306     MTdata mtData;
307 };
308 
309 
310 template <typename T> class BufferOwningPtr {
311     BufferOwningPtr(BufferOwningPtr const &); // do not implement
312     void operator=(BufferOwningPtr const &); // do not implement
313 
314     void *ptr;
315     void *map;
316     // Bytes allocated total, pointed to by map:
317     size_t mapsize;
318     // Bytes allocated in unprotected pages, pointed to by ptr:
319     size_t allocsize;
320     bool aligned;
321 
322 public:
323     explicit BufferOwningPtr(void *p = 0)
ptr(p)324         : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false)
325     {}
BufferOwningPtr(void * p,void * m,size_t s)326     explicit BufferOwningPtr(void *p, void *m, size_t s)
327         : ptr(p), map(m), mapsize(s), allocsize(0), aligned(false)
328     {
329 #if !defined(__APPLE__)
330         if (m)
331         {
332             log_error("ERROR: unhandled code path. BufferOwningPtr allocated "
333                       "with mapped buffer!");
334             abort();
335         }
336 #endif
337     }
~BufferOwningPtr()338     ~BufferOwningPtr()
339     {
340         if (map)
341         {
342 #if defined(__APPLE__)
343             int error = munmap(map, mapsize);
344             if (error)
345                 log_error("WARNING: munmap failed in BufferOwningPtr.\n");
346 #endif
347         }
348         else
349         {
350             if (aligned)
351             {
352                 align_free(ptr);
353             }
354             else
355             {
356                 free(ptr);
357             }
358         }
359     }
360     void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0,
361                bool aligned_ = false)
362     {
363         if (map)
364         {
365 #if defined(__APPLE__)
366             int error = munmap(map, mapsize);
367             if (error)
368                 log_error("WARNING: munmap failed in BufferOwningPtr.\n");
369 #else
370             log_error("ERROR: unhandled code path. BufferOwningPtr reset with "
371                       "mapped buffer!");
372             abort();
373 #endif
374         }
375         else
376         {
377             if (aligned)
378             {
379                 align_free(ptr);
380             }
381             else
382             {
383                 free(ptr);
384             }
385         }
386         ptr = p;
387         map = m;
388         mapsize = mapsize_;
389         // Force allocsize to zero if ptr is NULL:
390         allocsize = (ptr != NULL) ? allocsize_ : 0;
391         aligned = aligned_;
392 #if !defined(__APPLE__)
393         if (m)
394         {
395             log_error("ERROR: unhandled code path. BufferOwningPtr allocated "
396                       "with mapped buffer!");
397             abort();
398         }
399 #endif
400     }
401     operator T *() { return (T *)ptr; }
402 
getSize()403     size_t getSize() const { return allocsize; };
404 };
405 
406 #endif // _typeWrappers_h
407