Changeset 299

Show
Ignore:
Timestamp:
10/16/06 09:11:30 (2 years ago)
Author:
dirk
Message:

Fixed mem leak (State regenerated)
Adaptive bucket sort (buggy, disabled)
public stats

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.cpp

    r291 r299  
    9191    "percentage of successful tests for occlusion"); 
    9292 
     93 
     94bool      OcclusionCullingTreeBuilder::_isOccStateCreated = false; 
     95StatePtr  OcclusionCullingTreeBuilder::_testingStatePtr; 
     96State    *OcclusionCullingTreeBuilder::_testingState; 
     97 
    9398// Some typedefs to clean up OpenGL extension handling 
    9499 
     
    121126       
    122127    _buckets.clear(); 
    123     _buckets.resize(_nBuckets); 
     128    _buckets.resize(_nBuckets);    
     129    _bucketsWork.clear(); 
     130    _bucketsWork.resize(_nBuckets);    
    124131} 
    125132 
    126133OcclusionCullingTreeBuilder::~OcclusionCullingTreeBuilder(void) 
    127134{ 
     135    // Should delete queries here, but those need GL context... 
     136    delete [] _testSamples; 
    128137} 
    129138 
     
    136145    _buckets.clear(); 
    137146    _buckets.resize(_nBuckets); 
     147    _bucketsWork.clear(); 
     148    _bucketsWork.resize(_nBuckets); 
     149    
     150    _bucketLow   = 0.f; 
     151    _bucketHigh  = 0.f; 
     152    _bucketScale = 0.f; 
    138153} 
    139154 
     
    176191        GenQueryT genquer = (GenQueryT)win->getFunction(_funcGenQueriesARB); 
    177192        genquer(uNumNodes, _testSamples); 
    178          
     193        _isOccSetup = true; 
     194    } 
     195     
     196    if(!_isOccStateCreated) 
     197    { 
     198        _isOccStateCreated = true; 
    179199        // Create an empty state to render test nodes. 
    180200        _testingStatePtr = State::create(); 
     
    630650    } 
    631651     
     652    // Assumed to be between 0 and 1 for fixed bucket sort. Adaptive doesn't 
     653    // care. 
     654    float val = pNode->getScalar(); 
     655     
    632656    if(_pRoot == NULL) 
    633657    { 
    634658        _pRoot = _pNodePool->create(); 
    635     } 
    636  
    637 #if 1 // Bucket sorting 
    638  
    639     float val = pNode->getScalar(); // Assumed to be between 0 and 1 
     659        _bucketLow = val; 
     660        _bucketHigh = val + 0.1; 
     661        _bucketScale = (_nBuckets + 1) / (_bucketHigh - _bucketLow); 
     662    } 
     663 
     664#if 0 // Adaptive Bucket sorting 
     665  
     666    int index = static_cast<int>((val - _bucketLow) * _bucketScale); 
     667     
     668    // Do we need to rescale buckets? 
     669    if(index < 0 || index >= _nBuckets) 
     670    { 
     671        Real32 newLow  = osgMin(val, _bucketLow); 
     672        Real32 newHigh = osgMax(val, _bucketHigh); 
     673        Real32 newScale = (_nBuckets + 1) / (newHigh - newLow); 
     674         
     675        // Only want to scale in exponential steps to reduce number 
     676        // of rescales 
     677        Real32 rescale = _bucketScale / newScale; 
     678        UInt32 step = osgnextpower2(static_cast<int>(osgceil(rescale))); 
     679         
     680        newScale = _bucketScale / step; 
     681        Real32 d = (_nBuckets - 1) / newScale - (_bucketHigh - _bucketLow); 
     682        newLow = newLow - d / 2.f; 
     683        newHigh = newLow + (_nBuckets - 1) / newScale; 
     684         
     685        // Move bucket contents around 
     686        Real32 iter = _bucketLow; 
     687        Real32 istep = 1.f / _bucketScale; 
     688         
     689        for(UInt32 i = 0; i < _nBuckets; ++i, iter += istep) 
     690        { 
     691            if(_buckets[i] == NULL) 
     692                continue; 
     693                 
     694            int index = static_cast<int>((iter - newLow) * newScale); 
     695             
     696            if(_bucketsWork[index] == NULL) 
     697            { 
     698                _bucketsWork[index] = _buckets[i]; 
     699            } 
     700            else // Need to merge 
     701            { 
     702                _bucketsWork[index]->addChild(_buckets[i]); 
     703            } 
     704            _buckets[i] = NULL; 
     705        } 
     706         
     707        // Now swap the data 
     708        _buckets.swap(_bucketsWork); 
     709         
     710        _bucketLow   = newLow; 
     711        _bucketHigh  = newHigh; 
     712        _bucketScale = newScale; 
     713         
     714        index = static_cast<int>((val - _bucketLow) * _bucketScale); 
     715    } 
     716     
     717    if(_buckets[index] == NULL) // First node in bucket 
     718    { 
     719        _pRoot->addChild(pNode); 
     720        _buckets[index] = pNode; 
     721    } 
     722    else 
     723    { 
     724        _buckets[index]->addChild(pNode); 
     725    } 
     726    uNumNodes++; 
     727 
     728 
     729#elif 1 // Bucket sorting 
     730 
    640731    int index = osgClamp(0, static_cast<int>(val * _nBuckets), _nBuckets - 1); 
    641732     
  • branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/OSGOcclusionCullingTreeBuilder.h

    r291 r299  
    8181    
    8282    static OcclusionCullingTreeBuilder Proto; 
     83 
     84    static StatElemDesc<StatIntElem>  statNOccNodes; 
     85    static StatElemDesc<StatIntElem>  statNOccTests; 
     86    static StatElemDesc<StatIntElem>  statNOccInvisible; 
     87    static StatElemDesc<StatRealElem> statNOccSuccessTestPer; 
    8388     
    8489    //----------------------------------------------------------------------- 
     
    188193    static UInt32 _funcEndQueryARB; 
    189194 
    190     static StatElemDesc<StatIntElem> statNOccNodes; 
    191     static StatElemDesc<StatIntElem> statNOccTests; 
    192     static StatElemDesc<StatIntElem> statNOccInvisible; 
    193     static StatElemDesc<StatRealElem> statNOccSuccessTestPer; 
     195    static bool                    _isOccStateCreated; 
     196    static StatePtr                _testingStatePtr; 
     197    static State                  *_testingState; 
    194198 
    195199    GLuint* _testSamples; 
     
    200204    static const int _nBuckets = 1000;     //!< number of buckets for approximate sorting 
    201205    std::vector<RenderTreeNode*> _buckets; //!< buckets for approximate sorting 
     206    std::vector<RenderTreeNode*> _bucketsWork; //!< work copy of buckets 
     207    Real32 _bucketLow;                     //!< value for lowest bucket 
     208    Real32 _bucketHigh;                    //!< value for highest bucket 
     209    Real32 _bucketScale;                   //!< 1 / all buckets width 
     210     
    202211    std::vector<RenderTreeNode*> _testNodes; //!< Nodes currently being tested 
    203212 
     
    209218    Int32                   _vpWidth; 
    210219    Int32                   _vpHeight; 
    211     StatePtr                _testingStatePtr; 
    212     State                  *_testingState; 
    213220    RenderTraversalAction  *_rt; 
    214221    UInt32                 _minFeatureSize; 
  • branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/build.info

    r280 r299  
    77   osg_dep_libs = ['OSGBase','OSGSystem','OSGGroup','OSGState','OSGDrawable', 'OSGWindow'] 
    88 
     9   # This is only need in test, but I don't know how to add opt libs to test 
     10   nvperfsdk_option = opts.GetOption("NVPerfSDK") 
     11    
     12   for option in [nvperfsdk_option]: 
     13      if option.isAvailable(): 
     14         libs.append(option.library) 
     15         if option.incDir: 
     16            cpppath.append(option.incDir) 
     17         if option.libDir: 
     18            libpath.append(option.libDir) 
     19    
    920   # Tests' dependencies 
    1021 
    1122   osg_test_libs =  ['OSGGroup', 'OSGDrawable', 'OSGState', 'OSGFileIO',  
    1223                     'OSGWindowX', 'OSGUtil','OSGText', 'OSGWindowGLUT'] 
     24    
    1325   test_cpppath = [] 
    1426   test_libpath = [] 
  • branches/Dirk_RenderTraversalWork/Source/System/Action/RenderTraversal/testOcclusionCulling.cpp

    r290 r299  
    22#include <OSGGLUT.h> 
    33#include <OSGConfig.h> 
     4#include <OSGConfigured.h> 
    45#include <OSGSimpleGeometry.h> 
    56#include <OSGGLUTWindow.h> 
     
    1819#include "OSGSHLChunk.h" 
    1920 
     21#include "OSGStatStringElem.h" 
     22#include "OSGSimplePool.h" 
     23#include "OSGRenderTreeNode.h" 
     24#include "OSGOcclusionCullingTreeBuilder.h" 
    2025 
    2126OSG_USING_NAMESPACE 
     27 
     28#ifdef OSG_WITH_NVPERFSDK 
     29#include <NVPerfSDK.h> 
     30 
     31 
     32StatElemDesc<StatStringElem> GPUIdleStat("GPUIdle","GPUIdle"); 
     33StatElemDesc<StatStringElem> PSBusyStat("PSBusyStat","PSBusyStat"); 
     34StatElemDesc<StatStringElem> VSBusyStat("VSBusyStat","VSBusyStat"); 
     35StatElemDesc<StatStringElem> TextureWaitStat("TextureWait","TextureWait"); 
     36 
     37StatElemDesc<StatStringElem> *nvStatElems[] =  
     38    { &GPUIdleStat, &PSBusyStat, &VSBusyStat, &TextureWaitStat }; 
     39 
     40#endif 
    2241 
    2342SimpleSceneManager    *mgr; 
    2443RenderTraversalAction *tact = NULL; 
    2544RenderAction          *act = NULL; 
     45RenderAction          *debugact = NULL; 
    2646 
    2747GLUTWindowPtr mainwin; 
     
    2949int mainwinid = -1, debugwinid = -1; 
    3050 
     51SimpleStatisticsForegroundPtr statfg; 
    3152StatCollector         *collector; 
    3253 
     
    3455bool debug = false; 
    3556bool bGLFinish = false; 
     57 
     58 
     59 
     60#ifdef OSG_WITH_NVPERFSDK 
     61const GLuint counterEntryCount = 10; 
     62const GLuint bufferEntryCount = 10; 
     63 
     64// A simple class to manage counters, sampling, and display of the information 
     65class NVDataProvider 
     66{ 
     67    public: 
     68        NVDataProvider() 
     69            { 
     70                // We're averaging these, so we'll need to initialize to zero 
     71                for (GLuint i = 0; i < counterEntryCount; i++) { 
     72                    for (GLuint j = 0; j < bufferEntryCount; j++) { 
     73                        m_counterValues[i][j] = 0.0f; 
     74                    } 
     75                } 
     76                m_counterIndexArrayCount = 0; 
     77                m_counterValuesRRIndex = 0; 
     78            } 
     79         
     80        virtual size_t nCounters() const 
     81            { 
     82                return m_counterIndexArrayCount; 
     83            } 
     84 
     85        virtual bool add(GLuint counterIndex) 
     86            { 
     87                if (NVPMAddCounter(counterIndex) == NVPM_OK) { 
     88                    m_counterIndexArray[m_counterIndexArrayCount++] = counterIndex; 
     89                    return true; 
     90                } else { 
     91                    return false; 
     92                } 
     93            } 
     94             
     95        virtual bool add(char *counterName) 
     96            { 
     97                GLuint counterIndex; 
     98                if (NVPMGetCounterIndex(counterName, &counterIndex) == NVPM_OK) { 
     99                    return add(counterIndex); 
     100                } else { 
     101                    return false; 
     102                } 
     103            } 
     104 
     105        virtual bool removeAllCounters() 
     106            { 
     107                NVPMRemoveAllCounters(); 
     108 
     109                while (m_counterIndexArrayCount) { 
     110                    m_counterIndexArray[--m_counterIndexArrayCount] = 0; 
     111                } 
     112                 
     113                return true; 
     114            } 
     115 
     116        virtual bool sample() 
     117            { 
     118                GLuint counterIndex, unused; 
     119                UINT64 events, cycles; 
     120 
     121                // Sample the GPU counters 
     122                NVPMSample(NULL, &unused); 
     123 
     124                // Retrieve the current sample values 
     125                for (counterIndex = 0; 
     126                     counterIndex < m_counterIndexArrayCount; 
     127                     counterIndex++)  
     128                { 
     129                    NVPMGetCounterValue(m_counterIndexArray[counterIndex], 0, &events, &cycles); 
     130                     
     131                    m_counterValues[counterIndex][m_counterValuesRRIndex] = 
     132                        100.0f * (float) events / (float) cycles; 
     133                } 
     134                m_counterValuesRRIndex++; 
     135                if (m_counterValuesRRIndex >= bufferEntryCount) { 
     136                    m_counterValuesRRIndex = 0; 
     137                } 
     138                 
     139                return true; 
     140            } 
     141             
     142        virtual float value(const GLuint counterIndex) const 
     143            { 
     144                GLuint entryIndex; 
     145                GLfloat runningTotal = 0.0f; 
     146                for (entryIndex = 0; entryIndex < bufferEntryCount; entryIndex++) { 
     147                    runningTotal +=  
     148                        m_counterValues[counterIndex][entryIndex] / (float)bufferEntryCount; 
     149                } 
     150                return runningTotal; 
     151            } 
     152 
     153    protected: 
     154        GLuint m_counterIndexArray[counterEntryCount]; 
     155        GLuint m_counterIndexArrayCount; 
     156 
     157        // Maintain a round-robin style buffer and display the average of the 
     158        // the last bufferEntryCount samples. 
     159        GLfloat m_counterValues[counterEntryCount][bufferEntryCount]; 
     160        GLuint  m_counterValuesRRIndex; 
     161 
     162} g_nvDataProvider;     
     163 
     164NVDataProvider *nvDataProvider = &g_nvDataProvider; 
     165#endif 
    36166 
    37167// redraw the window 
     
    40170    if(glutGetWindow() == mainwinid) 
    41171    { 
     172#ifdef OSG_WITH_NVPERFSDK 
     173        if(nvDataProvider->nCounters()) 
     174        { 
     175            nvDataProvider->sample(); 
     176 
     177            Char8 str[40]; 
     178             
     179            for(int i = 0; i < 4; ++i) 
     180            { 
     181                sprintf(str, "%s: %f", nvStatElems[i]->getDescription().str(), 
     182                         nvDataProvider->value(i));  
     183                StatStringElem *e = dynamic_cast<StatStringElem*>( 
     184                                        collector->getElem(*nvStatElems[i]));   
     185                e->set(str); 
     186            } 
     187        } 
     188#endif 
    42189        mgr->redraw(); 
    43190    } 
    44191    else if(glutGetWindow() == debugwinid) 
    45192    { 
    46         // Use RenderAction to prevent new oicclusion culling on debug output 
    47         debugwin->render(act); 
     193        // Use RenderAction to prevent new occlusion culling on debug output 
     194        debugwin->render(debugact); 
     195    } 
     196
     197 
     198// Redisplay both windows, if active 
     199void redisplay(void) 
     200
     201    glutSetWindow(mainwinid); 
     202    glutPostRedisplay(); 
     203    if(debugwinid > 0) 
     204    { 
     205        glutSetWindow(debugwinid); 
     206        glutPostRedisplay(); 
    48207    } 
    49208} 
     
    72231        mgr->mouseButtonPress(button, x, y); 
    73232 
    74     glutSetWindow(mainwinid); 
    75     glutPostRedisplay(); 
    76     if(debugwinid > 0) 
    77     { 
    78         glutSetWindow(debugwinid); 
    79         glutPostRedisplay(); 
    80     } 
     233    redisplay(); 
    81234} 
    82235 
     
    86239    mgr->mouseMove(x, y); 
    87240 
    88     glutSetWindow(mainwinid); 
    89     glutPostRedisplay(); 
    90     if(debugwinid > 0) 
    91     { 
    92         glutSetWindow(debugwinid); 
    93         glutPostRedisplay(); 
    94     } 
     241    redisplay(); 
    95242} 
    96243 
     
    111258        case 27:     
    112259        { 
     260#ifdef OSG_WITH_NVPERFSDK 
     261            NVPMShutdown(); 
     262#endif 
    113263            osgExit(); 
    114264            exit(0); 
     
    175325            act->setUseGLFinish(bGLFinish); 
    176326            break; 
    177     } 
    178  
    179     glutSetWindow(mainwinid); 
    180     glutPostRedisplay(); 
    181     if(debugwinid > 0) 
    182     { 
    183         glutSetWindow(debugwinid); 
    184         glutPostRedisplay(); 
    185     } 
     327 
     328 
     329        case 'y': 
     330        { 
     331            Real32 cov = tact->getOcclusionCullingCoveredThreshold(); 
     332            cov+=0.1; 
     333            tact->setOcclusionCullingCoveredThreshold(cov); 
     334            std::cout << "Covered Threshold now: " << cov << std::endl; 
     335        } 
     336        break; 
     337             
     338        case 'h': 
     339        { 
     340            Real32 cov1 = tact->getOcclusionCullingCoveredThreshold(); 
     341            cov1-=0.1; 
     342            tact->setOcclusionCullingCoveredThreshold(cov1); 
     343            std::cout << "Covered Threshold now: " << cov1 << std::endl; 
     344        } 
     345            break; 
     346 
     347        case 'u': 
     348        { 
     349            UInt32 small = tact->getOcclusionCullingMinimumFeatureSize(); 
     350            small+=1; 
     351            tact->setOcclusionCullingMinimumFeatureSize(small); 
     352            std::cout << "Minimum Feature Size now: " << small << std::endl; 
     353        } 
     354        break; 
     355             
     356        case 'j': 
     357        { 
     358            UInt32 small1 = tact->getOcclusionCullingMinimumFeatureSize(); 
     359            small1-=1; 
     360            tact->setOcclusionCullingMinimumFeatureSize(small1); 
     361            std::cout << "Minimum Feature Size now: " << small1 << std::endl; 
     362        } 
     363        break; 
     364         
     365        case 'i': 
     366        { 
     367            UInt32 visT = tact->getOcclusionCullingVisibilityThreshold(); 
     368            visT+=1; 
     369            tact->setOcclusionCullingVisibilityThreshold(visT); 
     370            std::cout << "Visibility Threshold now: " << visT << std::endl; 
     371        } 
     372        break; 
     373 
     374        case 'k': 
     375        { 
     376            UInt32 visTa = tact->getOcclusionCullingVisibilityThreshold(); 
     377            visTa-=1; 
     378            tact->setOcclusionCullingVisibilityThreshold(visTa); 
     379            std::cout << "Visibility Threshold now: " << visTa << std::endl; 
     380        } 
     381        break; 
     382         
     383        case 'f': 
     384        { 
     385            std::cout << "Freeze Occlusion result" << std::endl; 
     386             
     387            //initElements(); 
     388            mgr->setUseTraversalAction(false); 
     389             
     390            // Render stuff that is visible and tested 
     391            mgr->getWindow()->getPort(0)->setTravMask(0x5); 
     392        } 
     393        break; 
     394         
     395        case 'F': 
     396        { 
     397            std::cout << "Unfreeze Occlusion result" << std::endl; 
     398             
     399            //initElements(); 
     400            mgr->setUseTraversalAction(true); 
     401             
     402            mgr->getWindow()->getPort(0)->setTravMask(0xffffffff); 
     403        } 
     404        break; 
     405 
     406    } 
     407 
     408    redisplay(); 
    186409} 
    187410 
     
    265488    mgr->setUseTraversalAction(true); 
    266489 
    267     tact = RenderTraversalAction::create(); 
    268     act  = RenderAction::create(); 
     490    tact      = RenderTraversalAction::create(); 
     491    act       = RenderAction::create(); 
     492    debugact  = RenderAction::create(); 
    269493 
    270494 
     
    316540    // add the statistics forground 
    317541     
    318     SimpleStatisticsForegroundPtr statfg =  
    319         SimpleStatisticsForeground::create(); 
     542    statfg = SimpleStatisticsForeground::create(); 
    320543     
    321544    statfg->setSize(25); 
    322545    statfg->setColor(Color4f(0,1,0,0.7)); 
    323 #if 0 
    324     statfg->addElement(RenderAction::statDrawTime, "Draw FPS: %r.3f"); 
    325     statfg->addElement(DrawActionBase::statTravTime, "TravTime: %.3f s"); 
    326     statfg->addElement(RenderAction::statDrawTime, "DrawTime: %.3f s"); 
    327     statfg->addElement(DrawActionBase::statCullTestedNodes,  
    328                        "%d Nodes culltested"); 
    329     statfg->addElement(DrawActionBase::statCulledNodes,  
    330                        "%d Nodes culled"); 
    331     statfg->addElement(RenderAction::statNMaterials,  
    332                        "%d material changes"); 
    333     statfg->addElement(RenderAction::statNMatrices,  
     546 
     547    statfg->addElement(RenderTraversalAction::statDrawTime, "Draw FPS: %r.3f"); 
     548    statfg->addElement(RenderTraversalAction::statNMatrices,  
    334549                       "%d matrix changes"); 
    335     statfg->addElement(RenderAction::statNGeometries,  
    336                        "%d Nodes drawn"); 
    337     statfg->addElement(RenderAction::statNTransGeometries,  
    338                        "%d transparent Nodes drawn"); 
    339     statfg->addElement(Drawable::statNTriangles,  
    340                        "%d triangles drawn"); 
    341     statfg->addElement(Drawable::statNLines,  
    342                        "%d lines drawn"); 
    343     statfg->addElement(Drawable::statNPoints,  
    344                        "%d points drawn"); 
    345     statfg->addElement(Drawable::statNPrimitives, 
    346                         "%d primitive groups drawn"); 
    347     statfg->addElement(Drawable::statNVertices,  
    348                        "%d vertices transformed"); 
    349     statfg->addElement(RenderAction::statNTextures, "%d textures used"); 
    350     statfg->addElement(RenderAction::statNTexBytes, "%d bytes of texture used"); 
    351 #endif 
    352      
     550    statfg->addElement(RenderTraversalAction::statNGeometries,  
     551                       "%d Geometries drawn"); 
     552    statfg->addElement(RenderTraversalAction::statNStates,  
     553                       "%d state changes"); 
     554    statfg->addElement(RenderTraversalAction::statNShaders,  
     555                       "%d shader changes"); 
     556    statfg->addElement(RenderTraversalAction::statNShaderParams,  
     557                       "%d shader param changes"); 
     558 
     559    statfg->addElement(OcclusionCullingTreeBuilder::statNOccNodes,  
     560                       "%d nodes in draw tree"); 
     561    statfg->addElement(OcclusionCullingTreeBuilder::statNOccTests,  
     562                       "%d occ tests"); 
     563    statfg->addElement(OcclusionCullingTreeBuilder::statNOccInvisible,  
     564                       "%d invisible nodes"); 
     565    statfg->addElement(OcclusionCullingTreeBuilder::statNOccSuccessTestPer,  
     566                       "%per%% success rate"); 
     567    
    353568    collector = &statfg->editCollector(); 
    354569 
     
    363578        mainwin->getPort(0)->addForeground(statfg); 
    364579    } 
     580 
     581#ifdef OSG_WITH_NVPERFSDK 
     582    NVPMRESULT status; 
     583 
     584    status = NVPMInit(); 
     585    if (status != NVPM_OK) { 
     586        FFATAL(("NVPerfSDK failed to initialize - no GPU data will be available")); 
     587    } 
     588    else 
     589    { 
     590        nvDataProvider->add("gpu_idle"); 
     591        nvDataProvider->add("pixel_shader_busy"); 
     592        nvDataProvider->add("vertex_shader_busy"); 
     593        nvDataProvider->add("shader_waits_for_texture"); 
     594         
     595        statfg->addElement(GPUIdleStat); 
     596        statfg->addElement(PSBusyStat); 
     597        statfg->addElement(VSBusyStat); 
     598        statfg->addElement(TextureWaitStat); 
     599          
     600    } 
     601#endif 
    365602     
    366603    // GLUT main loop