From bdd3cac0511be4f9de1beaa3070c899efd532a8d Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Sun, 20 Apr 2025 17:32:53 +0200 Subject: [PATCH] Reduces allocations for ShaderDefines. It allows to reduce the number of allocations per-frame for ShaderDefines. For example, on Acropolis Bay it goes down from 2.7k to 0.9k for the whole map view. We don't really need std::vector for it. Because materials and particularly shaders shouldn't have so many parameters. --- source/graphics/ShaderDefines.cpp | 26 +++++++++++++------------- source/graphics/ShaderDefines.h | 10 +++++++--- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/source/graphics/ShaderDefines.cpp b/source/graphics/ShaderDefines.cpp index 064cde5be3..f05117d9cd 100644 --- a/source/graphics/ShaderDefines.cpp +++ b/source/graphics/ShaderDefines.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -105,7 +105,7 @@ void CShaderParams::Set(CStrIntern name, const value_t& value) typename SItems::Item addedItem = std::make_pair(name, value); // Add the new item in a way that preserves the sortedness and uniqueness of item names - for (typename std::vector::iterator it = items.items.begin(); ; ++it) + for (typename SItems::ItemsContainers::iterator it = items.items.begin(); ; ++it) { if (it == items.items.end() || addedItem.first < it->first) { @@ -143,8 +143,8 @@ template std::map CShaderParams::GetMap() const { std::map ret; - for (size_t i = 0; i < m_Items->items.size(); ++i) - ret[m_Items->items[i].first] = m_Items->items[i].second; + for (const typename SItems::Item& item : m_Items->items) + ret[item.first] = item.second; return ret; } @@ -158,10 +158,10 @@ template void CShaderParams::SItems::RecalcHash() { size_t h = 0; - for (size_t i = 0; i < items.size(); ++i) + for (const Item& item : items) { - hash_combine(h, items[i].first); - hash_combine(h, items[i].second); + hash_combine(h, item.first); + hash_combine(h, item.second); } hash = h; } @@ -175,12 +175,12 @@ void CShaderDefines::Add(CStrIntern name, CStrIntern value) int CShaderDefines::GetInt(const char* name) const { CStrIntern nameIntern(name); - for (size_t i = 0; i < m_Items->items.size(); ++i) + for (const SItems::Item& item : m_Items->items) { - if (m_Items->items[i].first == nameIntern) + if (item.first == nameIntern) { int ret; - std::stringstream str(m_Items->items[i].second.c_str()); + std::stringstream str(item.second.c_str()); str >> ret; return ret; } @@ -197,11 +197,11 @@ void CShaderUniforms::Add(const char* name, const CVector4D& value) CVector4D CShaderUniforms::GetVector(const char* name) const { CStrIntern nameIntern(name); - for (size_t i = 0; i < m_Items->items.size(); ++i) + for (const SItems::Item& item : m_Items->items) { - if (m_Items->items[i].first == nameIntern) + if (item.first == nameIntern) { - return m_Items->items[i].second; + return item.second; } } return CVector4D(); diff --git a/source/graphics/ShaderDefines.h b/source/graphics/ShaderDefines.h index 2d91cd1ac8..8bcc0d8ec9 100644 --- a/source/graphics/ShaderDefines.h +++ b/source/graphics/ShaderDefines.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,6 +18,7 @@ #ifndef INCLUDED_SHADERDEFINES #define INCLUDED_SHADERDEFINES +#include "ps/containers/StaticVector.h" #include "ps/CStr.h" #include "ps/CStrIntern.h" #include "renderer/backend/IDeviceCommandContext.h" @@ -100,8 +101,11 @@ public: // Name/value pair using Item = std::pair; - // Sorted by name; no duplicated names - std::vector items; + // Sorted by name; no duplicated names. We can use the StaticVector + // because we shouldn't have too many shader parameters of a single + // type. + using ItemsContainers = PS::StaticVector; + ItemsContainers items; size_t hash;