void renderSync(const RenderParams& renderParams, PipeFilter& sendHistogramFilter, Renderer& renderer, NodeAvailability& availability) const { PipeFilterT<VisibleSetGeneratorFilter> visibleSetGenerator( "VisibleSetGenerator", _dataSource); setupVisibleGeneratorFilter(visibleSetGenerator, renderParams); visibleSetGenerator.execute(); const livre::UniqueFutureMap portFutures( visibleSetGenerator.getPostconditions()); const auto& nodeIds = renderer.order(portFutures.get<NodeIds>("VisibleNodes"), renderParams.frameInfo.frustum); const VolumeInformation& volInfo = _dataSource.getVolumeInfo(); const size_t blockMemSize = volInfo.maximumBlockSize.product() * volInfo.getBytesPerVoxel() * volInfo.compCount; const uint32_t maxNodesPerPass = renderParams.vrParams.getMaxGpuCacheMemory() * LB_1MB / blockMemSize; const uint32_t numberOfPasses = std::ceil((float)nodeIds.size() / (float)maxNodesPerPass); std::unique_ptr<boost::progress_display> showProgress; if (numberOfPasses > 1) { LBINFO << "Multipass rendering. Number of passes: " << numberOfPasses << std::endl; showProgress.reset(new boost::progress_display(numberOfPasses)); } sendHistogramFilter.getPromise("RelativeViewport") .set(renderParams.viewport); sendHistogramFilter.getPromise("Id").set( renderParams.frameInfo.frameId); for (uint32_t i = 0; i < numberOfPasses; ++i) { uint32_t renderStages = RENDER_FRAME; if (i == 0) renderStages |= RENDER_BEGIN; if (i == numberOfPasses - 1u) renderStages |= RENDER_END; const uint32_t startIndex = i * maxNodesPerPass; const uint32_t endIndex = (i + 1) * maxNodesPerPass; const NodeIds nodesPerPass(nodeIds.begin() + startIndex, endIndex > nodeIds.size() ? nodeIds.end() : nodeIds.begin() + endIndex); createAndExecuteSyncPass(nodesPerPass, renderParams, sendHistogramFilter, renderer, renderStages); if (numberOfPasses > 1) ++(*showProgress); } const UniqueFutureMap futures(visibleSetGenerator.getPostconditions()); availability.nAvailable = futures.get<NodeIds>("VisibleNodes").size(); availability.nNotAvailable = 0; }
void renderSync( RenderStatistics& statistics, Renderer& renderer, const RenderInputs& renderInputs ) { tuyau::PipeFilter sendHistogramFilter = renderInputs.filters.find( "SendHistogramFilter" )->second; tuyau::PipeFilter preRenderFilter = renderInputs.filters.find( "PreRenderFilter" )->second; tuyau::PipeFilterT< VisibleSetGeneratorFilter > visibleSetGenerator( "VisibleSetGenerator", renderInputs.dataSource ); setupVisibleGeneratorFilter( visibleSetGenerator, renderInputs ); visibleSetGenerator.connect( "VisibleNodes", preRenderFilter, "VisibleNodes" ); preRenderFilter.getPromise( "Frustum" ).set( renderInputs.frameInfo.frustum ); visibleSetGenerator.execute(); preRenderFilter.execute(); const tuyau::UniqueFutureMap portFutures( visibleSetGenerator.getPostconditions( )); NodeIds nodeIdsCopy = portFutures.get< NodeIds >( "VisibleNodes" ); DistanceOperator distanceOp( renderInputs.dataSource, renderInputs.frameInfo.frustum ); std::sort( nodeIdsCopy.begin(), nodeIdsCopy.end(), distanceOp ); const uint32_t maxNodesPerPass = texturePool->getTextureMem() / texturePool->getSlotMemSize(); const uint32_t numberOfPasses = std::ceil( (float)nodeIdsCopy.size() / (float)maxNodesPerPass ); std::unique_ptr< boost::progress_display > showProgress; if( numberOfPasses > 1 ) { LBINFO << "Multipass rendering. Number of passes: " << numberOfPasses << std::endl; showProgress.reset( new boost::progress_display( numberOfPasses )); } for( uint32_t i = 0; i < numberOfPasses; ++i ) { uint32_t renderStages = RENDER_FRAME; if( i == 0 ) renderStages |= RENDER_BEGIN; if( i == numberOfPasses - 1u ) renderStages |= RENDER_END; const uint32_t startIndex = i * maxNodesPerPass; const uint32_t endIndex = ( i + 1 ) * maxNodesPerPass; const NodeIds nodesPerPass( nodeIdsCopy.begin() + startIndex, endIndex > nodeIdsCopy.size() ? nodeIdsCopy.end() : nodeIdsCopy.begin() + endIndex ); createAndExecuteSyncPass( nodesPerPass, renderInputs, renderer, renderStages ); if( numberOfPasses > 1 ) ++(*showProgress); } tuyau::PipeFilterT< HistogramFilter > histogramFilter( "HistogramFilter", *histogramCache, *dataCache, renderInputs.dataSource ); histogramFilter.getPromise( "NodeIds" ).set( nodeIdsCopy ); sendHistogramFilter.getPromise( "RelativeViewport" ).set( renderInputs.viewport ); sendHistogramFilter.getPromise( "Id" ).set( renderInputs.frameInfo.frameId ); histogramFilter.getPromise( "Frustum" ).set( renderInputs.frameInfo.frustum ); histogramFilter.connect( "Histogram", sendHistogramFilter, "Histogram" ); histogramFilter.getPromise( "RelativeViewport" ).set( renderInputs.viewport ); histogramFilter.getPromise( "DataSourceRange" ).set( renderInputs.dataSourceRange ); histogramFilter.schedule( _computeExecutor ); sendHistogramFilter.schedule( _computeExecutor ); const tuyau::UniqueFutureMap futures( visibleSetGenerator.getPostconditions( )); statistics.nAvailable = futures.get< NodeIds >( "VisibleNodes" ).size(); statistics.nNotAvailable = 0; statistics.nRenderAvailable = statistics.nAvailable; }