Browse Source

Store batch groups into a HashMap for slightly better performance.

Lasse Öörni 13 năm trước cách đây
mục cha
commit
e1bd04e5dd
2 tập tin đã thay đổi với 20 bổ sung66 xóa
  1. 14 14
      Engine/Graphics/Batch.cpp
  2. 6 52
      Engine/Graphics/Batch.h

+ 14 - 14
Engine/Graphics/Batch.cpp

@@ -748,10 +748,10 @@ void BatchQueue::AddBatch(const Batch& batch)
         batches_.Push(batch);
         batches_.Push(batch);
     else
     else
     {
     {
-        Map<BatchGroupKey, BatchGroup>* groups = batch.isBase_ ? &baseBatchGroups_ : &batchGroups_;
+        HashMap<BatchGroupKey, BatchGroup>* groups = batch.isBase_ ? &baseBatchGroups_ : &batchGroups_;
         BatchGroupKey key(batch);
         BatchGroupKey key(batch);
         
         
-        Map<BatchGroupKey, BatchGroup>::Iterator i = groups->Find(key);
+        HashMap<BatchGroupKey, BatchGroup>::Iterator i = groups->Find(key);
         if (i == groups->End())
         if (i == groups->End())
         {
         {
             // Create a new group based on the batch
             // Create a new group based on the batch
@@ -779,10 +779,10 @@ void BatchQueue::SortBackToFront()
     sortedBatchGroups_.Resize(batchGroups_.Size());
     sortedBatchGroups_.Resize(batchGroups_.Size());
     
     
     unsigned index = 0;
     unsigned index = 0;
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
         sortedBaseBatchGroups_[index++] = &i->second_;
         sortedBaseBatchGroups_[index++] = &i->second_;
     index = 0;
     index = 0;
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
         sortedBatchGroups_[index++] = &i->second_;
         sortedBatchGroups_[index++] = &i->second_;
 }
 }
 
 
@@ -805,9 +805,9 @@ void BatchQueue::SortFrontToBack()
     Sort(sortedBatches_.Begin(), sortedBatches_.End(), CompareBatchesFrontToBack);
     Sort(sortedBatches_.Begin(), sortedBatches_.End(), CompareBatchesFrontToBack);
     
     
     // Sort each group front to back
     // Sort each group front to back
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
         Sort(i->second_.instances_.Begin(), i->second_.instances_.End(), CompareInstancesFrontToBack);
         Sort(i->second_.instances_.Begin(), i->second_.instances_.End(), CompareInstancesFrontToBack);
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
         Sort(i->second_.instances_.Begin(), i->second_.instances_.End(), CompareInstancesFrontToBack);
         Sort(i->second_.instances_.Begin(), i->second_.instances_.End(), CompareInstancesFrontToBack);
     
     
     // Now sort batch groups by the distance of the first batch
     // Now sort batch groups by the distance of the first batch
@@ -815,10 +815,10 @@ void BatchQueue::SortFrontToBack()
     sortedBatchGroups_.Resize(batchGroups_.Size());
     sortedBatchGroups_.Resize(batchGroups_.Size());
     
     
     unsigned index = 0;
     unsigned index = 0;
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
         sortedBaseBatchGroups_[index++] = &i->second_;
         sortedBaseBatchGroups_[index++] = &i->second_;
     index = 0;
     index = 0;
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
         sortedBatchGroups_[index++] = &i->second_;
         sortedBatchGroups_[index++] = &i->second_;
     
     
     Sort(sortedBaseBatchGroups_.Begin(), sortedBaseBatchGroups_.End(), CompareBatchGroupsFrontToBack);
     Sort(sortedBaseBatchGroups_.Begin(), sortedBaseBatchGroups_.End(), CompareBatchGroupsFrontToBack);
@@ -827,9 +827,9 @@ void BatchQueue::SortFrontToBack()
 
 
 void BatchQueue::SetTransforms(Renderer* renderer, void* lockedData, unsigned& freeIndex)
 void BatchQueue::SetTransforms(Renderer* renderer, void* lockedData, unsigned& freeIndex)
 {
 {
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
         i->second_.SetTransforms(renderer, lockedData, freeIndex);
         i->second_.SetTransforms(renderer, lockedData, freeIndex);
-    for (Map<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::Iterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
         i->second_.SetTransforms(renderer, lockedData, freeIndex);
         i->second_.SetTransforms(renderer, lockedData, freeIndex);
 }
 }
 
 
@@ -941,14 +941,14 @@ unsigned BatchQueue::GetNumInstances(Renderer* renderer) const
     unsigned total = 0;
     unsigned total = 0;
     unsigned maxIndexCount = renderer->GetMaxInstanceTriangles() * 3;
     unsigned maxIndexCount = renderer->GetMaxInstanceTriangles() * 3;
     
     
-    // This is for the purpose of calculating how much space is needed in the instancing buffer. Do not add groups
-    // that have too many triangles
-    for (Map<BatchGroupKey, BatchGroup>::ConstIterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
+    // As this function is for the purpose of calculating how much space is needed in the instancing buffer, do not add groups
+    // that have too many triangles to be instanced
+    for (HashMap<BatchGroupKey, BatchGroup>::ConstIterator i = baseBatchGroups_.Begin(); i != baseBatchGroups_.End(); ++i)
     {
     {
         if (i->second_.geometry_->GetIndexCount() <= maxIndexCount)
         if (i->second_.geometry_->GetIndexCount() <= maxIndexCount)
             total += i->second_.instances_.Size();
             total += i->second_.instances_.Size();
     }
     }
-    for (Map<BatchGroupKey, BatchGroup>::ConstIterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
+    for (HashMap<BatchGroupKey, BatchGroup>::ConstIterator i = batchGroups_.Begin(); i != batchGroups_.End(); ++i)
     {
     {
         if (i->second_.geometry_->GetIndexCount() <= maxIndexCount)
         if (i->second_.geometry_->GetIndexCount() <= maxIndexCount)
             total += i->second_.instances_.Size();
             total += i->second_.instances_.Size();

+ 6 - 52
Engine/Graphics/Batch.h

@@ -25,7 +25,6 @@
 
 
 #include "GraphicsDefs.h"
 #include "GraphicsDefs.h"
 #include "HashMap.h"
 #include "HashMap.h"
-#include "Map.h"
 #include "MathDefs.h"
 #include "MathDefs.h"
 #include "Ptr.h"
 #include "Ptr.h"
 #include "Rect.h"
 #include "Rect.h"
@@ -190,53 +189,8 @@ struct BatchGroupKey
     /// Test for inequality with another batch group key.
     /// Test for inequality with another batch group key.
     bool operator != (const BatchGroupKey& rhs) const { return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ || geometry_ != rhs.geometry_; }
     bool operator != (const BatchGroupKey& rhs) const { return zone_ != rhs.zone_ || lightQueue_ != rhs.lightQueue_ || pass_ != rhs.pass_ || material_ != rhs.material_ || geometry_ != rhs.geometry_; }
     
     
-    /// Test if less than another batch group key.
-    bool operator < (const BatchGroupKey& rhs) const
-    {
-        if (zone_ == rhs.zone_)
-        {
-            if (lightQueue_ == rhs.lightQueue_)
-            {
-                if (pass_ == rhs.pass_)
-                {
-                    if (material_ == rhs.material_)
-                        return geometry_ < rhs.geometry_;
-                    else
-                        return material_ < rhs.material_;
-                }
-                else
-                    return pass_ < rhs.pass_;
-            }
-            else
-                return lightQueue_ < rhs.lightQueue_;
-        }
-        else
-            return zone_ < rhs.zone_;
-    }
-    
-    /// Test if greater than another batch group key.
-    bool operator > (const BatchGroupKey& rhs) const
-    {
-        if (zone_ == rhs.zone_)
-        {
-            if (lightQueue_ == rhs.lightQueue_)
-            {
-                if (pass_ == rhs.pass_)
-                {
-                    if (material_ == rhs.material_)
-                        return geometry_ > rhs.geometry_;
-                    else
-                        return material_ > rhs.material_;
-                }
-                else
-                    return pass_ > rhs.pass_;
-            }
-            else
-                return lightQueue_ > rhs.lightQueue_;
-        }
-        else
-            return zone_ > rhs.zone_;
-    }
+    /// Return hash value.
+    unsigned ToHash() const { return (unsigned)zone_ + (unsigned)lightQueue_ + (unsigned)pass_ + (unsigned)material_ + (unsigned)geometry_; }
 };
 };
 
 
 /// Queue that contains both instanced and non-instanced draw calls.
 /// Queue that contains both instanced and non-instanced draw calls.
@@ -262,12 +216,12 @@ public:
     /// Return whether the batch group is empty.
     /// Return whether the batch group is empty.
     bool IsEmpty() const { return batches_.Empty() && baseBatchGroups_.Empty() && batchGroups_.Empty(); }
     bool IsEmpty() const { return batches_.Empty() && baseBatchGroups_.Empty() && batchGroups_.Empty(); }
     
     
-    /// Unsorted non-instanced draw calls.
-    PODVector<Batch> batches_;
     /// Instanced draw calls with base flag.
     /// Instanced draw calls with base flag.
-    Map<BatchGroupKey, BatchGroup> baseBatchGroups_;
+    HashMap<BatchGroupKey, BatchGroup> baseBatchGroups_;
     /// Instanced draw calls.
     /// Instanced draw calls.
-    Map<BatchGroupKey, BatchGroup> batchGroups_;
+    HashMap<BatchGroupKey, BatchGroup> batchGroups_;
+    /// Unsorted non-instanced draw calls.
+    PODVector<Batch> batches_;
     /// Sorted non-instanced draw calls with base flag.
     /// Sorted non-instanced draw calls with base flag.
     PODVector<Batch*> sortedBaseBatches_;
     PODVector<Batch*> sortedBaseBatches_;
     /// Sorted non-instanced draw calls.
     /// Sorted non-instanced draw calls.