00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _LUXRAYS_INTERSECTIONDEVICE_H
00023 #define _LUXRAYS_INTERSECTIONDEVICE_H
00024
00025 #include "luxrays/luxrays.h"
00026 #include "luxrays/core/device.h"
00027
00028 namespace luxrays {
00029
00030 class IntersectionDevice : public Device {
00031 public:
00032 const DataSet *GetDataSet() const { return dataSet; }
00033
00034 virtual RayBuffer *NewRayBuffer() = 0;
00035 virtual void PushRayBuffer(RayBuffer *rayBuffer) = 0;
00036 virtual RayBuffer *PopRayBuffer() = 0;
00037 virtual size_t GetQueueSize() = 0;
00038
00039 double GetPerformance() const {
00040 const double statsTotalRayTime = WallClockTime() - statsStartTime;
00041 return (statsTotalRayTime == 0.0) ? 1.0 : (statsTotalRayCount / statsTotalRayTime);
00042 }
00043 virtual double GetLoad() const = 0;
00044
00045 friend class Context;
00046 friend class VirtualM2OHardwareIntersectionDevice;
00047 friend class VirtualM2MHardwareIntersectionDevice;
00048
00049 protected:
00050 IntersectionDevice(const Context *context, const DeviceType type, const unsigned int index);
00051 virtual ~IntersectionDevice();
00052
00053 virtual void SetDataSet(const DataSet *newDataSet);
00054 virtual void Start();
00055
00056 const DataSet *dataSet;
00057 double statsStartTime, statsTotalRayCount, statsDeviceIdleTime, statsDeviceTotalTime;
00058 };
00059
00060 class HardwareIntersectionDevice : public IntersectionDevice {
00061 protected:
00062 HardwareIntersectionDevice(const Context *context, const DeviceType type, const unsigned int index) :
00063 IntersectionDevice(context, type, index) { }
00064 virtual ~HardwareIntersectionDevice() { }
00065
00066 virtual void SetExternalRayBufferQueue(RayBufferQueue *queue) = 0;
00067
00068 friend class VirtualM2OHardwareIntersectionDevice;
00069 friend class VirtualM2MHardwareIntersectionDevice;
00070 };
00071
00072
00073
00074
00075
00076 class NativeThreadIntersectionDevice : public IntersectionDevice {
00077 public:
00078 NativeThreadIntersectionDevice(const Context *context, const unsigned int threadIndex,
00079 const unsigned int devIndex);
00080 ~NativeThreadIntersectionDevice();
00081
00082 void SetDataSet(const DataSet *newDataSet);
00083 void Start();
00084 void Interrupt();
00085 void Stop();
00086
00087 RayBuffer *NewRayBuffer();
00088 size_t GetQueueSize() { return 0; }
00089 void PushRayBuffer(RayBuffer *rayBuffer);
00090 RayBuffer *PopRayBuffer();
00091
00092 double GetLoad() const {
00093 return 1.0;
00094 }
00095
00096 void Intersect(RayBuffer *rayBuffer);
00097
00098 static size_t RayBufferSize;
00099
00100 friend class Context;
00101
00102 private:
00103 RayBufferSingleQueue doneRayBufferQueue;
00104 };
00105
00106
00107
00108
00109
00110 #define OPENCL_RAYBUFFER_SIZE 65536
00111
00112 #if !defined(LUXRAYS_DISABLE_OPENCL)
00113
00114 class OpenCLIntersectionDevice : public HardwareIntersectionDevice {
00115 public:
00116 OpenCLIntersectionDevice(const Context *context, OpenCLDeviceDescription *desc,
00117 const unsigned int index, const unsigned int forceWGSize);
00118 ~OpenCLIntersectionDevice();
00119
00120 void SetDataSet(const DataSet *newDataSet);
00121 void Start();
00122 void Interrupt();
00123 void Stop();
00124
00125 RayBuffer *NewRayBuffer();
00126 size_t GetQueueSize() { return rayBufferQueue.GetSizeToDo(); }
00127 void PushRayBuffer(RayBuffer *rayBuffer);
00128 RayBuffer *PopRayBuffer();
00129
00130 const OpenCLDeviceDescription *GetDeviceDesc() const { return deviceDesc; }
00131
00132 double GetLoad() const {
00133 return (statsDeviceTotalTime == 0.0) ? 0.0 : (1.0 - statsDeviceIdleTime / statsDeviceTotalTime);
00134 }
00135
00136
00137 void SetQBVHDisableImageStorage(const bool v) {
00138 qbvhDisableImageStorage = v;
00139 }
00140
00141
00142
00143
00144
00145 cl::Context &GetOpenCLContext() { return deviceDesc->GetOCLContext(); }
00146 cl::Device &GetOpenCLDevice() { return deviceDesc->GetOCLDevice(); }
00147 cl::CommandQueue &GetOpenCLQueue() { return *oclQueue; }
00148 unsigned int GetForceWorkGroupSize() const { return forceWorkGroupSize; }
00149 void EnqueueTraceRayBuffer(cl::Buffer &rBuff, cl::Buffer &hBuff, const unsigned int rayCount);
00150
00151 friend class Context;
00152
00153 static size_t RayBufferSize;
00154
00155 protected:
00156 void SetExternalRayBufferQueue(RayBufferQueue *queue);
00157 void UpdateDataSet();
00158
00159 private:
00160 static void IntersectionThread(OpenCLIntersectionDevice *renderDevice);
00161
00162 void TraceRayBuffer(RayBuffer *rayBuffer, cl::Event *event);
00163 void FreeDataSetBuffers();
00164
00165 unsigned int forceWorkGroupSize;
00166 OpenCLDeviceDescription *deviceDesc;
00167 boost::thread *intersectionThread;
00168
00169
00170 cl::CommandQueue *oclQueue;
00171
00172
00173 cl::Kernel *bvhKernel;
00174 size_t bvhWorkGroupSize;
00175 cl::Buffer *vertsBuff;
00176 cl::Buffer *trisBuff;
00177 cl::Buffer *bvhBuff;
00178
00179
00180
00181
00182 cl::Kernel *qbvhKernel;
00183 size_t qbvhWorkGroupSize;
00184 cl::Buffer *qbvhBuff;
00185 cl::Buffer *qbvhTrisBuff;
00186
00187
00188 cl::Kernel *qbvhImageKernel;
00189 size_t qbvhImageWorkGroupSize;
00190
00191 cl::Image2D *qbvhImageBuff;
00192 cl::Image2D *qbvhTrisImageBuff;
00193
00194
00195 cl::Kernel *mqbvhKernel;
00196 size_t mqbvhWorkGroupSize;
00197 cl::Buffer *mqbvhBuff;
00198 cl::Buffer *mqbvhMemMapBuff;
00199 cl::Buffer *mqbvhLeafBuff;
00200 cl::Buffer *mqbvhLeafQuadTrisBuff;
00201 cl::Buffer *mqbvhInvTransBuff;
00202 cl::Buffer *mqbvhTrisOffsetBuff;
00203
00204 cl::Buffer *raysBuff;
00205 cl::Buffer *hitsBuff;
00206
00207 RayBufferQueueO2O rayBufferQueue;
00208 RayBufferQueue *externalRayBufferQueue;
00209
00210 bool reportedPermissionError, qbvhUseImage, qbvhDisableImageStorage;
00211 };
00212
00213 #endif
00214
00215 }
00216
00217 #endif