Ticket #1859: ModelCache.2.patch

File ModelCache.2.patch, 5.6 KB (added by wraitii, 11 years ago)
  • source/renderer/ModelRenderer.cpp

     
    453453            }
    454454
    455455            SMRMaterialBucketKey key(model->GetMaterial().GetShaderEffect(), defs);
    456             std::vector<CModel*>& bucketItems = materialBuckets[key];
    457             bucketItems.push_back(model);
     456            materialBuckets[key].push_back(model);
    458457        }
    459458    }
    460 
    461459    std::vector<SMRSortByDistItem> sortByDistItems;
    462460
    463461    std::vector<CShaderTechniquePtr> sortByDistTechs;
     
    573571
    574572        size_t idxTechStart = 0;
    575573       
    576         // This vector keeps track of texture changes during rendering. It is kept outside the
    577         // loops to avoid excessive reallocations. The token allocation of 64 elements
    578         // should be plenty, though it is reallocated below (at a cost) if necessary.
    579         std::vector<CTexture*> currentTexs;
    580         currentTexs.reserve(64);
    581574       
    582         // texBindings holds the identifier bindings in the shader, which can no longer be defined
    583         // statically in the ShaderRenderModifier class. texBindingNames uses interned strings to
    584         // keep track of when bindings need to be reevaluated.
    585         std::vector<CShaderProgram::Binding> texBindings;
    586         texBindings.reserve(64);
    587         std::vector<CStrIntern> texBindingNames;
    588         texBindingNames.reserve(64);
    589 
     575        // using "4" as the maximal size of these arrays as it's what we currently use at most.
     576        // will crash if using more.
     577        // This is temporary.
     578       
     579        CTexture* currentTexs[4];
     580        CShaderProgram::Binding texBindings[4];
     581        CStrIntern texBindingNames[4];
     582       
    590583        while (idxTechStart < techBuckets.size())
    591584        {
    592585            CShaderTechniquePtr currentTech = techBuckets[idxTechStart].tech;
     
    611604
    612605                m->vertexRenderer->BeginPass(streamflags);
    613606               
    614                 // When the shader technique changes, textures need to be
    615                 // rebound, so ensure there are no remnants from the last pass.
    616                 // (the vector size is set to 0, but memory is not freed)
    617                 currentTexs.clear();
    618                 texBindings.clear();
    619                 texBindingNames.clear();
     607                // reinitialize the values since we're using a new shader that has not be bound yet.
     608                for (size_t i = 0; i < 4; ++i)
     609                {
     610                    texBindingNames[i] = CStrIntern();
     611                    currentTexs[i] = NULL;
     612                    texBindings[i] = CShaderProgram::Binding();
     613                }
    620614               
    621615                CModelDef* currentModeldef = NULL;
    622616                CShaderUniforms currentStaticUniforms;
     
    625619                {
    626620                    CModel** models = techBuckets[idx].models;
    627621                    size_t numModels = techBuckets[idx].numModels;
     622
    628623                    for (size_t i = 0; i < numModels; ++i)
    629624                    {
    630625                        CModel* model = models[i];
     
    635630                        CMaterial::SamplersVector samplers = model->GetMaterial().GetSamplers();
    636631                        size_t samplersNum = samplers.size();
    637632                       
    638                         // make sure the vectors are the right virtual sizes, and also
    639                         // reallocate if there are more samplers than expected.
    640                         if (currentTexs.size() != samplersNum)
     633                        // We only cache up to 4. If there are more, we won't use caching
     634                        // TODO: this isn't really nice, it probably ought to fail or something.
     635                        if (samplersNum > 4)
    641636                        {
    642                             currentTexs.resize(samplersNum, NULL);
    643                             texBindings.resize(samplersNum, CShaderProgram::Binding());
    644                             texBindingNames.resize(samplersNum, CStrIntern());
    645                            
    646                             // ensure they are definitely empty
    647                             std::fill(texBindings.begin(), texBindings.end(), CShaderProgram::Binding());
    648                             std::fill(currentTexs.begin(), currentTexs.end(), (CTexture*)NULL);
    649                             std::fill(texBindingNames.begin(), texBindingNames.end(), CStrIntern());
    650                         }
    651                        
    652                         // bind the samplers to the shader
    653                         for (size_t s = 0; s < samplersNum; ++s)
    654                         {
    655                             CMaterial::TextureSampler &samp = samplers[s];
    656                            
    657                             CShaderProgram::Binding bind = texBindings[s];
    658                             // check that the handles are current
    659                             // and reevaluate them if necessary
    660                             if (texBindingNames[s] == samp.Name && bind.Active())
     637                            for (size_t s = 0; s < samplersNum; ++s)
    661638                            {
    662                                 bind = texBindings[s];
     639                                CMaterial::TextureSampler &samp = samplers[s];
     640                                CShaderProgram::Binding bind = texBindings[s];
     641                                bind = shader->GetTextureBinding(samp.Name.c_str());
     642                                if (bind.Active())
     643                                    shader->BindTexture(bind, samp.Sampler->GetHandle());
    663644                            }
    664                             else
     645                        } else {
     646                            // bind the samplers to the shader
     647                            for (size_t s = 0; s < samplersNum; ++s)
    665648                            {
    666                                 bind = shader->GetTextureBinding(samp.Name.c_str());       
    667                                 texBindings[s] = bind;
    668                                 texBindingNames[s] = samp.Name;
     649                                CMaterial::TextureSampler &samp = samplers[s];
     650                               
     651                                CShaderProgram::Binding bind = texBindings[s];
     652                                // check that the handles are current
     653                                // and reevaluate them if necessary
     654                                if (!(texBindingNames[s] == samp.Name))
     655                                {
     656                                    bind = shader->GetTextureBinding(samp.Name.c_str());
     657                                    texBindings[s] = bind;
     658                                    texBindingNames[s] = samp.Name;
     659                                }
     660                               
     661                                // same with the actual sampler bindings
     662                                CTexture* newTex = samp.Sampler.get();
     663                                if (bind.Active() && newTex != currentTexs[s])
     664                                {
     665                                    shader->BindTexture(bind, samp.Sampler->GetHandle());
     666                                    currentTexs[s] = newTex;
     667                                }
    669668                            }
    670 
    671                             // same with the actual sampler bindings
    672                             CTexture* newTex = samp.Sampler.get();
    673                             if (bind.Active() && newTex != currentTexs[s])
    674                             {
    675                                 shader->BindTexture(bind, samp.Sampler->GetHandle());
    676                                 currentTexs[s] = newTex;
    677                             }
    678669                        }
    679670                       
    680671                        // Bind modeldef when it changes