/** Pure DB rendering when each node compose result from its pipes and transmit only one set of images to the destination node. */ static void _modeDB( Config* config, const unsigned nChannels, const unsigned nPipes ) { Compound* compound = config->getCompounds()[0]; vector<float> ranges( nChannels + 1, 0 ); ranges[ nChannels ] = 1.0; for( unsigned i = 1; i < nChannels; ++i ) ranges[ i ] = ranges[ i-1 ] + 1.0/nChannels; unsigned i = 0; // for each node for( unsigned n = 0 ; n < nChannels/nPipes; ++n ) { Compound* childNode = compound; if( n != 0 ) // don't create separate compound for dst channel { childNode = new Compound( compound ); std::ostringstream channelName; channelName << "channel" << n*nPipes; Channel* childChannel = config->find< Channel >( channelName.str()); childNode->setChannel( childChannel ); } // for each gpu on the node for( unsigned p = 0; p < nPipes; ++p ) { Compound* childPipe = new Compound( childNode ); childPipe->setRange( eq::Range( ranges[ i ], ranges[ i+1 ] )); if( i != n*nPipes ) { std::ostringstream channelName; channelName << "channel" << i; Channel* childChannel = config->find< Channel >( channelName.str( )); childPipe->setChannel( childChannel ); std::ostringstream frameName; frameName << "frame.channel" << i; childPipe->addOutputFrame( ::Frame::create( frameName )); childNode->addInputFrame( ::Frame::create( frameName )); } i++; } if( n != 0 ) // dst channel has no output { std::ostringstream frameName; frameName << "frame.channel" << n*nPipes; childNode->addOutputFrame( ::Frame::create( frameName )); compound->addInputFrame( ::Frame::create( frameName )); } } }
/** 2D decomposition based on precalculated grid */ static void _mode2D( Config* config, const vector<float>& xMarks, const vector<float>& yMarks ) { Compound* compound = config->getCompounds()[0]; const size_t rows = yMarks.size() - 1; const size_t columns = xMarks.size() - 1; size_t i = 0; for( size_t y = 0; y < rows; ++y ) for( size_t x = 0; x < columns; ++x ) { Compound* child = new Compound( compound ); std::ostringstream channelName; channelName << "channel" << i; Channel* childChannel = config->find< Channel >( channelName.str( )); child->setChannel( childChannel ); child->setViewport( eq::Viewport( xMarks[x ], yMarks[y ], xMarks[x+1]-xMarks[x], yMarks[y+1]-yMarks[y] )); if( i != 0 ) { std::ostringstream frameName; frameName << "frame.channel" << i; child->addOutputFrame( ::Frame::create( frameName )); compound->addInputFrame( ::Frame::create( frameName )); } i++; } }
/** DB_ds rendering when each node compose result from its pipes on to first pipe, then result is used in DB_ds compositing between nodes */ static void _modeDS( Config* config, const unsigned nChannels, const unsigned nPipes, const vector< vector<int> >& descr, const vector<float>& xMarks, const vector<float>& yMarks ) { Compound* compound = config->getCompounds()[0]; vector<float> ranges( nChannels + 1, 0 ); ranges[ nChannels ] = 1.0; for( unsigned i = 1; i < nChannels; ++i ) ranges[ i ] = ranges[ i-1 ] + 1.0/nChannels; const unsigned nNodes = nChannels/nPipes; if( descr.size() < nNodes ) { cerr << "Description file is incomplete" << std::endl; return; } const int rows = int( yMarks.size( )) - 1; const int columns = int( xMarks.size( )) - 1; const int cells = rows*columns; // check that all specified viewports are within a grid for( size_t i = 0; i < nNodes; ++i ) { const vector< int >& vals = descr[i]; for( size_t j = 0; j < vals.size(); ++j ) if( vals[j] >= cells || vals[j] < 0 ) { cerr << "description of region is invalid: " << vals[j] << " no such cell" << std::endl; return; } } // fill all viewports for grid vector< eq::Viewport > tmpVP; for( int y = 0; y < rows; ++y ) for( int x = 0; x < columns; ++x ) tmpVP.push_back( eq::Viewport( xMarks[x], yMarks[y], xMarks[x+1]-xMarks[x], yMarks[y+1]-yMarks[y] )); // build per-node viewports vector< eq::Viewport > vp( nNodes ); for( size_t i = 0; i < nNodes; ++i ) { const vector< int >& vals = descr[i]; vp[i] = tmpVP[vals[0]]; for( size_t j = 1; j < vals.size(); ++j ) vp[i].unite( tmpVP[vals[j]] ); } unsigned i = 0; // for each node for( unsigned n = 0 ; n < nNodes; ++n ) { Compound* child = compound; if( n != 0 ) // don't create separate compound for dst channel { child = new Compound( compound ); std::ostringstream channelName; channelName << "channel" << n*nPipes; Channel* childChannel = config->find< Channel >( channelName.str()); child->setChannel( childChannel ); } Compound* childNode = new Compound( child ); // for each gpu on the node for( unsigned p = 0; p < nPipes; ++p ) { Compound* childPipe = new Compound( childNode ); childPipe->setRange( eq::Range( ranges[ i ], ranges[ i+1 ] )); if( i != n*nPipes ) { std::ostringstream channelName; channelName << "channel" << i; Channel* childChannel = config->find< Channel >( channelName.str( )); childPipe->setChannel( childChannel ); std::ostringstream frameName; frameName << "frame.channel" << i; childPipe->addOutputFrame( ::Frame::create( frameName )); childNode->addInputFrame( ::Frame::create( frameName )); } i++; } for( unsigned k = 0; k < nNodes; ++k ) if( k != n ) { // output parts to compose on other nodes std::ostringstream frameName; frameName << "fr" << k*nPipes << ".ch" << n*nPipes; childNode->addOutputFrame( ::Frame::create( frameName, vp[k] )); // input parts from other nodes to compose on current node frameName.str(""); frameName<< "fr" << n*nPipes << ".ch" << k*nPipes; child->addInputFrame( ::Frame::create( frameName )); } // output color result for final compositing on the first node if( n != 0 ) { std::ostringstream frameName; frameName << "frame.channel" << n*nPipes; child->addOutputFrame( ::Frame::create( frameName, vp[n], true )); compound->addInputFrame( ::Frame::create( frameName )); } } }