Skip to content

Commit

Permalink
Big refactoring before switching from CMatrix44f to Transform
Browse files Browse the repository at this point in the history
  • Loading branch information
lhog committed Dec 15, 2024
1 parent fd875e0 commit b612e92
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 163 deletions.
25 changes: 13 additions & 12 deletions rts/Rendering/Common/ModelDrawerData.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ class CModelDrawerDataBase : public CModelDrawerDataConcept
void ClearPreviousDrawFlags() { for (auto object : unsortedObjects) object->previousDrawFlag = 0; }

const ScopedTransformMemAlloc& GetObjectTransformMemAlloc(const T* o) const {
const auto it = matricesMemAllocs.find(const_cast<T*>(o));
return (it != matricesMemAllocs.end()) ? it->second : ScopedTransformMemAlloc::Dummy();
const auto it = scTransMemAllocMap.find(const_cast<T*>(o));
return (it != scTransMemAllocMap.end()) ? it->second : ScopedTransformMemAlloc::Dummy();
}
ScopedTransformMemAlloc& GetObjectTransformMemAlloc(const T* o) { return matricesMemAllocs[const_cast<T*>(o)]; }
ScopedTransformMemAlloc& GetObjectTransformMemAlloc(const T* o) { return scTransMemAllocMap[const_cast<T*>(o)]; }
private:
static constexpr int MMA_SIZE0 = 2 << 16;
protected:
std::array<ModelRenderContainer<T>, MODELTYPE_CNT> modelRenderers;

std::vector<T*> unsortedObjects;
std::unordered_map<T*, ScopedTransformMemAlloc> matricesMemAllocs;
std::unordered_map<T*, ScopedTransformMemAlloc> scTransMemAllocMap;

bool& mtModelDrawer;
};
Expand All @@ -100,15 +100,15 @@ inline CModelDrawerDataBase<T>::CModelDrawerDataBase(const std::string& ecName,
: CModelDrawerDataConcept(ecName, ecOrder)
, mtModelDrawer(mtModelDrawer_)
{
matricesMemAllocs.reserve(MMA_SIZE0);
scTransMemAllocMap.reserve(MMA_SIZE0);
for (auto& mr : modelRenderers) { mr.Clear(); }
}

template<typename T>
inline CModelDrawerDataBase<T>::~CModelDrawerDataBase()
{
unsortedObjects.clear();
matricesMemAllocs.clear();
scTransMemAllocMap.clear();
}

template<typename T>
Expand All @@ -126,7 +126,7 @@ inline void CModelDrawerDataBase<T>::AddObject(const T* co, bool add)
unsortedObjects.emplace_back(o);

const uint32_t numMatrices = (o->model ? o->model->numPieces : 0) + 1u;
matricesMemAllocs.emplace(o, ScopedTransformMemAlloc(numMatrices));
scTransMemAllocMap.emplace(o, ScopedTransformMemAlloc(numMatrices));

modelUniformsStorage.GetObjOffset(co);
}
Expand All @@ -141,7 +141,7 @@ inline void CModelDrawerDataBase<T>::DelObject(const T* co, bool del)
}

if (del && spring::VectorErase(unsortedObjects, o)) {
matricesMemAllocs.erase(o);
scTransMemAllocMap.erase(o);
modelUniformsStorage.GetObjOffset(co);
}
}
Expand All @@ -164,8 +164,7 @@ inline void CModelDrawerDataBase<T>::UpdateObjectSMMA(const T* o)

// from one point it doesn't worth the comparison, cause units usually move
// but having not updated smma[0] allows for longer solid no-update areas in ModelUniformsUploader::UpdateDerived()
if (tmNew != tmOld)
smma[0] = tmNew;
smma.UpdateIfChanged(0, tmNew);

for (int i = 0; i < o->localModel.pieces.size(); ++i) {
const LocalModelPiece& lmp = o->localModel.pieces[i];
Expand All @@ -175,11 +174,13 @@ inline void CModelDrawerDataBase<T>::UpdateObjectSMMA(const T* o)
continue;

if unlikely(!lmp.GetScriptVisible()) {
smma[i + 1] = CMatrix44f::Zero();
//smma[i + 1] = CMatrix44f::Zero();
smma.UpdateForced(i + 1, CMatrix44f::Zero());
continue;
}

smma[i + 1] = lmp.GetModelSpaceMatrix();
// UpdateIfChanged is not needed, wasCustomDirty takes that role
smma.UpdateForced(i + 1, lmp.GetModelSpaceMatrix());
}
}

Expand Down
22 changes: 20 additions & 2 deletions rts/Rendering/Common/UpdateList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ void UpdateList::ResetNeedUpdateAll()
changed = false;
}

void UpdateList::Trim(size_t newLessThanOrEqualSize)
{
RECOIL_DETAILED_TRACY_ZONE;
assert(newLessThanOrEqualSize <= updateList.size());
updateList.resize(newLessThanOrEqualSize);
// no need to modify the update status
}

void UpdateList::SetUpdate(size_t first, size_t count)
{
RECOIL_DETAILED_TRACY_ZONE;

auto beg = updateList.begin() + first;
auto end = beg + count;

SetUpdate(UpdateList::IteratorPair(beg, end));
}

void UpdateList::SetUpdate(const UpdateList::IteratorPair& it)
{
RECOIL_DETAILED_TRACY_ZONE;
Expand Down Expand Up @@ -60,7 +78,7 @@ void UpdateList::PopBack(size_t N)
changed = true;
}

std::optional<UpdateList::IteratorPair> UpdateList::GetNext(const std::optional<UpdateList::IteratorPair>& prev)
std::optional<UpdateList::ConstIteratorPair> UpdateList::GetNext(const std::optional<UpdateList::ConstIteratorPair>& prev) const
{
RECOIL_DETAILED_TRACY_ZONE;
auto beg = prev.has_value() ? prev.value().second : updateList.begin();
Expand All @@ -73,7 +91,7 @@ std::optional<UpdateList::IteratorPair> UpdateList::GetNext(const std::optional<
return std::make_optional(std::make_pair(beg, end));
}

std::pair<size_t, size_t> UpdateList::GetOffsetAndSize(const UpdateList::IteratorPair& it)
std::pair<size_t, size_t> UpdateList::GetOffsetAndSize(const UpdateList::ConstIteratorPair& it) const
{
RECOIL_DETAILED_TRACY_ZONE;
return std::make_pair(
Expand Down
13 changes: 10 additions & 3 deletions rts/Rendering/Common/UpdateList.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,26 @@
class UpdateList {
CR_DECLARE_STRUCT(UpdateList)
public:
using ConstIteratorPair = std::pair<std::vector<bool>::const_iterator, std::vector<bool>::const_iterator>;
using IteratorPair = std::pair<std::vector<bool>::iterator, std::vector<bool>::iterator>;
public:
UpdateList()
: updateList()
, changed(true)
, changed(false)
{}
UpdateList(size_t initialSize)
: updateList(initialSize)
, changed(initialSize > 0)
{}

size_t Size() const { return updateList.size(); }
size_t Capacity() const { return updateList.capacity(); }

void Trim(size_t newLessThanOrEqualSize);
void Resize(size_t newSize) { updateList.resize(newSize); SetNeedUpdateAll(); }
void Reserve(size_t reservedSize) { updateList.reserve(reservedSize); }

void SetUpdate(size_t first, size_t count);
void SetUpdate(const IteratorPair& it);
void SetUpdate(size_t offset);

Expand All @@ -33,8 +40,8 @@ class UpdateList {

bool NeedUpdate() const { return changed; }

std::optional<IteratorPair> GetNext(const std::optional<IteratorPair>& prev = std::nullopt);
std::pair<size_t, size_t> GetOffsetAndSize(const IteratorPair& it);
std::optional<ConstIteratorPair> GetNext(const std::optional<ConstIteratorPair>& prev = std::nullopt) const;
std::pair<size_t, size_t> GetOffsetAndSize(const ConstIteratorPair& it) const;
private:
std::vector<bool> updateList;
bool changed;
Expand Down
6 changes: 4 additions & 2 deletions rts/Rendering/Models/3DModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -763,13 +763,15 @@ void S3DModel::SetPieceMatrices()
// use this occasion and copy bpose matrices
for (size_t i = 0; i < pieceObjects.size(); ++i) {
const auto* po = pieceObjects[i];
traAlloc[0 + i] = po->bposeTransform.ToMatrix();
//traAlloc[0 + i] = po->bposeTransform.ToMatrix();
traAlloc.UpdateForced((0 + i), po->bposeTransform.ToMatrix());
}

// use this occasion and copy inverse bpose matrices
// store them right after all bind pose matrices
for (size_t i = 0; i < pieceObjects.size(); ++i) {
const auto* po = pieceObjects[i];
traAlloc[numPieces + i] = po->bposeInvTransform.ToMatrix();
//traAlloc[numPieces + i] = po->bposeInvTransform.ToMatrix();
traAlloc.UpdateForced((numPieces + i), po->bposeInvTransform.ToMatrix());
}
}
71 changes: 66 additions & 5 deletions rts/Rendering/Models/ModelsMemStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,31 @@ ModelUniformsStorage modelUniformsStorage;
ModelUniformsStorage::ModelUniformsStorage()
{
RECOIL_DETAILED_TRACY_ZONE;
storage[0] = dummy;
objectsMap.emplace(nullptr, 0);
storage[AddObjects(static_cast<const CWorldObject*>(nullptr))] = dummy;
}

ModelUniformsStorage::~ModelUniformsStorage()
{
// just in case
DelObjects(static_cast<const CWorldObject*>(nullptr));
}

size_t ModelUniformsStorage::AddObjects(const CWorldObject* o)
{
RECOIL_DETAILED_TRACY_ZONE;
const size_t idx = storage.Add(ModelUniformData());
objectsMap[const_cast<CWorldObject*>(o)] = idx;

if (idx + 1 == storage.size()) {
//new item got added to the end of storage
updateList.EmplaceBackUpdate();
} else {
// storage got updated somewhere in the middle, use updateList.SetUpdate()
updateList.SetUpdate(idx);
}

assert(storage.size() == updateList.Size());

return idx;
}

Expand All @@ -28,7 +44,18 @@ void ModelUniformsStorage::DelObjects(const CWorldObject* o)
assert(it != objectsMap.end());

storage.Del(it->second);

if (storage.size() < updateList.Size()) {
// storage got one element shorter, trim updateList as well
updateList.Trim(it->second);
} else {
// storage got updated somewhere in the middle, use updateList.SetUpdate()
updateList.SetUpdate(it->second);
}

objectsMap.erase(it);

assert(storage.size() == updateList.Size());
}

size_t ModelUniformsStorage::GetObjOffset(const CWorldObject* o)
Expand All @@ -49,9 +76,43 @@ ModelUniformsStorage::MyType& ModelUniformsStorage::GetObjUniformsArray(const CW
return storage[offset];
}

void TransformsMemStorage::SetAllDirty()
TransformsMemStorage::TransformsMemStorage()
: storage(StablePosAllocator<MyType>(INIT_NUM_ELEMS))
, updateList(INIT_NUM_ELEMS)
{}

void TransformsMemStorage::Reset()
{
RECOIL_DETAILED_TRACY_ZONE;
assert(Threading::IsMainThread());
std::fill(dirtyMap.begin(), dirtyMap.end(), BUFFERING);
storage.Reset();
updateList.Trim(storage.GetSize());
}

size_t TransformsMemStorage::Allocate(size_t numElems)
{
auto lock = CModelsLock::GetScopedLock();

auto res = storage.Allocate(numElems);
updateList.Resize(storage.GetSize());

assert(updateList.Size() == storage.GetSize());

return res;
}

void TransformsMemStorage::Free(size_t firstElem, size_t numElems, const MyType* T0)
{
auto lock = CModelsLock::GetScopedLock();

storage.Free(firstElem, numElems, T0);
updateList.SetUpdate(firstElem, numElems);
updateList.Trim(storage.GetSize());

assert(updateList.Size() == storage.GetSize());
}

const TransformsMemStorage::MyType& TransformsMemStorage::operator[](std::size_t idx) const
{
auto lock = CModelsLock::GetScopedLock();
return storage[idx];
}
Loading

0 comments on commit b612e92

Please sign in to comment.