| // |
| // Copyright (c) 2017 The Khronos Group Inc. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| #ifndef _typeWrappers_h |
| #define _typeWrappers_h |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| #if !defined(_WIN32) |
| #include <sys/mman.h> |
| #endif |
| |
| #include "compat.h" |
| #include <stdio.h> |
| #include "mt19937.h" |
| #include "errorHelpers.h" |
| #include "kernelHelpers.h" |
| |
| /* cl_context wrapper */ |
| |
| class clContextWrapper { |
| public: |
| clContextWrapper() { mContext = NULL; } |
| clContextWrapper(cl_context program) { mContext = program; } |
| ~clContextWrapper() |
| { |
| if (mContext != NULL) clReleaseContext(mContext); |
| } |
| |
| clContextWrapper &operator=(const cl_context &rhs) |
| { |
| mContext = rhs; |
| return *this; |
| } |
| operator cl_context() const { return mContext; } |
| |
| cl_context *operator&() { return &mContext; } |
| |
| bool operator==(const cl_context &rhs) { return mContext == rhs; } |
| |
| protected: |
| cl_context mContext; |
| }; |
| |
| /* cl_program wrapper */ |
| |
| class clProgramWrapper { |
| public: |
| clProgramWrapper() { mProgram = NULL; } |
| clProgramWrapper(cl_program program) { mProgram = program; } |
| ~clProgramWrapper() |
| { |
| if (mProgram != NULL) clReleaseProgram(mProgram); |
| } |
| |
| clProgramWrapper &operator=(const cl_program &rhs) |
| { |
| mProgram = rhs; |
| return *this; |
| } |
| operator cl_program() const { return mProgram; } |
| |
| cl_program *operator&() { return &mProgram; } |
| |
| bool operator==(const cl_program &rhs) { return mProgram == rhs; } |
| |
| protected: |
| cl_program mProgram; |
| }; |
| |
| /* cl_kernel wrapper */ |
| |
| class clKernelWrapper { |
| public: |
| clKernelWrapper() { mKernel = NULL; } |
| clKernelWrapper(cl_kernel kernel) { mKernel = kernel; } |
| ~clKernelWrapper() |
| { |
| if (mKernel != NULL) clReleaseKernel(mKernel); |
| } |
| |
| clKernelWrapper &operator=(const cl_kernel &rhs) |
| { |
| mKernel = rhs; |
| return *this; |
| } |
| operator cl_kernel() const { return mKernel; } |
| |
| cl_kernel *operator&() { return &mKernel; } |
| |
| bool operator==(const cl_kernel &rhs) { return mKernel == rhs; } |
| |
| protected: |
| cl_kernel mKernel; |
| }; |
| |
| /* cl_mem (stream) wrapper */ |
| |
| class clMemWrapper { |
| public: |
| clMemWrapper() { mMem = NULL; } |
| clMemWrapper(cl_mem mem) { mMem = mem; } |
| ~clMemWrapper() |
| { |
| if (mMem != NULL) clReleaseMemObject(mMem); |
| } |
| |
| clMemWrapper &operator=(const cl_mem &rhs) |
| { |
| mMem = rhs; |
| return *this; |
| } |
| operator cl_mem() const { return mMem; } |
| |
| cl_mem *operator&() { return &mMem; } |
| |
| bool operator==(const cl_mem &rhs) { return mMem == rhs; } |
| |
| protected: |
| cl_mem mMem; |
| }; |
| |
| class clProtectedImage { |
| public: |
| clProtectedImage() |
| { |
| image = NULL; |
| backingStore = NULL; |
| } |
| clProtectedImage(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width, |
| cl_int *errcode_ret); |
| clProtectedImage(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width, size_t height, |
| cl_int *errcode_ret); |
| clProtectedImage(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width, size_t height, |
| size_t depth, cl_int *errcode_ret); |
| clProtectedImage(cl_context context, cl_mem_object_type imageType, |
| cl_mem_flags flags, const cl_image_format *fmt, |
| size_t width, size_t height, size_t depth, |
| size_t arraySize, cl_int *errcode_ret); |
| ~clProtectedImage() |
| { |
| if (image != NULL) clReleaseMemObject(image); |
| |
| #if defined(__APPLE__) |
| if (backingStore) munmap(backingStore, backingStoreSize); |
| #endif |
| } |
| |
| cl_int Create(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width); |
| cl_int Create(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width, size_t height); |
| cl_int Create(cl_context context, cl_mem_flags flags, |
| const cl_image_format *fmt, size_t width, size_t height, |
| size_t depth); |
| cl_int Create(cl_context context, cl_mem_object_type imageType, |
| cl_mem_flags flags, const cl_image_format *fmt, size_t width, |
| size_t height, size_t depth, size_t arraySize); |
| |
| clProtectedImage &operator=(const cl_mem &rhs) |
| { |
| image = rhs; |
| backingStore = NULL; |
| return *this; |
| } |
| operator cl_mem() { return image; } |
| |
| cl_mem *operator&() { return ℑ } |
| |
| bool operator==(const cl_mem &rhs) { return image == rhs; } |
| |
| protected: |
| void *backingStore; |
| size_t backingStoreSize; |
| cl_mem image; |
| }; |
| |
| /* cl_command_queue wrapper */ |
| class clCommandQueueWrapper { |
| public: |
| clCommandQueueWrapper() { mMem = NULL; } |
| clCommandQueueWrapper(cl_command_queue mem) { mMem = mem; } |
| ~clCommandQueueWrapper() |
| { |
| if (mMem != NULL) |
| { |
| clReleaseCommandQueue(mMem); |
| } |
| } |
| |
| clCommandQueueWrapper &operator=(const cl_command_queue &rhs) |
| { |
| mMem = rhs; |
| return *this; |
| } |
| operator cl_command_queue() const { return mMem; } |
| |
| cl_command_queue *operator&() { return &mMem; } |
| |
| bool operator==(const cl_command_queue &rhs) { return mMem == rhs; } |
| |
| protected: |
| cl_command_queue mMem; |
| }; |
| |
| /* cl_sampler wrapper */ |
| class clSamplerWrapper { |
| public: |
| clSamplerWrapper() { mMem = NULL; } |
| clSamplerWrapper(cl_sampler mem) { mMem = mem; } |
| ~clSamplerWrapper() |
| { |
| if (mMem != NULL) clReleaseSampler(mMem); |
| } |
| |
| clSamplerWrapper &operator=(const cl_sampler &rhs) |
| { |
| mMem = rhs; |
| return *this; |
| } |
| operator cl_sampler() const { return mMem; } |
| |
| cl_sampler *operator&() { return &mMem; } |
| |
| bool operator==(const cl_sampler &rhs) { return mMem == rhs; } |
| |
| protected: |
| cl_sampler mMem; |
| }; |
| |
| /* cl_event wrapper */ |
| class clEventWrapper { |
| public: |
| clEventWrapper() { mMem = NULL; } |
| clEventWrapper(cl_event mem) { mMem = mem; } |
| ~clEventWrapper() |
| { |
| if (mMem != NULL) clReleaseEvent(mMem); |
| } |
| |
| clEventWrapper &operator=(const cl_event &rhs) |
| { |
| mMem = rhs; |
| return *this; |
| } |
| operator cl_event() const { return mMem; } |
| |
| cl_event *operator&() { return &mMem; } |
| |
| bool operator==(const cl_event &rhs) { return mMem == rhs; } |
| |
| protected: |
| cl_event mMem; |
| }; |
| |
| /* Generic protected memory buffer, for verifying access within bounds */ |
| class clProtectedArray { |
| public: |
| clProtectedArray(); |
| clProtectedArray(size_t sizeInBytes); |
| virtual ~clProtectedArray(); |
| |
| void Allocate(size_t sizeInBytes); |
| |
| operator void *() { return (void *)mValidBuffer; } |
| operator const void *() const { return (const void *)mValidBuffer; } |
| |
| protected: |
| char *mBuffer; |
| char *mValidBuffer; |
| size_t mRealSize, mRoundedSize; |
| }; |
| |
| class RandomSeed { |
| public: |
| RandomSeed(cl_uint seed) |
| { |
| if (seed) log_info("(seed = %10.10u) ", seed); |
| mtData = init_genrand(seed); |
| } |
| ~RandomSeed() |
| { |
| if (gReSeed) gRandomSeed = genrand_int32(mtData); |
| free_mtdata(mtData); |
| } |
| |
| operator MTdata() { return mtData; } |
| |
| protected: |
| MTdata mtData; |
| }; |
| |
| |
| template <typename T> class BufferOwningPtr { |
| BufferOwningPtr(BufferOwningPtr const &); // do not implement |
| void operator=(BufferOwningPtr const &); // do not implement |
| |
| void *ptr; |
| void *map; |
| // Bytes allocated total, pointed to by map: |
| size_t mapsize; |
| // Bytes allocated in unprotected pages, pointed to by ptr: |
| size_t allocsize; |
| bool aligned; |
| |
| public: |
| explicit BufferOwningPtr(void *p = 0) |
| : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false) |
| {} |
| explicit BufferOwningPtr(void *p, void *m, size_t s) |
| : ptr(p), map(m), mapsize(s), allocsize(0), aligned(false) |
| { |
| #if !defined(__APPLE__) |
| if (m) |
| { |
| log_error("ERROR: unhandled code path. BufferOwningPtr allocated " |
| "with mapped buffer!"); |
| abort(); |
| } |
| #endif |
| } |
| ~BufferOwningPtr() |
| { |
| if (map) |
| { |
| #if defined(__APPLE__) |
| int error = munmap(map, mapsize); |
| if (error) |
| log_error("WARNING: munmap failed in BufferOwningPtr.\n"); |
| #endif |
| } |
| else |
| { |
| if (aligned) |
| { |
| align_free(ptr); |
| } |
| else |
| { |
| free(ptr); |
| } |
| } |
| } |
| void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0, |
| bool aligned_ = false) |
| { |
| if (map) |
| { |
| #if defined(__APPLE__) |
| int error = munmap(map, mapsize); |
| if (error) |
| log_error("WARNING: munmap failed in BufferOwningPtr.\n"); |
| #else |
| log_error("ERROR: unhandled code path. BufferOwningPtr reset with " |
| "mapped buffer!"); |
| abort(); |
| #endif |
| } |
| else |
| { |
| if (aligned) |
| { |
| align_free(ptr); |
| } |
| else |
| { |
| free(ptr); |
| } |
| } |
| ptr = p; |
| map = m; |
| mapsize = mapsize_; |
| // Force allocsize to zero if ptr is NULL: |
| allocsize = (ptr != NULL) ? allocsize_ : 0; |
| aligned = aligned_; |
| #if !defined(__APPLE__) |
| if (m) |
| { |
| log_error("ERROR: unhandled code path. BufferOwningPtr allocated " |
| "with mapped buffer!"); |
| abort(); |
| } |
| #endif |
| } |
| operator T *() { return (T *)ptr; } |
| |
| size_t getSize() const { return allocsize; }; |
| }; |
| |
| #endif // _typeWrappers_h |