From 326dc95f9c7ab7adf6ee63f4221b64b4002b6bed Mon Sep 17 00:00:00 2001 From: Teselka <53512153+Teselka@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:10:36 +0200 Subject: [PATCH] Misc: use native crc32 instructions on SEE 4.2 targets. (#8169, #4933) --- docs/CHANGELOG.txt | 1 + imgui.cpp | 18 ++++++++++++++++++ imgui_internal.h | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e901e437e..b93888c85 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,6 +62,7 @@ Other changes: - Tools: binary_to_compressed_c: added -u8/-u32/-base85 export options. - Demo: example tree used by Property Editor & Selection demos properly freed on application closure. (#8158) [@Legulysse] +- Misc: use SSE 4.2 crc32 instructions when available. (#8169, #4933) [@Teselka] - Backends: Vulkan: Make user-provided descriptor pool optional. As a convenience, when setting init_info->DescriptorPoolSize then the backend will create and manage one itself. (#8172, #4867) [@zeux] diff --git a/imgui.cpp b/imgui.cpp index 072c09799..ff5d25408 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2150,6 +2150,7 @@ void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, } } +#ifndef IMGUI_ENABLE_SSE4_2 // CRC32 needs a 1KB lookup table (not cache friendly) // Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily: // - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe. @@ -2173,6 +2174,7 @@ static const ImU32 GCrc32LookupTable[256] = 0xE330A81A,0x115B2B19,0x020BD8ED,0xF0605BEE,0x24AA3F05,0xD6C1BC06,0xC5914FF2,0x37FACCF1,0x69E9F0D5,0x9B8273D6,0x88D28022,0x7AB90321,0xAE7367CA,0x5C18E4C9,0x4F48173D,0xBD23943E, 0xF36E6F75,0x0105EC76,0x12551F82,0xE03E9C81,0x34F4F86A,0xC69F7B69,0xD5CF889D,0x27A40B9E,0x79B737BA,0x8BDCB4B9,0x988C474D,0x6AE7C44E,0xBE2DA0A5,0x4C4623A6,0x5F16D052,0xAD7D5351 }; +#endif // Known size hash // It is ok to call ImHashData on a string with known length but the ### operator won't be supported. @@ -2181,10 +2183,16 @@ ImGuiID ImHashData(const void* data_p, size_t data_size, ImGuiID seed) { ImU32 crc = ~seed; const unsigned char* data = (const unsigned char*)data_p; +#ifndef IMGUI_ENABLE_SSE4_2 const ImU32* crc32_lut = GCrc32LookupTable; while (data_size-- != 0) crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++]; return ~crc; +#else + while (data_size-- != 0) + crc = _mm_crc32_u8(crc, *data++); + return ~crc; +#endif } // Zero-terminated string hash, with support for ### to reset back to seed value @@ -2198,7 +2206,9 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) seed = ~seed; ImU32 crc = seed; const unsigned char* data = (const unsigned char*)data_p; +#ifndef IMGUI_ENABLE_SSE4_2 const ImU32* crc32_lut = GCrc32LookupTable; +#endif if (data_size != 0) { while (data_size-- != 0) @@ -2206,7 +2216,11 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) unsigned char c = *data++; if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#') crc = seed; +#ifndef IMGUI_ENABLE_SSE4_2 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; +#else + crc = _mm_crc32_u8(crc, c); +#endif } } else @@ -2215,7 +2229,11 @@ ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) { if (c == '#' && data[0] == '#' && data[1] == '#') crc = seed; +#ifndef IMGUI_ENABLE_SSE4_2 crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; +#else + crc = _mm_crc32_u8(crc, c); +#endif } } return ~crc; diff --git a/imgui_internal.h b/imgui_internal.h index 40cf3c0c3..fd8a185a5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -61,6 +61,10 @@ Index of this file: #if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) #define IMGUI_ENABLE_SSE #include +#if (defined __AVX__ || defined __SSE4_2__) +#define IMGUI_ENABLE_SSE4_2 +#include +#endif #endif // Visual Studio warnings