00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cstdio>
00023
00024 #include "luxrays/core/device.h"
00025 #include "luxrays/core/virtualdevice.h"
00026
00027 using namespace luxrays;
00028
00029
00030
00031
00032
00033 size_t VirtualM2OHardwareIntersectionDevice::RayBufferSize = OPENCL_RAYBUFFER_SIZE;
00034
00035 VirtualM2OHardwareIntersectionDevice::VirtualM2OHardwareIntersectionDevice(const size_t count,
00036 HardwareIntersectionDevice *device) {
00037 virtualDeviceCount = count;
00038 realDevice = device;
00039 realDevice->SetExternalRayBufferQueue(&rayBufferQueue);
00040
00041 virtualDeviceInstances = new VirtualM2ODevHInstance *[virtualDeviceCount];
00042 for (size_t i = 0; i < virtualDeviceCount; ++i)
00043 virtualDeviceInstances[i] = new VirtualM2ODevHInstance(this, i);
00044 }
00045
00046 VirtualM2OHardwareIntersectionDevice::~VirtualM2OHardwareIntersectionDevice() {
00047 for (size_t i = 0; i < virtualDeviceCount; ++i)
00048 delete virtualDeviceInstances[i];
00049 delete virtualDeviceInstances;
00050 }
00051
00052 IntersectionDevice *VirtualM2OHardwareIntersectionDevice::GetVirtualDevice(size_t index) {
00053 return virtualDeviceInstances[index];
00054 }
00055
00056
00057
00058
00059
00060 VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::VirtualM2ODevHInstance(
00061 VirtualM2OHardwareIntersectionDevice *device, const size_t index) :
00062 IntersectionDevice(device->realDevice->GetContext(), DEVICE_TYPE_VIRTUAL, index) {
00063 char buf[256];
00064 sprintf(buf, "VirtualM2OHDevice-%03d-%s", (int)index, device->realDevice->GetName().c_str());
00065 deviceName = std::string(buf);
00066
00067 instanceIndex = index;
00068 virtualDevice = device;
00069 }
00070
00071 VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::~VirtualM2ODevHInstance() {
00072 if (started)
00073 Stop();
00074 }
00075
00076 void VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::SetDataSet(const DataSet *newDataSet) {
00077 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00078 IntersectionDevice::SetDataSet(newDataSet);
00079
00080
00081 if (virtualDevice->realDevice->GetDataSet() != newDataSet)
00082 virtualDevice->realDevice->SetDataSet(newDataSet);
00083 }
00084
00085 void VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::Start() {
00086 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00087
00088 IntersectionDevice::Start();
00089 pendingRayBuffers = 0;
00090
00091
00092 if (!virtualDevice->realDevice->IsRunning()) {
00093 LR_LOG(deviceContext, "[VirtualM2ODevice::" << deviceName << "] Starting real device");
00094 virtualDevice->realDevice->Start();
00095 }
00096 }
00097
00098 void VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::Interrupt() {
00099 }
00100
00101 void VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::Stop() {
00102 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00103
00104
00105 while (pendingRayBuffers > 0)
00106 PopRayBuffer();
00107
00108
00109 bool lastOne = true;
00110 for (size_t i = 0; i < virtualDevice->virtualDeviceCount; ++i) {
00111 if ((i != instanceIndex) && (virtualDevice->virtualDeviceInstances[i]->IsRunning())) {
00112 lastOne = false;
00113 break;
00114 }
00115 }
00116
00117 if (lastOne) {
00118 LR_LOG(deviceContext, "[VirtualM2ODevice::" << deviceName << "] Stopping real device");
00119 virtualDevice->realDevice->Stop();
00120 }
00121
00122 IntersectionDevice::Stop();
00123 }
00124
00125 RayBuffer *VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::NewRayBuffer() {
00126 return new RayBuffer(RayBufferSize);
00127 }
00128
00129 void VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::PushRayBuffer(RayBuffer *rayBuffer) {
00130 virtualDevice->rayBufferQueue.PushToDo(rayBuffer, instanceIndex);
00131 ++pendingRayBuffers;
00132 }
00133
00134 RayBuffer *VirtualM2OHardwareIntersectionDevice::VirtualM2ODevHInstance::PopRayBuffer() {
00135 RayBuffer *rayBuffer = virtualDevice->rayBufferQueue.PopDone(instanceIndex);
00136 --pendingRayBuffers;
00137
00138 statsTotalRayCount += rayBuffer->GetRayCount();
00139
00140 return rayBuffer;
00141 }
00142
00143
00144
00145
00146
00147 size_t VirtualM2MHardwareIntersectionDevice::RayBufferSize = OPENCL_RAYBUFFER_SIZE;
00148
00149 VirtualM2MHardwareIntersectionDevice::VirtualM2MHardwareIntersectionDevice(const size_t count,
00150 const std::vector<HardwareIntersectionDevice *> &devices) : rayBufferQueue(count) {
00151 assert (count > 0);
00152 assert (devices.size() > 0);
00153
00154
00155 realDevices = devices;
00156 for (size_t i = 0; i < realDevices.size(); ++i)
00157 realDevices[i]->SetExternalRayBufferQueue(&rayBufferQueue);
00158
00159 virtualDeviceCount = count;
00160 virtualDeviceInstances = new VirtualM2MDevHInstance *[virtualDeviceCount];
00161 for (size_t i = 0; i < virtualDeviceCount; ++i)
00162 virtualDeviceInstances[i] = new VirtualM2MDevHInstance(this, i);
00163 }
00164
00165 VirtualM2MHardwareIntersectionDevice::~VirtualM2MHardwareIntersectionDevice() {
00166 for (size_t i = 0; i < virtualDeviceCount; ++i)
00167 delete virtualDeviceInstances[i];
00168 delete virtualDeviceInstances;
00169 }
00170
00171 IntersectionDevice *VirtualM2MHardwareIntersectionDevice::GetVirtualDevice(size_t index) {
00172 return virtualDeviceInstances[index];
00173 }
00174
00175
00176
00177
00178
00179 VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::VirtualM2MDevHInstance(
00180 VirtualM2MHardwareIntersectionDevice *device, const size_t index) :
00181 IntersectionDevice(device->realDevices[0]->GetContext(), DEVICE_TYPE_VIRTUAL, index) {
00182 char buf[256];
00183 sprintf(buf, "VirtualM2MHDevice-%03d", (int)index);
00184 deviceName = std::string(buf);
00185
00186 instanceIndex = index;
00187 virtualDevice = device;
00188 }
00189
00190 VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::~VirtualM2MDevHInstance() {
00191 if (started)
00192 Stop();
00193 }
00194
00195 void VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::SetDataSet(const DataSet *newDataSet) {
00196 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00197 IntersectionDevice::SetDataSet(newDataSet);
00198
00199
00200 for (size_t i = 0; i < virtualDevice->realDevices.size(); ++i) {
00201 if (virtualDevice->realDevices[i]->GetDataSet() != newDataSet)
00202 virtualDevice->realDevices[i]->SetDataSet(newDataSet);
00203 }
00204 }
00205
00206 void VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::Start() {
00207 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00208
00209 IntersectionDevice::Start();
00210 pendingRayBuffers = 0;
00211
00212
00213 for (size_t i = 0; i < virtualDevice->realDevices.size(); ++i) {
00214 if (!virtualDevice->realDevices[i]->IsRunning()) {
00215 LR_LOG(deviceContext, "[VirtualM2MHDevice::" << deviceName << "] Starting real device: " << i);
00216 virtualDevice->realDevices[i]->Start();
00217 }
00218 }
00219
00220 }
00221
00222 void VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::Interrupt() {
00223 }
00224
00225 void VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::Stop() {
00226 boost::mutex::scoped_lock lock(virtualDevice->virtualDeviceMutex);
00227
00228
00229 while (pendingRayBuffers > 0)
00230 PopRayBuffer();
00231
00232
00233 bool lastOne = true;
00234 for (size_t i = 0; i < virtualDevice->virtualDeviceCount; ++i) {
00235 if ((i != instanceIndex) && (virtualDevice->virtualDeviceInstances[i]->IsRunning())) {
00236 lastOne = false;
00237 break;
00238 }
00239 }
00240
00241 if (lastOne) {
00242 for (size_t i = 0; i < virtualDevice->realDevices.size(); ++i) {
00243 LR_LOG(deviceContext, "[VirtualM2ODevice::" << deviceName << "] Stopping real device: " << i);
00244 virtualDevice->realDevices[i]->Stop();
00245 }
00246 }
00247
00248 IntersectionDevice::Stop();
00249 }
00250
00251 RayBuffer *VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::NewRayBuffer() {
00252 return new RayBuffer(RayBufferSize);
00253 }
00254
00255 void VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::PushRayBuffer(RayBuffer *rayBuffer) {
00256 virtualDevice->rayBufferQueue.PushToDo(rayBuffer, instanceIndex);
00257 ++pendingRayBuffers;
00258 }
00259
00260 RayBuffer *VirtualM2MHardwareIntersectionDevice::VirtualM2MDevHInstance::PopRayBuffer() {
00261 RayBuffer *rayBuffer = virtualDevice->rayBufferQueue.PopDone(instanceIndex);
00262 --pendingRayBuffers;
00263
00264 statsTotalRayCount += rayBuffer->GetRayCount();
00265
00266 return rayBuffer;
00267 }