|
31 | 31 | #include "gfx-base/GFXDescriptorSet.h" |
32 | 32 | #include "gfx-base/GFXDevice.h" |
33 | 33 | #include "gfx-base/GFXInputAssembler.h" |
| 34 | +#include "base/StringUtil.h" |
34 | 35 |
|
35 | 36 | namespace cc { |
36 | 37 | namespace pipeline { |
@@ -84,26 +85,24 @@ void InstancedBuffer::merge(scene::SubModel *subModel, uint32_t passIdx, gfx::Sh |
84 | 85 | _sortRender.hash = hash; |
85 | 86 | _sortRender.shaderID = shaderId; |
86 | 87 | _sortRender.passIndex = passIdx; |
87 | | - const ccstd::hash_t key = [&]() { |
88 | | - ccstd::hash_t seed = 2; |
89 | | - ccstd::hash_combine(seed, gfx::GFXObject::getObjectID(sourceIA->getIndexBuffer())); |
90 | | - ccstd::hash_combine(seed, gfx::GFXObject::getObjectID(lightingMap)); |
91 | | - ccstd::hash_combine(seed, reflectionProbeType); |
92 | | - ccstd::hash_combine(seed, gfx::GFXObject::getObjectID(reflectionProbeCubemap)); |
93 | | - ccstd::hash_combine(seed, gfx::GFXObject::getObjectID(reflectionProbePlanarMap)); |
94 | | - ccstd::hash_combine(seed, gfx::GFXObject::getObjectID(reflectionProbeBlendCubemap)); |
95 | | - ccstd::hash_combine(seed, stride); |
96 | | - return seed; |
97 | | - }(); |
| 88 | + const ccstd::string key = StringUtil::format("%u/%u/%u/%u/%u/%u/%u", |
| 89 | + sourceIA->getIndexBuffer() ? sourceIA->getIndexBuffer()->getObjectID() : 0, |
| 90 | + lightingMap ? lightingMap->getObjectID() : 0, |
| 91 | + reflectionProbeType, |
| 92 | + reflectionProbeCubemap ? reflectionProbeCubemap->getObjectID() : 0, |
| 93 | + reflectionProbePlanarMap ? reflectionProbePlanarMap->getObjectID() : 0, |
| 94 | + reflectionProbeBlendCubemap ? reflectionProbeBlendCubemap->getObjectID() : 0, |
| 95 | + stride); |
98 | 96 | const auto iter = _instancesMap.find(key); |
99 | 97 | if (iter != _instancesMap.end()) { |
100 | | - for (size_t idx : iter->second) { |
| 98 | + uint32_t idx = iter->second; |
| 99 | + while (idx != InstancedItem::INVALID_INDEX) { |
101 | 100 | auto &instance = _instances[idx]; |
102 | | - if (instance.drawInfo.instanceCount >= MAX_CAPACITY) { |
103 | | - continue; |
| 101 | + if (instance.drawInfo.instanceCount < MAX_CAPACITY) { |
| 102 | + appendInstance(instance, attrs.buffer, shader, descriptorSet); |
| 103 | + return; |
104 | 104 | } |
105 | | - appendInstance(instance, attrs.buffer, shader, descriptorSet); |
106 | | - return; |
| 105 | + idx = instance.nextWithSameKey; |
107 | 106 | } |
108 | 107 | } |
109 | 108 |
|
@@ -147,7 +146,7 @@ void InstancedBuffer::appendInstance(InstancedItem &instance, |
147 | 146 | _hasPendingModels = true; |
148 | 147 | } |
149 | 148 |
|
150 | | -void InstancedBuffer::createInstance(ccstd::hash_t key, |
| 149 | +void InstancedBuffer::createInstance(const ccstd::string &key, |
151 | 150 | gfx::InputAssembler *sourceIA, |
152 | 151 | const ccstd::vector<gfx::Attribute> &attributes, |
153 | 152 | Uint8Array &buffer, |
@@ -194,8 +193,10 @@ void InstancedBuffer::createInstance(ccstd::hash_t key, |
194 | 193 | reflectionProbeBlendCubemap, |
195 | 194 | ia->getDrawInfo()}; |
196 | 195 | item.drawInfo.instanceCount = 1; |
| 196 | + const auto headIter = _instancesMap.find(key); |
| 197 | + item.nextWithSameKey = headIter != _instancesMap.end() ? headIter->second : InstancedItem::INVALID_INDEX; |
197 | 198 | _instances.emplace_back(item); |
198 | | - _instancesMap[key].emplace_back(_instances.size() - 1); |
| 199 | + _instancesMap[key] = static_cast<uint32_t>(_instances.size() - 1); |
199 | 200 | _hasPendingModels = true; |
200 | 201 | } |
201 | 202 |
|
|
0 commit comments