Instancing will no longer be used under X instances

*Experimental* optimization


Former-commit-id: 4dee4905d59739b3ec062ef283d4b7561160e21d
This commit is contained in:
Lynix 2013-08-09 00:33:18 +02:00
parent b969c24060
commit 28eff9af30
4 changed files with 25 additions and 12 deletions

View File

@ -29,6 +29,9 @@
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci /// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
// À partir de combien d'instances d'un même mesh/matériau l'instancing doit-il être utilisé ?
#define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 100
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) // Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
#define NAZARA_GRAPHICS_MEMORYLEAKTRACKER 0 #define NAZARA_GRAPHICS_MEMORYLEAKTRACKER 0

View File

@ -14,6 +14,7 @@
#include <Nazara/Math/Box.hpp> #include <Nazara/Math/Box.hpp>
#include <Nazara/Math/Matrix4.hpp> #include <Nazara/Math/Matrix4.hpp>
#include <map> #include <map>
#include <tuple>
class NzCamera; class NzCamera;
class NzMaterial; class NzMaterial;
@ -85,7 +86,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
typedef std::map<const NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer; typedef std::map<const NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
typedef std::map<const NzStaticMesh*, std::vector<StaticData>, StaticMeshComparator> StaticMeshContainer; typedef std::map<const NzStaticMesh*, std::vector<StaticData>, StaticMeshComparator> StaticMeshContainer;
typedef std::map<const NzMaterial*, std::pair<SkeletalMeshContainer, StaticMeshContainer>, ModelMaterialComparator> MeshContainer; typedef std::map<const NzMaterial*, std::tuple<bool, SkeletalMeshContainer, StaticMeshContainer>, ModelMaterialComparator> MeshContainer;
MeshContainer opaqueModels; MeshContainer opaqueModels;
std::vector<std::pair<unsigned int, bool>> transparentsModels; std::vector<std::pair<unsigned int, bool>> transparentsModels;

View File

@ -136,7 +136,7 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
if (pair.second) if (pair.second)
material->AddResourceListener(this, ResourceType_Material); material->AddResourceListener(this, ResourceType_Material);
auto& meshMap = pair.first->second.second; auto& meshMap = std::get<2>(pair.first->second);
auto pair2 = meshMap.insert(std::make_pair(staticMesh, StaticMeshContainer::mapped_type())); auto pair2 = meshMap.insert(std::make_pair(staticMesh, StaticMeshContainer::mapped_type()));
if (pair2.second) if (pair2.second)
@ -144,7 +144,13 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
std::vector<StaticData>& staticDataContainer = pair2.first->second; std::vector<StaticData>& staticDataContainer = pair2.first->second;
staticDataContainer.resize(staticDataContainer.size()+1); unsigned int instanceCount = staticDataContainer.size() + 1;
// As-t-on suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
if (instanceCount >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
std::get<0>(pair.first->second) = true; // Apparemment oui, activons l'instancing avec ce matériau
staticDataContainer.resize(instanceCount);
StaticData& data = staticDataContainer.back(); StaticData& data = staticDataContainer.back();
data.aabb = staticMesh->GetAABB(); data.aabb = staticMesh->GetAABB();
@ -211,7 +217,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
case ResourceType_SkeletalMesh: case ResourceType_SkeletalMesh:
{ {
for (auto& pair : opaqueModels) for (auto& pair : opaqueModels)
pair.second.first.erase(static_cast<const NzSkeletalMesh*>(resource)); std::get<1>(pair.second).erase(static_cast<const NzSkeletalMesh*>(resource));
break; break;
} }
@ -219,7 +225,7 @@ void NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
case ResourceType_StaticMesh: case ResourceType_StaticMesh:
{ {
for (auto& pair : opaqueModels) for (auto& pair : opaqueModels)
pair.second.second.erase(static_cast<const NzStaticMesh*>(resource)); std::get<2>(pair.second).erase(static_cast<const NzStaticMesh*>(resource));
break; break;
} }

View File

@ -143,20 +143,20 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
// Rendu des modèles opaques // Rendu des modèles opaques
for (auto& matIt : m_renderQueue.opaqueModels) for (auto& matIt : m_renderQueue.opaqueModels)
{ {
NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = matIt.second.first; NzForwardRenderQueue::SkeletalMeshContainer& skeletalContainer = std::get<1>(matIt.second);
NzForwardRenderQueue::StaticMeshContainer& staticContainer = matIt.second.second; NzForwardRenderQueue::StaticMeshContainer& staticContainer = std::get<2>(matIt.second);
if (!skeletalContainer.empty() || !staticContainer.empty()) if (!skeletalContainer.empty() || !staticContainer.empty())
{ {
const NzMaterial* material = matIt.first; const NzMaterial* material = matIt.first;
// Nous utilisons de l'instancing lorsqu'aucune lumière (autre que directionnelle) n'est active // La RenderQueue active ou non l'instancing selon le nombre d'instances
bool renderQueueInstancing = std::get<0>(matIt.second);
// Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active
// Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches
// (Le deferred shading n'a pas ce problème) // (Le deferred shading n'a pas ce problème)
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty() && renderQueueInstancing;
///FIXME: l'instancing fait-il réellement gagner en performances ?
///TODO: Activer l'instancing uniquement si plusieurs instances sont à rendre ?
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty();
// On commence par récupérer le programme du matériau // On commence par récupérer le programme du matériau
const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, (instancing) ? nzShaderFlags_Instancing : 0); const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, (instancing) ? nzShaderFlags_Instancing : 0);
@ -284,6 +284,9 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
} }
} }
} }
// Et on remet à zéro l'instancing
std::get<0>(matIt.second) = false;
} }
for (const std::pair<unsigned int, bool>& pair : m_renderQueue.transparentsModels) for (const std::pair<unsigned int, bool>& pair : m_renderQueue.transparentsModels)