From 14136a659777ad680235e9cd768ad07a84f558eb Mon Sep 17 00:00:00 2001 From: Yoojin Jang Date: Wed, 13 Jun 2018 15:10:38 -0700 Subject: [PATCH] [HdSt] Enhance the current implementation of batching in HdSt With the current aggregation strategy, there is a chance to end up with one batch per draw item, which could affect rendering performance. For example, if you have a scene with many draw items, the draw items could map onto the same batchMap key which alternate into multiple different aggregated buffers. This PR provides managing multiple aggregated buffers for each batchMap key to reduce the number of draw batches. The test scene has - rprims: 8029 - instancer: 7429 (1 prototype for each instancer) - instances: 28132 - textures: 231 and everything is static with an animated camera. The current implementation generated - 156 draw batches, - 8029 draw items and it attempted to append a batch 3 times. This PR generated - 7 draw batches, - still 8029 draw items and it attempted to append a batch 11,319 times. The batchMap had 3 keys and the depth of each key's vector was 1, 5, and 1. The test scene was able to be rendered upto 10fps performance improvement. --- pxr/imaging/lib/hdSt/commandBuffer.cpp | 36 ++++++++++++++++++++------ 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/pxr/imaging/lib/hdSt/commandBuffer.cpp b/pxr/imaging/lib/hdSt/commandBuffer.cpp index ac78ad1efe..0e5d94a00f 100644 --- a/pxr/imaging/lib/hdSt/commandBuffer.cpp +++ b/pxr/imaging/lib/hdSt/commandBuffer.cpp @@ -44,6 +44,7 @@ #include #include +#include PXR_NAMESPACE_OPEN_SCOPE @@ -161,7 +162,7 @@ HdStCommandBuffer::_RebuildDrawBatches() .bindlessTextureEnabled; // XXX: Temporary sorting by shader. - std::map batchMap; + std::unordered_map> batchMap; for (size_t i = 0; i < _drawItems.size(); i++) { HdStDrawItem const * drawItem = _drawItems[i]; @@ -191,13 +192,32 @@ HdStCommandBuffer::_RebuildDrawBatches() key, drawItem->GetBufferArraysHash()); //, drawItem->GetRprimID().GetText()); - - HdSt_DrawBatchSharedPtr batch; - TfMapLookup(batchMap, key, &batch); - if (!batch || !batch->Append(drawItemInstance)) { - batch = _NewDrawBatch(drawItemInstance); - _drawBatches.push_back(batch); - batchMap[key] = batch; + + std::vector batches; + auto batchIter = batchMap.find(key); + if (batchIter == batchMap.end()) { + HdSt_DrawBatchSharedPtr batch = _NewDrawBatch(drawItemInstance); + _drawBatches.push_back(batch); + batches.push_back(batch); + batchMap[key] = batches; + } + else + { + batches = (batchIter->second); + bool hasAppended = false; + for (auto iter : batches) { + if (iter->Append(drawItemInstance)) { + hasAppended = true; + break; + } + } + + if (!hasAppended) { + HdSt_DrawBatchSharedPtr batch = _NewDrawBatch(drawItemInstance); + _drawBatches.push_back(batch); + batches.push_back(batch); + batchIter->second = batches; + } } } }