Fixing broken hashmaps on linux

Fixes #414

The issue is caused by Linux (and possibly other platforms) implementing the hash function as an identify function for data smaller than 64bit (including `int`).

Fixing only the TerrainGenerator is possible, but the issue could be generated again elsewhere and it would be quite difficult to identify and debug.

Therefore the proposed solution is to replace the `wi::unordered_map` on Linux with another implementation which is still quite fast and does account for the issue of the identify hash function.
The library is https://github.com/martinus/robin-hood-hashing (MIT License)

robin_hood.h:768
```
// return mixed of that, to be safe against identity hash
```
This commit is contained in:
Matteo De Carlo
2022-08-20 18:54:15 +02:00
committed by Matteo De Carlo
parent 64babc8fcd
commit fdc052b9f9
7 changed files with 2565 additions and 18 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ if (WICKED_TESTS)
add_subdirectory(Tests)
endif()
if (WICKED_TESTS)
if (WICKED_IMGUI_EXAMPLE)
add_subdirectory(Example_ImGui)
add_subdirectory(Example_ImGui_Docking)
endif()
-5
View File
@@ -62,12 +62,7 @@ struct TerrainGenerator : public wi::gui::Window
wi::scene::MaterialComponent material_HighAltitude;
wi::scene::MaterialComponent material_GrassParticle;
wi::HairParticleSystem grass_properties;
#ifdef PLATFORM_LINUX
// TODO: investigate why wi::unordered_map is crashing terrain generator on Linux
std::unordered_map<Chunk, ChunkData> chunks;
#else
wi::unordered_map<Chunk, ChunkData> chunks;
#endif
wi::vector<uint32_t> indices;
struct LOD
{
+4
View File
@@ -229,6 +229,10 @@ if (WIN32)
set(LIBDXCOMPILER "dxcompiler.dll")
else ()
# `ska::flat_hash_map` has issues on linux because of the hash function being identity
# in same cases. Use `robin_hood::unordered_flat_map` instead
target_compile_definitions(${TARGET_NAME} PUBLIC WI_UNORDERED_MAP_TYPE=2)
target_link_libraries(${TARGET_NAME} PUBLIC
Threads::Threads
SDL2::SDL2
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -556,7 +556,7 @@ int main(int argc, char* argv[])
std::string name_repl = name;
std::replace(name_repl.begin(), name_repl.end(), '/', '_');
std::replace(name_repl.begin(), name_repl.end(), '.', '_');
ss += "std::pair<std::string, ShaderDumpEntry>(\"" + name + "\", {" + name_repl + ",sizeof(" + name_repl + ")}),\n";
ss += "{\"" + name + "\", {" + name_repl + ",sizeof(" + name_repl + ")}},\n";
}
ss += "};\n"; // map end
ss += "}\n"; // namespace end
+11 -11
View File
@@ -100,17 +100,17 @@ namespace wi
SOUND,
};
static const wi::unordered_map<std::string, DataType> types = {
std::make_pair("BASIS", DataType::IMAGE),
std::make_pair("KTX2", DataType::IMAGE),
std::make_pair("JPG", DataType::IMAGE),
std::make_pair("JPEG", DataType::IMAGE),
std::make_pair("PNG", DataType::IMAGE),
std::make_pair("BMP", DataType::IMAGE),
std::make_pair("DDS", DataType::IMAGE),
std::make_pair("TGA", DataType::IMAGE),
std::make_pair("QOI", DataType::IMAGE),
std::make_pair("WAV", DataType::SOUND),
std::make_pair("OGG", DataType::SOUND),
{"BASIS", DataType::IMAGE},
{"KTX2", DataType::IMAGE},
{"JPG", DataType::IMAGE},
{"JPEG", DataType::IMAGE},
{"PNG", DataType::IMAGE},
{"BMP", DataType::IMAGE},
{"DDS", DataType::IMAGE},
{"TGA", DataType::IMAGE},
{"QOI", DataType::IMAGE},
{"WAV", DataType::SOUND},
{"OGG", DataType::SOUND},
};
wi::vector<std::string> GetSupportedImageExtensions()
{
+4
View File
@@ -8,6 +8,8 @@
#if WI_UNORDERED_MAP_TYPE == 1
#include "Utility/flat_hash_map.hpp"
#elif WI_UNORDERED_MAP_TYPE == 2
#include "Utility/robin_hood.h"
#else
#include <unordered_map>
#endif // WI_UNORDERED_MAP_TYPE
@@ -17,6 +19,8 @@ namespace wi
template<typename K, typename V, typename H = std::hash<K>, typename E = std::equal_to<K>, typename A = std::allocator<std::pair<const K, V> > >
#if WI_UNORDERED_MAP_TYPE == 1
using unordered_map = ska::flat_hash_map<K, V, H, E, A>;
#elif WI_UNORDERED_MAP_TYPE == 2
using unordered_map = robin_hood::unordered_flat_map<K, V, H, E>;
#else
using unordered_map = std::unordered_map<K, V, H, E, A>;
#endif // WI_UNORDERED_MAP_TYPE