void OpenCLIntersectionDevice::IntersectionThread(OpenCLIntersectionDevice *renderDevice) { LR_LOG(renderDevice->deviceContext, "[OpenCL device::" << renderDevice->deviceName << "] Rendering thread started"); try { RayBufferQueue *queue = renderDevice->externalRayBufferQueue ? renderDevice->externalRayBufferQueue : &(renderDevice->rayBufferQueue); RayBuffer *rayBuffer0, *rayBuffer1, *rayBuffer2; const double startTime = WallClockTime(); while (!boost::this_thread::interruption_requested()) { const double t1 = WallClockTime(); queue->Pop3xToDo(&rayBuffer0, &rayBuffer1, &rayBuffer2); renderDevice->statsDeviceIdleTime += WallClockTime() - t1; const unsigned int count = (rayBuffer0 ? 1 : 0) + (rayBuffer1 ? 1 : 0) + (rayBuffer2 ? 1 : 0); switch(count) { case 1: { // Only one ray buffer to trace available VECTOR_CLASS<cl::Event> readEvent0(1); VECTOR_CLASS<cl::Event> traceEvent0(1); cl::Event event0; renderDevice->TraceRayBuffer(rayBuffer0, readEvent0, traceEvent0, &event0); event0.wait(); queue->PushDone(rayBuffer0); renderDevice->statsDeviceTotalTime = WallClockTime() - startTime; break; } case 2: { // At least 2 ray buffers to trace // Trace 0 ray buffer VECTOR_CLASS<cl::Event> readEvent0(1); VECTOR_CLASS<cl::Event> traceEvent0(1); cl::Event event0; renderDevice->TraceRayBuffer(rayBuffer0, readEvent0, traceEvent0, &event0); // Trace 1 ray buffer VECTOR_CLASS<cl::Event> readEvent1(1); VECTOR_CLASS<cl::Event> traceEvent1(1); cl::Event event1; renderDevice->TraceRayBuffer(rayBuffer1, readEvent1, traceEvent1, &event1); // Pop 0 ray buffer event0.wait(); queue->PushDone(rayBuffer0); // Pop 1 ray buffer event1.wait(); queue->PushDone(rayBuffer1); renderDevice->statsDeviceTotalTime = WallClockTime() - startTime; break; } case 3: { // At least 3 ray buffers to trace // Trace 0 ray buffer VECTOR_CLASS<cl::Event> readEvent0(1); VECTOR_CLASS<cl::Event> traceEvent0(1); cl::Event event0; renderDevice->TraceRayBuffer(rayBuffer0, readEvent0, traceEvent0, &event0); // Trace 1 ray buffer VECTOR_CLASS<cl::Event> readEvent1(1); VECTOR_CLASS<cl::Event> traceEvent1(1); cl::Event event1; renderDevice->TraceRayBuffer(rayBuffer1, readEvent1, traceEvent1, &event1); // Trace 2 ray buffer VECTOR_CLASS<cl::Event> readEvent2(1); VECTOR_CLASS<cl::Event> traceEvent2(1); cl::Event event2; renderDevice->TraceRayBuffer(rayBuffer2, readEvent2, traceEvent2, &event2); // Pop 0 ray buffer event0.wait(); queue->PushDone(rayBuffer0); // Pop 1 ray buffer event1.wait(); queue->PushDone(rayBuffer1); // Pop 2 ray buffer event2.wait(); queue->PushDone(rayBuffer2); renderDevice->statsDeviceTotalTime = WallClockTime() - startTime; break; } default: assert (false); } } LR_LOG(renderDevice->deviceContext, "[OpenCL device::" << renderDevice->deviceName << "] Rendering thread halted"); } catch (boost::thread_interrupted) { LR_LOG(renderDevice->deviceContext, "[OpenCL device::" << renderDevice->deviceName << "] Rendering thread halted"); } catch (cl::Error err) { LR_LOG(renderDevice->deviceContext, "[OpenCL device::" << renderDevice->deviceName << "] Rendering thread ERROR: " << err.what() << "(" << luxrays::utils::oclErrorString(err.err()) << ")"); } }