00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _LUXRAYS_DEVICE_H
00023 #define _LUXRAYS_DEVICE_H
00024
00025 #include <string>
00026 #include <cstdlib>
00027
00028 #include <boost/thread/thread.hpp>
00029
00030 #include "luxrays/luxrays.h"
00031 #include "luxrays/core/utils.h"
00032 #include "luxrays/core/dataset.h"
00033 #include "luxrays/core/context.h"
00034
00035 namespace luxrays {
00036
00037 typedef enum {
00038 DEVICE_TYPE_ALL, DEVICE_TYPE_OPENCL, DEVICE_TYPE_NATIVE_THREAD, DEVICE_TYPE_VIRTUAL
00039 } DeviceType;
00040
00041 class DeviceDescription {
00042 public:
00043 DeviceDescription() { }
00044 DeviceDescription(const std::string deviceName, const DeviceType deviceType) :
00045 name(deviceName), type(deviceType) { }
00046
00047 const std::string &GetName() const { return name; }
00048 const DeviceType GetType() const { return type; };
00049
00050 static void FilterOne(std::vector<DeviceDescription *> &deviceDescriptions);
00051 static void Filter(DeviceType type, std::vector<DeviceDescription *> &deviceDescriptions);
00052 static std::string GetDeviceType(const DeviceType type);
00053
00054 protected:
00055 std::string name;
00056 DeviceType type;
00057 };
00058
00059 class Device {
00060 public:
00061 const std::string &GetName() const { return deviceName; }
00062 const Context *GetContext() const { return deviceContext; }
00063 const DeviceType GetType() const { return deviceType; }
00064
00065 virtual bool IsRunning() const { return started; };
00066
00067 friend class Context;
00068 friend class VirtualM2OHardwareIntersectionDevice;
00069 friend class VirtualM2MHardwareIntersectionDevice;
00070
00071 protected:
00072 Device(const Context *context, const DeviceType type, const unsigned int index);
00073 virtual ~Device();
00074
00075 virtual void Start();
00076 virtual void Interrupt() = 0;
00077 virtual void Stop();
00078
00079 const Context *deviceContext;
00080 DeviceType deviceType;
00081 unsigned int deviceIndex;
00082
00083 std::string deviceName;
00084
00085 bool started;
00086 };
00087
00088
00089
00090
00091
00092 class NativeThreadDeviceDescription : public DeviceDescription {
00093 public:
00094 NativeThreadDeviceDescription(const std::string deviceName, const unsigned int threadIdx) :
00095 DeviceDescription(deviceName, DEVICE_TYPE_NATIVE_THREAD), threadIndex(threadIdx) { }
00096
00097 size_t GetThreadIndex() const { return threadIndex; };
00098
00099 friend class Context;
00100
00101 protected:
00102 static void AddDeviceDescs(std::vector<DeviceDescription *> &descriptions);
00103
00104 size_t threadIndex;
00105 };
00106
00107
00108
00109
00110
00111 #if !defined(LUXRAYS_DISABLE_OPENCL)
00112
00113 class OpenCLIntersectionDevice;
00114
00115 typedef enum {
00116 OCL_DEVICE_TYPE_ALL, OCL_DEVICE_TYPE_DEFAULT, OCL_DEVICE_TYPE_CPU,
00117 OCL_DEVICE_TYPE_GPU, OCL_DEVICE_TYPE_UNKNOWN
00118 } OpenCLDeviceType;
00119
00120 class OpenCLDeviceDescription : public DeviceDescription {
00121 public:
00122 OpenCLDeviceDescription(cl::Device &device, const size_t devIndex) :
00123 DeviceDescription(device.getInfo<CL_DEVICE_NAME>().c_str(), DEVICE_TYPE_OPENCL),
00124 oclType(GetOCLDeviceType(device.getInfo<CL_DEVICE_TYPE>())),
00125 deviceIndex(devIndex),
00126 computeUnits(device.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>()),
00127 maxMemory(device.getInfo<CL_DEVICE_GLOBAL_MEM_SIZE>()),
00128 usedMemory(0),
00129 forceWorkGroupSize(0),
00130 oclDevice(device),
00131 oclContext(NULL),
00132 enableOpenGLInterop(false) { }
00133
00134 ~OpenCLDeviceDescription() {
00135 delete oclContext;
00136 }
00137
00138 OpenCLDeviceType GetOpenCLType() const { return oclType; }
00139 size_t GetDeviceIndex() const { return deviceIndex; }
00140 int GetComputeUnits() const { return computeUnits; }
00141 size_t GetMaxMemory() const { return maxMemory; }
00142 size_t GetUsedMemory() const { return usedMemory; }
00143 void AllocMemory(size_t s) const { usedMemory += s; }
00144 void FreeMemory(size_t s) const { usedMemory -= s; }
00145 unsigned int GetForceWorkGroupSize() const { return forceWorkGroupSize; }
00146
00147 bool HasImageSupport() const { return oclDevice.getInfo<CL_DEVICE_IMAGE_SUPPORT>(); }
00148 size_t GetImage2DMaxWidth() const { return oclDevice.getInfo<CL_DEVICE_IMAGE2D_MAX_WIDTH>(); }
00149 size_t GetImage2DMaxHeight() const { return oclDevice.getInfo<CL_DEVICE_IMAGE2D_MAX_HEIGHT>(); }
00150
00151 void SetForceWorkGroupSize(const unsigned int size) const { forceWorkGroupSize = size; }
00152
00153 bool HasOCLContext() const { return (oclContext != NULL); }
00154 bool HasOGLInterop() const { return enableOpenGLInterop; }
00155 void EnableOGLInterop() const {
00156 if (!oclContext || enableOpenGLInterop)
00157 enableOpenGLInterop = true;
00158 else
00159 throw std::runtime_error("It is not possible to enable OpenGL interoperability when the OpenCL context has laready been created");
00160 }
00161
00162 cl::Context &GetOCLContext() const;
00163 cl::Device &GetOCLDevice() const { return oclDevice; }
00164
00165 static void Filter(const OpenCLDeviceType type, std::vector<DeviceDescription *> &deviceDescriptions);
00166
00167 friend class Context;
00168 friend class OpenCLIntersectionDevice;
00169 friend class OpenCLPixelDevice;
00170 friend class OpenCLSampleBuffer;
00171
00172 protected:
00173 static std::string GetDeviceType(const cl_int type);
00174 static std::string GetDeviceType(const OpenCLDeviceType type);
00175 static OpenCLDeviceType GetOCLDeviceType(const cl_int type);
00176 static void AddDeviceDescs(const cl::Platform &oclPlatform, const OpenCLDeviceType filter,
00177 std::vector<DeviceDescription *> &descriptions);
00178
00179 OpenCLDeviceType oclType;
00180 size_t deviceIndex;
00181 int computeUnits;
00182 size_t maxMemory;
00183 mutable size_t usedMemory;
00184
00185
00186
00187 mutable unsigned int forceWorkGroupSize;
00188
00189 private:
00190 mutable cl::Device oclDevice;
00191 mutable cl::Context *oclContext;
00192 mutable bool enableOpenGLInterop;
00193 };
00194
00195 #endif
00196
00197 }
00198
00199 #endif