From 0650721b199927464b2ef327d181a1bd621a4ab3 Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Mon, 21 Sep 2026 00:47:13 +0200 Subject: [PATCH] Replaces round to closest power of two by std ones --- source/graphics/HeightMipmap.cpp | 4 ++-- source/graphics/LOSTexture.cpp | 5 +++-- source/graphics/MiniMapTexture.cpp | 4 ++-- source/graphics/TerrainTextureManager.cpp | 2 +- source/graphics/TerritoryTexture.cpp | 6 +++--- source/lib/bits.h | 18 ------------------ source/lib/file/io/write_buffer.cpp | 5 +++-- source/lib/tests/test_bits.h | 17 ----------------- source/ps/memory/LinearAllocator.h | 5 +++-- source/renderer/ShadowMap.cpp | 4 ++-- source/renderer/TerrainOverlay.cpp | 6 +++--- source/renderer/WaterManager.cpp | 4 ++-- .../backend/vulkan/DeviceCommandContext.cpp | 5 ++--- .../backend/vulkan/RingCommandContext.cpp | 3 ++- 14 files changed, 28 insertions(+), 60 deletions(-) diff --git a/source/graphics/HeightMipmap.cpp b/source/graphics/HeightMipmap.cpp index 2d5ccae8f2..d387e9e766 100644 --- a/source/graphics/HeightMipmap.cpp +++ b/source/graphics/HeightMipmap.cpp @@ -22,7 +22,6 @@ #include "lib/alignment.h" #include "lib/allocators/dynarray.h" #include "lib/allocators/shared_ptr.h" -#include "lib/bits.h" #include "lib/debug.h" #include "lib/file/vfs/vfs.h" #include "lib/file/vfs/vfs_path.h" @@ -32,6 +31,7 @@ #include "maths/MathUtil.h" #include "ps/Filesystem.h" +#include #include #include #include @@ -96,7 +96,7 @@ void CHeightMipmap::Initialize(size_t mapSize, const u16* ptr) ReleaseData(); m_MapSize = mapSize; - size_t mipmapSize = round_down_to_pow2(mapSize); + size_t mipmapSize = std::bit_floor(mapSize); while (mipmapSize > 1) { diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp index cabdcd7f4e..3c1188c6e4 100644 --- a/source/graphics/LOSTexture.cpp +++ b/source/graphics/LOSTexture.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -47,6 +47,7 @@ #include "simulation2/system/Entity.h" #include +#include #include #include @@ -255,7 +256,7 @@ void CLOSTexture::ConstructTexture(Renderer::Backend::IDeviceCommandContext* dev m_MapSize = cmpRangeManager->GetVerticesPerSide(); - const size_t textureSize = round_up_to_pow2(round_up((size_t)m_MapSize + g_BlurSize - 1, g_SubTextureAlignment)); + const size_t textureSize = std::bit_ceil(round_up((size_t)m_MapSize + g_BlurSize - 1, g_SubTextureAlignment)); Renderer::Backend::IDevice* backendDevice = deviceCommandContext->GetDevice(); diff --git a/source/graphics/MiniMapTexture.cpp b/source/graphics/MiniMapTexture.cpp index 1e7ebbda7e..d729fdfad8 100644 --- a/source/graphics/MiniMapTexture.cpp +++ b/source/graphics/MiniMapTexture.cpp @@ -28,7 +28,6 @@ #include "graphics/TerrainTextureEntry.h" #include "graphics/TerritoryTexture.h" #include "graphics/TextureManager.h" -#include "lib/bits.h" #include "lib/code_generation.h" #include "lib/debug.h" #include "lib/hash.h" @@ -69,6 +68,7 @@ #include #include +#include #include #include #include @@ -392,7 +392,7 @@ void CMiniMapTexture::CreateTextures( DestroyTextures(); m_MapSize = terrain.GetVerticesPerSide(); - const size_t textureSize = round_up_to_pow2(static_cast(m_MapSize)); + const size_t textureSize = std::bit_ceil(static_cast(m_MapSize)); const Renderer::Backend::Sampler::Desc defaultSamplerDesc = Renderer::Backend::Sampler::MakeDefaultSampler( diff --git a/source/graphics/TerrainTextureManager.cpp b/source/graphics/TerrainTextureManager.cpp index 0b387d177e..df5df91911 100644 --- a/source/graphics/TerrainTextureManager.cpp +++ b/source/graphics/TerrainTextureManager.cpp @@ -231,7 +231,7 @@ CTerrainTextureManager::LoadAlphaMap(const VfsPath& alphaMapType) // copy each alpha map (tile) into one buffer, arrayed horizontally. // const size_t tileWidth = 2 + base + 2; // 2 pixel border (avoids bilinear filtering artifacts) - const size_t totalWidth = round_up_to_pow2(tileWidth * NUM_ALPHA_MAPS); + const size_t totalWidth = std::bit_ceil(tileWidth * NUM_ALPHA_MAPS); const size_t totalHeight = base; ENSURE(std::has_single_bit(totalHeight)); std::shared_ptr data; AllocateAligned(data, totalWidth * totalHeight, maxSectorSize); diff --git a/source/graphics/TerritoryTexture.cpp b/source/graphics/TerritoryTexture.cpp index 53410c167b..4b979c4a42 100644 --- a/source/graphics/TerritoryTexture.cpp +++ b/source/graphics/TerritoryTexture.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,7 +21,6 @@ #include "graphics/Color.h" #include "graphics/Terrain.h" -#include "lib/bits.h" #include "lib/debug.h" #include "ps/Profile.h" #include "renderer/backend/Format.h" @@ -39,6 +38,7 @@ #include "simulation2/system/Entity.h" #include +#include #include #include #include @@ -93,7 +93,7 @@ void CTerritoryTexture::ConstructTexture(Renderer::Backend::IDeviceCommandContex // Convert size from terrain tiles to territory tiles m_MapSize = cmpTerrain->GetMapSize() * Pathfinding::NAVCELL_SIZE_INT / ICmpTerritoryManager::NAVCELLS_PER_TERRITORY_TILE; - const uint32_t textureSize = round_up_to_pow2(static_cast(m_MapSize)); + const uint32_t textureSize = std::bit_ceil(static_cast(m_MapSize)); m_Texture = deviceCommandContext->GetDevice()->CreateTexture2D("TerritoryTexture", Renderer::Backend::ITexture::Usage::TRANSFER_DST | diff --git a/source/lib/bits.h b/source/lib/bits.h index aef6203cd0..883195fd44 100644 --- a/source/lib/bits.h +++ b/source/lib/bits.h @@ -195,24 +195,6 @@ struct CeilLog2<0> **/ extern int floor_log2(const float x); -/** - * round up to next larger power of two. - **/ -template -inline T round_up_to_pow2(T x) -{ - return T(1) << ceil_log2(x); -} - -/** - * round down to next larger power of two. - **/ -template -inline T round_down_to_pow2(T x) -{ - return T(1) << floor_log2(x); -} - /** * round number up/down to the next given multiple. * diff --git a/source/lib/file/io/write_buffer.cpp b/source/lib/file/io/write_buffer.cpp index 7c4de6e927..a2b4081013 100644 --- a/source/lib/file/io/write_buffer.cpp +++ b/source/lib/file/io/write_buffer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -32,6 +32,7 @@ #include "lib/sysdep/rtl.h" #include +#include #include static const size_t BLOCK_SIZE = 512*KiB; @@ -47,7 +48,7 @@ void WriteBuffer::EnsureSufficientCapacity(size_t size) { if(m_size + size > m_capacity) { - m_capacity = round_up_to_pow2(m_size + size); + m_capacity = std::bit_ceil(m_size + size); std::shared_ptr newData; AllocateAligned(newData, m_capacity, maxSectorSize); memcpy(newData.get(), m_data.get(), m_size); diff --git a/source/lib/tests/test_bits.h b/source/lib/tests/test_bits.h index 8a1e8207aa..0955d0a696 100644 --- a/source/lib/tests/test_bits.h +++ b/source/lib/tests/test_bits.h @@ -101,23 +101,6 @@ public: EQUALS(floor_log2(256.f), 8); } - void test_round_up_to_pow2() - { - EQUALS(round_up_to_pow2(0u), 1u); - EQUALS(round_up_to_pow2(1u), 1u); - EQUALS(round_up_to_pow2(127u), 128u); - EQUALS(round_up_to_pow2(128u), 128u); - EQUALS(round_up_to_pow2(129u), 256u); - } - - void test_round_down_to_pow2() - { - EQUALS(round_down_to_pow2(1u), 1u); - EQUALS(round_down_to_pow2(127u), 64u); - EQUALS(round_down_to_pow2(128u), 128u); - EQUALS(round_down_to_pow2(129u), 128u); - } - void test_round_up() { EQUALS(round_up( 0u, 16u), 0u); diff --git a/source/ps/memory/LinearAllocator.h b/source/ps/memory/LinearAllocator.h index 4fd3f9f4a3..ebb6419082 100644 --- a/source/ps/memory/LinearAllocator.h +++ b/source/ps/memory/LinearAllocator.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ #include "lib/bits.h" #include "ps/containers/StaticVector.h" +#include #include #include #include @@ -64,7 +65,7 @@ public: { m_BuffersToFree.emplace_back(std::move(m_Buffer)); m_Size = 0; - m_Capacity = std::min(std::max(round_up_to_pow2(n), m_Capacity * 2), m_MaxCapacity); + m_Capacity = std::min(std::max(std::bit_ceil(n), m_Capacity * 2), m_MaxCapacity); if (n > m_Capacity) { throw CapacityExceededException{fmt::format( diff --git a/source/renderer/ShadowMap.cpp b/source/renderer/ShadowMap.cpp index 45b1200138..e5eb4d61f1 100644 --- a/source/renderer/ShadowMap.cpp +++ b/source/renderer/ShadowMap.cpp @@ -21,7 +21,6 @@ #include "graphics/Camera.h" #include "graphics/Color.h" -#include "lib/bits.h" #include "lib/config2.h" #include "lib/debug.h" #include "maths/BoundingBoxAligned.h" @@ -50,6 +49,7 @@ #include #include +#include #include #include #include @@ -513,7 +513,7 @@ void ShadowMapInternals::CreateTexture(const uint32_t width, const uint32_t heig break; // Ultra case 2: - shadowMapSize = std::max(round_up_to_pow2(std::max(width, height)), 4096u); + shadowMapSize = std::max(std::bit_ceil(static_cast(std::max(width, height))), 4096u); break; // Medium as is default: diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp index ca9ab481f1..3b84232e54 100644 --- a/source/renderer/TerrainOverlay.cpp +++ b/source/renderer/TerrainOverlay.cpp @@ -26,7 +26,6 @@ #include "graphics/ShaderManager.h" #include "graphics/ShaderTechnique.h" #include "graphics/Terrain.h" -#include "lib/bits.h" #include "maths/MathUtil.h" #include "maths/Matrix3D.h" #include "maths/Vector2D.h" @@ -50,6 +49,7 @@ #include #include +#include #include #include #include @@ -360,8 +360,8 @@ void TerrainTextureOverlay::RenderAfterWater( const ssize_t w = static_cast(terrain.GetTilesPerSide() * m_TexelsPerTile); const ssize_t h = static_cast(terrain.GetTilesPerSide() * m_TexelsPerTile); - const uint32_t requiredWidth = round_up_to_pow2(w); - const uint32_t requiredHeight = round_up_to_pow2(h); + const uint32_t requiredWidth = std::bit_ceil(static_cast(w)); + const uint32_t requiredHeight = std::bit_ceil(static_cast(h)); // Recreate the texture with new size if necessary if (!m_Texture || m_Texture->GetWidth() != requiredWidth || m_Texture->GetHeight() != requiredHeight) diff --git a/source/renderer/WaterManager.cpp b/source/renderer/WaterManager.cpp index e0a956b8f9..f8c53a1fdb 100644 --- a/source/renderer/WaterManager.cpp +++ b/source/renderer/WaterManager.cpp @@ -25,7 +25,6 @@ #include "graphics/ShaderTechniquePtr.h" #include "graphics/Terrain.h" #include "graphics/TextureManager.h" -#include "lib/bits.h" #include "lib/code_annotation.h" #include "lib/debug.h" #include "lib/path.h" @@ -56,6 +55,7 @@ #include #include +#include #include #include #include @@ -264,7 +264,7 @@ void WaterManager::DestroyViewSizeDependentObjects() void WaterManager::RecreateOrLoadTexturesIfNeeded() { // Use screen-sized textures for minimum artifacts. - const size_t newRefTextureSize = round_up_to_pow2(g_Renderer.GetHeight()); + const size_t newRefTextureSize = std::bit_ceil(static_cast(g_Renderer.GetHeight())); if (m_RefTextureSize != newRefTextureSize) { diff --git a/source/renderer/backend/vulkan/DeviceCommandContext.cpp b/source/renderer/backend/vulkan/DeviceCommandContext.cpp index 6eab401ded..cefbaec771 100644 --- a/source/renderer/backend/vulkan/DeviceCommandContext.cpp +++ b/source/renderer/backend/vulkan/DeviceCommandContext.cpp @@ -20,7 +20,6 @@ #include "DeviceCommandContext.h" #include "graphics/Color.h" -#include "lib/bits.h" #include "lib/debug.h" #include "ps/CLogger.h" #include "ps/ConfigDB.h" @@ -246,7 +245,7 @@ void CDeviceCommandContext::CUploadRing::ResizeIfNeeded( // We need to pad the data size for uniforms because we use dynamic offsets // with a fixed range. const uint32_t paddedDataSize{ - m_Type == IBuffer::Type::UNIFORM ? round_up_to_pow2(dataSize) : dataSize}; + m_Type == IBuffer::Type::UNIFORM ? std::bit_ceil(dataSize) : dataSize}; const bool resizeNeeded = !m_Buffer || m_BlockOffset + paddedDataSize > m_Capacity; if (!resizeNeeded) return; @@ -257,7 +256,7 @@ void CDeviceCommandContext::CUploadRing::ResizeIfNeeded( ExecuteUploads(commandBuffer); } - m_Capacity = std::max(m_Capacity * 2, round_up_to_pow2(dataSize)); + m_Capacity = std::max(m_Capacity * 2, std::bit_ceil(dataSize)); m_Buffer = m_Device->CreateCBuffer( "UploadRingBuffer", m_Type, m_Capacity, IBuffer::Usage::DYNAMIC | IBuffer::Usage::TRANSFER_DST); diff --git a/source/renderer/backend/vulkan/RingCommandContext.cpp b/source/renderer/backend/vulkan/RingCommandContext.cpp index 403f865c8c..e86ee8f105 100644 --- a/source/renderer/backend/vulkan/RingCommandContext.cpp +++ b/source/renderer/backend/vulkan/RingCommandContext.cpp @@ -32,6 +32,7 @@ #include "renderer/backend/vulkan/Utilities.h" #include +#include #include #include #include @@ -374,7 +375,7 @@ uint32_t CRingCommandContext::AcquireFreeSpace( !m_StagingBuffer || m_StagingBuffer->GetSize() < m_MaxStagingBufferCapacity; if (needsResize && canResize) { - const uint32_t minimumRequiredCapacity = round_up_to_pow2(requiredSize); + const uint32_t minimumRequiredCapacity = std::bit_ceil(requiredSize); const uint32_t newCapacity = std::min( std::max(m_StagingBuffer ? m_StagingBuffer->GetSize() * 2 : INITIAL_STAGING_BUFFER_CAPACITY, minimumRequiredCapacity), m_MaxStagingBufferCapacity);