HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CE_Context.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_Context.h ( CE Library, C++)
7  *
8  * COMMENTS: Compute Engine Contexts.
9  */
10 
11 #ifndef __CE_Context__
12 #define __CE_Context__
13 
14 #include "CE_API.h"
15 
16 #ifdef CE_ENABLED
17 
18 #include <SYS/SYS_Types.h>
19 
20 #include <UT/UT_StringMap.h>
21 #include <UT/UT_Map.h>
22 #include <UT/UT_Error.h>
23 #include <UT/UT_Array.h>
24 
25 class CE_MemoryPool;
26 
27 typedef void (*CE_ErrorCB)(const char *errmsg, UT_ErrorSeverity severity,
28  void *data);
29 
31 {
32 public:
35 
36  virtual void rebindOGLBuffer( uint buf_obj ) = 0;
37  virtual void unbindOGLBuffer() = 0;
38  virtual bool isBinded() = 0;
39 };
40 
41 /// CE_Context encapsulates the OpenCL context and provides various convenience
42 /// functions for loading kernel programs and allocating GPU memory.
44 {
45 public:
46  CE_Context();
47  virtual ~CE_Context();
48 
49  /// Returns a pointer to the singleton CE_Context object. This function
50  /// attempts to initialize OpenCL if it has not yet been.
51  /// gl_shared should be true if the context will be expected to interoperate
52  /// with the OpenGL context. If both gl_shared and shared_fallback are true,
53  /// then the function will try to make an unshared context in case the
54  /// shared context fails to create.
55  static CE_Context *getContext(bool gl_shared = true,
56  bool shared_fallback = true);
57  /// Returns true if interoperability between CL and GL is possible.
58  static bool isGLSharingPossible();
59 
60  /// Returns the underlying cl::Context object.
61  cl::Context getCLContext() const {return myContext;}
62 
63  /// Returns the cl::Queue object that is used to enqueue OpenCL kernels
64  /// and memory transfers.
65  cl::CommandQueue getQueue() const {return myQueue;}
66 
67  /// Returns the OpenCL Device object.
68  cl::Device getDevice() const {return myDevice;}
69 
70  // Write OpenCL Device info to the supplied buffer.
71  static void getInfo(const cl::Device &device, UT_WorkBuffer &buffer );
72  static void getExtendedInfo(const cl::Device &device, UT_WorkBuffer &buffer );
73 
74  // Write info for all available OpenCL platforms to the supplied buffer.
75  static void getAllPlatformsInfo(UT_WorkBuffer &buffer);
76 
77  /// Get the suggested global and local ranges for the given 1-D kernel over
78  /// the specified number of items.
79  void get1DRanges(const cl::Kernel &k, size_t items,
81 
82  /// Loads the OpenCL program specified by progname. This functions searches
83  /// for the file in the HOUDINI_OCL_PATH environment variable. Any compile-
84  /// time options can be passed in the options parameter. If the program
85  /// load succeeds, the progname will be cached, using the progrname and
86  /// options strings together as a hash value lookup. In this way the same
87  /// OpenCL program can be loaded several times with different compile-time
88  /// flags.
89  cl::Program loadProgram(const char *progname, const char *options = NULL,
90  bool recompile = false);
91  cl::Program compileProgram(const char *progtext, const char *options = NULL,
92  bool recompile = false);
93 
94  /// Create an OpenCL kernel named kernelname from the program specified by
95  /// progname. For some types of devices these kernels will be cached, as
96  /// kernels can be expensive to create. This is the recommended method
97  /// for creating kernels.
98  cl::Kernel loadKernel(const cl::Program &prog, const UT_StringRef &kernelname);
99  cl::Kernel loadKernel(const char *progname, const UT_StringRef &kernelname,
100  const char *options = NULL)
101  { return loadKernel(loadProgram(progname, options), kernelname); }
102 
103  /// Returns whether the CE_Context has been successfully initialized.
104  bool isValid() const {return myIsValid;}
105 
106  /// Returns whether the singleton CE_Context has been initialized yet. This
107  /// can be used to test whether OpenCL has been initialized without calling
108  /// getContext and forcing an attempt at initialization.
109  static bool isInitialized(bool gl_shared=false);
110 
111  /// Returns true if the OpenCL device is running on the CPU.
112  bool isCPU() const;
113 
114  /// Returns true if the OpenCL device supports double precision.
115  bool hasDoubleSupport() const {return mySupportsDouble;}
116 
117  /// Block until any outstanding kernel or memory transfers on the main
118  /// CommandQueue have executed. If sweepPool is true, the context's
119  /// CE_MemoryPool will sweep for any buffers that were in use when their
120  /// CE_Grid's went out of scope, but that were still active in kernels.
121  void finish(bool sweepPool=true);
122 
123  /// Allocate a buffer of specified size on the CE_Device.
124  /// usePool= true, attempts to use the underlying CE_MemoryPool to possibly return
125  /// an already allocated, unused buffer.
126  /// read=true, creates a buffer that is readable inside kernels.
127  /// write=true, creates a buffer that is writable inside kernels.
128  /// ogl_bind, specifies an OGL buffer to bind to.
129  cl::Buffer allocBuffer(int64 size, bool usePool=true, bool read=true, bool write=true, uint32 ogl_bind=SYS_UINT32_MAX);
130 
131  /// Release the specified buffer, possibly to the CE_MemoryPool.
132  void releaseBuffer(cl::Buffer &&buf);
133 
134  /// Keep a map buffer to bind at render time
135  /// The first time a CL::Buffer is created it can be registered to rebing to a OGL vertex buffer at drawing time.
136  /// The uint returned by the register call can be attached to a detail attribute and the drawing code can convert
137  /// the CL Buffer to a CL BufferGL.
138  uint32 registerDelayedOGLBindBuffer(CE_DelayedOGLBindBuffer* buffer);
139  void unregisterDelayedOGLBindBuffer(uint32 id);
140  CE_DelayedOGLBindBuffer* lookupDelayedOGLBindBuffer( uint id );
141 
142  /// Clear the CE_MemoryPool object.
143  void clearMemoryPool();
144 
145  /// Return a pointer to pinned (page-locked) host memory. On some devices
146  /// (Nvidia), using this type of memory for the PCI/E host/device transfers
147  /// can double the throughput. Will return NULL if the memory can't be
148  /// allocated, or if the device is not a GPU.
149  fpreal32 *getPinnedBuffer(int64 size);
150 
151  cl::Buffer getXNoiseData();
152 
153  /// Standard error reporting for OpenCL exceptions. They should generally
154  /// take the form:
155  /// @code
156  /// try
157  /// {
158  /// OpenCL calls...
159  /// }
160  /// catch(cl::Error &err)
161  /// {
162  /// CE_Context::reportError(err);
163  /// ///cleanup
164  /// }
165  /// @endcode
166  /// This will not capture delayed errors, however. Instead
167  /// you will need to add a callback to intercept them.
168  static void reportError(const cl::Error &err);
169  static void outputErrorMessage(const char *errMsg);
170  static void setErrorCB(CE_ErrorCB callback, void *data);
171  static void outputWarningMessage(const char *errMsg);
172 
173  static void initMainSharedGLContext( int devicetype, void* context, void* display );
174  static bool useHalfNormalDelayedBindBuffer();
175 
176  /// Marks that an operation has run out of memory, allowing us
177  /// to report elsewhere.
178  void setOutOfMemoryFailure(bool hasfailed = true) { myOutOfMemoryFailure = true; }
179  bool hasOutOfMemoryFailureHappened() const { return myOutOfMemoryFailure; }
180 
181  /// This structure holds a device name, vendor, and device number with respect to
182  /// its vendor platform.
184  {
188  int number;
189  };
190  /// Get the vector of available devices of the given type.
191  static void getDevices(UT_Array<DeviceDescriptor>&, cl_device_type t);
192 
193  /// Get an index to the preferred/default device for the specified device
194  /// type and the list of available devices.
195  static int getDefaultDevice(
197 
198  /// Returns true if environment variables are set that override preferences.
199  static bool isEnvironmentOverride();
200 
201  // Queries the device by calling clGetDeviceInfo, but returning false and setting
202  // result to zero for unknown flags or flags that are disabled with environment
203  // variables.
204  template <class T>
205  static bool getDeviceInfoRestricted(cl_device_id device, cl_uint flag, T &result);
206 
207  /// Queries the current device give the specified flag using clGetDeviceInfo,
208  /// used by ocldeviceinfo EXPR function. Returns false for unrecognized flag.
209  bool getDeviceInfo(const char *flag, fpreal &result);
210 
211 protected:
212  cl::Program *doCompileProgram(const char *progtext, const char *options);
213 
214  /// Initialize the context for the given device.
215  void init(cl::Context &context, cl::Device &device);
216 
217  /// Releases the pinned, page-locked memory buffer.
218  void releasePinnedBuffer();
219 
220 
225  bool myIsValid;
228 
229  struct KernelInfo
230  {
233  };
234 
237 
239 
240  // The pinned buffer is unique to the main thread.
243 
245 
247 
248  static void* theGLContext;
249  static void* theGLDisplay;
250  static int theGLDeviceType;
251 };
252 
253 #endif
254 #endif
255 
#define CE_API
Definition: CE_API.h:10
struct _cl_device_id * cl_device_id
Definition: cl.h:42
bool myIsValid
Definition: CE_Context.h:225
GLsizeiptr size
Definition: glew.h:1681
cl::Device getDevice() const
Returns the OpenCL Device object.
Definition: CE_Context.h:68
Unsorted map container.
Definition: UT_Map.h:83
bool myOutOfMemoryFailure
Definition: CE_Context.h:244
GLenum severity
Definition: glew.h:2579
cl::Kernel loadKernel(const char *progname, const UT_StringRef &kernelname, const char *options=NULL)
Definition: CE_Context.h:99
UT_ErrorSeverity
Definition: UT_Error.h:25
GLdouble l
Definition: glew.h:9122
virtual ~CE_DelayedOGLBindBuffer()
Definition: CE_Context.h:34
float fpreal32
Definition: SYS_Types.h:200
void read(T &in, bool &v)
Definition: ImfXdr.h:611
cl::CommandQueue getQueue() const
Definition: CE_Context.h:65
fpreal32 * myPinnedData
Definition: CE_Context.h:242
cl::CommandQueue myQueue
Definition: CE_Context.h:222
bool isValid() const
Returns whether the CE_Context has been successfully initialized.
Definition: CE_Context.h:104
UT_Map< uint32, CE_DelayedOGLBindBuffer * > myDelayedOGLBindBuffers
Definition: CE_Context.h:246
cl_bitfield cl_device_type
Definition: cl.h:53
GLuint buffer
Definition: glew.h:1680
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
cl::CommandQueue myDeviceQueue
Definition: CE_Context.h:223
CE_MemoryPool * myMemPool
Definition: CE_Context.h:238
void
Definition: png.h:1083
long long int64
Definition: SYS_Types.h:116
cl::Device myDevice
Definition: CE_Context.h:224
static void * theGLDisplay
Definition: CE_Context.h:249
void setOutOfMemoryFailure(bool hasfailed=true)
Definition: CE_Context.h:178
#define SYS_UINT32_MAX
Definition: SYS_Types.h:172
cl::Context myContext
Definition: CE_Context.h:221
CommandQueue interface for cl_command_queue.
Definition: cl.hpp:2842
static void * theGLContext
Definition: CE_Context.h:248
cl_int getInfo(Func f, cl_uint name, T *param)
Definition: cl.hpp:1028
fpreal64 fpreal
Definition: SYS_Types.h:277
bool mySupportsDouble
Definition: CE_Context.h:226
unsigned int uint32
Definition: SYS_Types.h:40
Memory buffer interface.
Definition: cl.hpp:1865
cl::Buffer myXNoiseData
Definition: CE_Context.h:227
NDRange interface.
Definition: cl.hpp:2458
GLuint64EXT * result
Definition: glew.h:14007
UT_StringHolder name
Definition: CE_Context.h:231
void(* CE_ErrorCB)(const char *errmsg, UT_ErrorSeverity severity, void *data)
Definition: CE_Context.h:27
Kernel interface that implements cl_kernel.
Definition: cl.hpp:2536
cl::Context getCLContext() const
Returns the underlying cl::Context object.
Definition: CE_Context.h:61
static int theGLDeviceType
Definition: CE_Context.h:250
UT_Map< const _cl_program *, UT_Array< KernelInfo > * > myKernelTable
Definition: CE_Context.h:236
Device interface for cl_device_id.
Definition: cl.hpp:1263
bool hasDoubleSupport() const
Returns true if the OpenCL device supports double precision.
Definition: CE_Context.h:115
void write(T &out, bool v)
Definition: ImfXdr.h:332
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2580
Program interface that implements cl_program.
Definition: cl.hpp:2641
bool hasOutOfMemoryFailureHappened() const
Definition: CE_Context.h:179
unsigned int uint
Definition: SYS_Types.h:45
cl::Kernel * kernel
Definition: CE_Context.h:232
GLdouble GLdouble t
Definition: glew.h:1398
cl::Buffer myPinnedBuffer
Definition: CE_Context.h:241
UT_StringMap< cl::Program * > myProgramTable
Definition: CE_Context.h:235
GLboolean GLboolean g
Definition: glew.h:9477