示例#1
0
IProgram*   ShaderModuleRepository::findProgram(ShaderType type, int numShaders, IShader ** pShaders)
{
    int sz = (int)m_programs.size();
    for(int i=0; i<sz; i++)
    {
        IProgram* p = m_programs[i].p;
        if(numShaders != p->getNumShaders())
            continue;
        int j;
        for(j=0; j<numShaders; j++)
        {
            ShaderType t;
            IShader* pShd;
            pShd = p->getShader(0, &t);
            if(t != type)
                return NULL;
            if((pShd == NULL) || (findShader(pShd->getName()) == NULL) )
                break;
        }
        if(j == numShaders)
            return p;
    }
    return NULL;
}
示例#2
0
/*************************************************************************/ /**
 ** 
 ** 
 **/ /*************************************************************************/ 
void Container::consolidateShaders()
{
    ShaderModuleRepository* pShdRep = 
        static_cast<ShaderModuleRepository*>(getShaderModuleRepositorySingleton());
    std::set<IProgram *> usedPrograms;
    int sz = (int)m_shaderprograms.size();
    for(int i=0; i<sz; i++)
    {
        //assert(m_shaderprograms[i]);
        CHECK_POINTER(m_shaderprograms[i]);
        usedPrograms.insert(m_shaderprograms[i]);
    }
    // Clear the table : we are about to re-create it
    m_shaderprograms.clear();
    // Walk through techs/passes and check if any pass is using it
    TechVec::iterator it = m_techniques.begin();
    while(it != m_techniques.end())
    {
        Technique::PassVec::iterator ip = (*it)->m_passes.begin();
        while(ip != (*it)->m_passes.end())
        {
            Pass::StatesLayerMap::iterator isl = ip->pass->m_statesLayers.begin();
            while(isl != ip->pass->m_statesLayers.end())
            {
                IProgram* p;
                CHECK_TRUE_MSG(isl->second.program == NULL, "TODO: handle consolidation for non-separable programs");
                if(isl->second.programPipeline)
                  for(int i=0; p = isl->second.programPipeline->getShaderProgram(i); i++)
                  {
                    std::set<IProgram *>::iterator iip;
                    // at last we have a program
                    iip = usedPrograms.find(p);
#ifdef _DEBUG
                        //LOGD("Program %d (", p->getProgram() );
                        //IShader* pshd;
                        //for(int ii=0; pshd = p->getShader(ii); ii++)
                        //    LOGD("%s ", pshd->getName());
#endif
                    if(iip != usedPrograms.end())
                    {
#ifdef _DEBUG
                        LOGD("Program %d (", p->getProgram() );
                        IShader* pshd;
                        for(int ii=0; pshd = p->getShader(ii); ii++)
                            LOGD("%s ", pshd->getName());
                        LOGD(") Found as used by some pass (%s)\n", ip->pass->getName());
#endif
                        usedPrograms.erase(iip);
                        m_shaderprograms.push_back(p); // add it back, because used here
                    } else {
#ifdef _DEBUG
                        //LOGD(") used in pass %s BUT not found\n", ip->pass->getName());
#endif
                    }
                  } // for()
                ++isl;
            }
            ++ip;
        }
        ++it;
    }
    std::set<IProgram *>::iterator iip = usedPrograms.begin();
    while(iip != usedPrograms.end())
    {
#ifdef _DEBUG
        LOGD("Program %d (", (*iip)->getProgram() );
        IShader* pshd;
        for(int ii=0; pshd = (*iip)->getShader(ii); ii++)
            LOGD("%s ", pshd->getName());
#endif
        int c = pShdRep->releaseProgram(*iip);
        if(c <= 0)
        {
    #ifdef _DEBUG
            LOGD(") Not used anymore anywhere. DELETING it\n");
    #endif
            // good enough : query the first shader in the program
            switch((*iip)->getShader(0)->getType())
            {
            case TGLSL:
            case THLSL:
                delete_Program(*iip);
                break;
            case TCUDA:
                delete_ProgramCUDA(*iip);
                break;
            }
        } else {
#ifdef _DEBUG
        LOGD(") Still used as Global (%d)\n", c);
#endif
        }
        ++iip;
    }
}