diff options
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/client.cpp | 3 | ||||
-rw-r--r-- | src/dyetool/client.cpp | 3 | ||||
-rw-r--r-- | src/maingui.cpp | 4 | ||||
-rw-r--r-- | src/resources/dye/dye_unittest.cc | 245 | ||||
-rw-r--r-- | src/resources/dye/dyepalette.cpp | 33 | ||||
-rw-r--r-- | src/resources/dye/dyepalette.h | 55 | ||||
-rw-r--r-- | src/resources/dye/dyepalette_replacescolor.cpp | 277 | ||||
-rw-r--r-- | src/resources/dye/dyepalette_replacescolor_avx2.hpp | 95 | ||||
-rw-r--r-- | src/resources/dye/dyepalette_replacescolor_default.hpp | 105 | ||||
-rw-r--r-- | src/resources/dye/dyepalette_replacescolor_sse2.hpp | 95 | ||||
-rw-r--r-- | src/resources/dye/dyepaletteptr.h | 31 | ||||
-rw-r--r-- | src/resources/imagehelper.cpp | 2 | ||||
-rw-r--r-- | src/resources/sdlimagehelper.cpp | 2 | ||||
-rw-r--r-- | src/test/testlauncher.cpp | 6 | ||||
-rw-r--r-- | src/utils/cpu.cpp | 18 | ||||
-rw-r--r-- | src/utils/cpu.h | 2 |
18 files changed, 378 insertions, 606 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f6c5f58a..7fe0b9445 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -649,13 +649,11 @@ SET(SRCS resources/dye/dyepalette_replaceaoglcolor_default.hpp resources/dye/dyepalette_replaceaoglcolor_sse2.hpp resources/dye/dyepalette_replacescolor.cpp - resources/dye/dyepalette_replacescolor_avx2.hpp - resources/dye/dyepalette_replacescolor_default.hpp - resources/dye/dyepalette_replacescolor_sse2.hpp resources/dye/dyepalette_replacesoglcolor.cpp resources/dye/dyepalette_replacesoglcolor_avx2.hpp resources/dye/dyepalette_replacesoglcolor_default.hpp resources/dye/dyepalette_replacesoglcolor_sse2.hpp + resources/dye/dyepaletteptr.h resources/effectdescription.h resources/emoteinfo.h resources/emotesprite.h diff --git a/src/Makefile.am b/src/Makefile.am index 87b7c7101..13206a9ae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -433,13 +433,11 @@ BASE_SRC += events/actionevent.h \ resources/dye/dyepalette_replaceaoglcolor_default.hpp \ resources/dye/dyepalette_replaceaoglcolor_sse2.hpp \ resources/dye/dyepalette_replacescolor.cpp \ - resources/dye/dyepalette_replacescolor_avx2.hpp \ - resources/dye/dyepalette_replacescolor_default.hpp \ - resources/dye/dyepalette_replacescolor_sse2.hpp \ resources/dye/dyepalette_replacesoglcolor.cpp \ resources/dye/dyepalette_replacesoglcolor_avx2.hpp \ resources/dye/dyepalette_replacesoglcolor_default.hpp \ resources/dye/dyepalette_replacesoglcolor_sse2.hpp \ + resources/dye/dyepaletteptr.h \ resources/fboinfo.h \ resources/frame.h \ resources/image/image.cpp \ diff --git a/src/client.cpp b/src/client.cpp index 0dd0b7326..c36f96e2b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -134,6 +134,8 @@ #include "resources/db/unitsdb.h" #include "resources/db/weaponsdb.h" +#include "resources/dye/dyepalette.h" + #include "resources/resourcemanager/resourcemanager.h" #include "resources/sprite/spritereference.h" @@ -401,6 +403,7 @@ void Client::gameInit() ConfigManager::checkConfigVersion(); logVars(); Cpu::detect(); + DyePalette::initFunctions(); #if defined(USE_OPENGL) #if !defined(ANDROID) && !defined(__APPLE__) && \ !defined(__native_client__) && !defined(UNITTESTS) diff --git a/src/dyetool/client.cpp b/src/dyetool/client.cpp index b7ac6ac4b..0677e2b19 100644 --- a/src/dyetool/client.cpp +++ b/src/dyetool/client.cpp @@ -53,6 +53,8 @@ #include "resources/imagehelper.h" +#include "resources/dye/dyepalette.h" + #include "resources/resourcemanager/resourcemanager.h" #include "utils/cpu.h" @@ -249,6 +251,7 @@ void Client::gameInit() ConfigManager::checkConfigVersion(); logVars(); Cpu::detect(); + DyePalette::initFunctions(); #if defined(USE_OPENGL) #if !defined(ANDROID) && !defined(__APPLE__) && !defined(__native_client__) if (!settings.options.safeMode && settings.options.test.empty() diff --git a/src/maingui.cpp b/src/maingui.cpp index 2513a9211..4561fd427 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -49,6 +49,8 @@ #endif // SDL_VERSIONNUM #ifdef UNITTESTS +#include "utils/cpu.h" +#include "resources/dye/dyepalette.h" #ifdef UNITTESTS_CATCH #define CATCH_CONFIG_RUNNER #include "test/catch.hpp" @@ -146,6 +148,8 @@ int mainGui(int argc, char *argv[]) int main(int argc, char *argv[]) { VirtFs::init(argv[0]); + Cpu::detect(); + DyePalette::initFunctions(); #ifdef UNITTESTS_CATCH return Catch::Session().run(argc, argv); #elif defined(UNITTESTS_DOCTEST) diff --git a/src/resources/dye/dye_unittest.cc b/src/resources/dye/dye_unittest.cc index 0c0e26eb7..5d2cfdb8d 100644 --- a/src/resources/dye/dye_unittest.cc +++ b/src/resources/dye/dye_unittest.cc @@ -514,7 +514,7 @@ TEST_CASE("Dye replaceSColor 1 1", "") DyePalette palette("#00ff00,000011", 6); uint32_t data[1]; data[0] = buildHex(0x10, 0x03, 0x02, 0x01); - palette.replaceSColor(&data[0], 1); + DYEPALETTE(palette, SColor)(&data[0], 1); REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01)); } @@ -523,7 +523,7 @@ TEST_CASE("Dye replaceSColor 1 2", "") DyePalette palette("#403020,706050", 6); uint32_t data[1]; data[0] = buildHex(0x40, 0x30, 0x20, 0x10); - palette.replaceSColor(&data[0], 1); + DYEPALETTE(palette, SColor)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -532,7 +532,7 @@ TEST_CASE("Dye replaceSColor 1 3", "") DyePalette palette("#123456,000000,ff3020,706050", 6); uint32_t data[1]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - palette.replaceSColor(&data[0], 1); + DYEPALETTE(palette, SColor)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -542,7 +542,7 @@ TEST_CASE("Dye replaceSColor 2 1", "") uint32_t data[2]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColor(&data[0], 2); + DYEPALETTE(palette, SColor)(&data[0], 2); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); } @@ -554,7 +554,7 @@ TEST_CASE("Dye replaceSColor 3 1", "") data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x30, 0x20, 0x30); - palette.replaceSColor(&data[0], 3); + DYEPALETTE(palette, SColor)(&data[0], 3); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30)); @@ -568,7 +568,7 @@ TEST_CASE("Dye replaceSColor 4 1", "") data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColor(&data[0], 4); + DYEPALETTE(palette, SColor)(&data[0], 4); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -584,7 +584,7 @@ TEST_CASE("Dye replaceSColor 5 1", "") data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x30); data[4] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColor(&data[0], 5); + DYEPALETTE(palette, SColor)(&data[0], 5); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -603,7 +603,7 @@ TEST_CASE("Dye replaceSColor 7 1", "") data[4] = buildHex(0xff, 0x30, 0x20, 0x10); data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - palette.replaceSColor(&data[0], 7); + DYEPALETTE(palette, SColor)(&data[0], 7); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -625,7 +625,7 @@ TEST_CASE("Dye replaceSColor 8 1", "") data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - palette.replaceSColor(&data[0], 8); + DYEPALETTE(palette, SColor)(&data[0], 8); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -649,7 +649,7 @@ TEST_CASE("Dye replaceSColor 9 1", "") data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0xff, 0x30, 0x20, 0x70); - palette.replaceSColor(&data[0], 9); + DYEPALETTE(palette, SColor)(&data[0], 9); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -675,7 +675,7 @@ TEST_CASE("Dye replaceSColor 10 1", "") data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0x12, 0x34, 0x56, 0x70); data[9] = buildHex(0xff, 0x30, 0x20, 0x80); - palette.replaceSColor(&data[0], 10); + DYEPALETTE(palette, SColor)(&data[0], 10); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -867,191 +867,12 @@ TEST_CASE("Dye replaceSColor 10 1 default", "") REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80)); } -TEST_CASE("Dye replaceSColor 1 1 simd", "") -{ - DyePalette palette("#00ff00,000011", 6); - uint32_t data[1]; - data[0] = buildHex(0x10, 0x03, 0x02, 0x01); - palette.replaceSColorSimd(&data[0], 1); - REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01)); -} - -TEST_CASE("Dye replaceSColor 1 2 simd", "") -{ - DyePalette palette("#403020,706050", 6); - uint32_t data[1]; - data[0] = buildHex(0x40, 0x30, 0x20, 0x10); - palette.replaceSColorSimd(&data[0], 1); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); -} - -TEST_CASE("Dye replaceSColor 1 3 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[1]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - palette.replaceSColorSimd(&data[0], 1); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); -} - -TEST_CASE("Dye replaceSColor 2 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[2]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSimd(&data[0], 2); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); -} - -TEST_CASE("Dye replaceSColor 3 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[3]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x30, 0x20, 0x30); - palette.replaceSColorSimd(&data[0], 3); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30)); -} - -TEST_CASE("Dye replaceSColor 4 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[4]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSimd(&data[0], 4); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20)); -} - -TEST_CASE("Dye replaceSColor 5 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[5]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x30); - data[4] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSimd(&data[0], 5); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x30)); - REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x20)); -} - -TEST_CASE("Dye replaceSColor 7 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[7]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - data[4] = buildHex(0xff, 0x30, 0x20, 0x10); - data[5] = buildHex(0xff, 0x30, 0x20, 0x40); - data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - palette.replaceSColorSimd(&data[0], 7); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40)); - REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50)); -} - -TEST_CASE("Dye replaceSColor 8 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[8]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - data[4] = buildHex(0xff, 0x30, 0x20, 0x10); - data[5] = buildHex(0xff, 0x30, 0x20, 0x40); - data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - palette.replaceSColorSimd(&data[0], 8); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40)); - REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50)); - REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60)); -} - -TEST_CASE("Dye replaceSColor 9 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[9]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - data[4] = buildHex(0xff, 0x30, 0x20, 0x10); - data[5] = buildHex(0xff, 0x30, 0x20, 0x40); - data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - data[8] = buildHex(0xff, 0x30, 0x20, 0x70); - palette.replaceSColorSimd(&data[0], 9); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40)); - REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50)); - REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60)); - REQUIRE(data[8] == buildHex(0x70, 0x60, 0x50, 0x70)); -} - -TEST_CASE("Dye replaceSColor 10 1 simd", "") -{ - DyePalette palette("#123456,000000,ff3020,706050", 6); - uint32_t data[10]; - data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - data[2] = buildHex(0xff, 0x40, 0x20, 0x10); - data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - data[4] = buildHex(0xff, 0x30, 0x20, 0x10); - data[5] = buildHex(0xff, 0x30, 0x20, 0x40); - data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - data[8] = buildHex(0x12, 0x34, 0x56, 0x70); - data[9] = buildHex(0xff, 0x30, 0x20, 0x80); - palette.replaceSColorSimd(&data[0], 10); - REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); - REQUIRE(data[3] == buildHex(0x70, 0x60, 0x50, 0x20)); - REQUIRE(data[4] == buildHex(0x70, 0x60, 0x50, 0x10)); - REQUIRE(data[5] == buildHex(0x70, 0x60, 0x50, 0x40)); - REQUIRE(data[6] == buildHex(0xff, 0x40, 0x20, 0x50)); - REQUIRE(data[7] == buildHex(0x70, 0x60, 0x50, 0x60)); - REQUIRE(data[8] == buildHex(0x00, 0x00, 0x00, 0x70)); - REQUIRE(data[9] == buildHex(0x70, 0x60, 0x50, 0x80)); -} - TEST_CASE("Dye replaceSColor 1 1 sse2", "") { DyePalette palette("#00ff00,000011", 6); uint32_t data[1]; data[0] = buildHex(0x10, 0x03, 0x02, 0x01); - palette.replaceSColorSse2(&data[0], 1); + DYEPALETTE(palette, SColorSse2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01)); } @@ -1060,7 +881,7 @@ TEST_CASE("Dye replaceSColor 1 2 sse2", "") DyePalette palette("#403020,706050", 6); uint32_t data[1]; data[0] = buildHex(0x40, 0x30, 0x20, 0x10); - palette.replaceSColorSse2(&data[0], 1); + DYEPALETTE(palette, SColorSse2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -1069,7 +890,7 @@ TEST_CASE("Dye replaceSColor 1 3 sse2", "") DyePalette palette("#123456,000000,ff3020,706050", 6); uint32_t data[1]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - palette.replaceSColorSse2(&data[0], 1); + DYEPALETTE(palette, SColorSse2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -1079,7 +900,7 @@ TEST_CASE("Dye replaceSColor 2 1 sse2", "") uint32_t data[2]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSse2(&data[0], 2); + DYEPALETTE(palette, SColorSse2)(&data[0], 2); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); } @@ -1091,7 +912,7 @@ TEST_CASE("Dye replaceSColor 3 1 sse2", "") data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x30, 0x20, 0x30); - palette.replaceSColorSse2(&data[0], 3); + DYEPALETTE(palette, SColorSse2)(&data[0], 3); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30)); @@ -1105,7 +926,7 @@ TEST_CASE("Dye replaceSColor 4 1 sse2", "") data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSse2(&data[0], 4); + DYEPALETTE(palette, SColorSse2)(&data[0], 4); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1121,7 +942,7 @@ TEST_CASE("Dye replaceSColor 5 1 sse2", "") data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x30); data[4] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorSse2(&data[0], 5); + DYEPALETTE(palette, SColorSse2)(&data[0], 5); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1140,7 +961,7 @@ TEST_CASE("Dye replaceSColor 7 1 sse2", "") data[4] = buildHex(0xff, 0x30, 0x20, 0x10); data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - palette.replaceSColorSse2(&data[0], 7); + DYEPALETTE(palette, SColorSse2)(&data[0], 7); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1162,7 +983,7 @@ TEST_CASE("Dye replaceSColor 8 1 sse2", "") data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - palette.replaceSColorSse2(&data[0], 8); + DYEPALETTE(palette, SColorSse2)(&data[0], 8); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1186,7 +1007,7 @@ TEST_CASE("Dye replaceSColor 9 1 sse2", "") data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0xff, 0x30, 0x20, 0x70); - palette.replaceSColorSse2(&data[0], 9); + DYEPALETTE(palette, SColorSse2)(&data[0], 9); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1212,7 +1033,7 @@ TEST_CASE("Dye replaceSColor 10 1 sse2", "") data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0x12, 0x34, 0x56, 0x70); data[9] = buildHex(0xff, 0x30, 0x20, 0x80); - palette.replaceSColorSse2(&data[0], 10); + DYEPALETTE(palette, SColorSse2)(&data[0], 10); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1230,7 +1051,7 @@ TEST_CASE("Dye replaceSColor 1 1 avx2", "") DyePalette palette("#00ff00,000011", 6); uint32_t data[1]; data[0] = buildHex(0x10, 0x03, 0x02, 0x01); - palette.replaceSColorAvx2(&data[0], 1); + DYEPALETTE(palette, SColorAvx2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x10, 0x03, 0x02, 0x01)); } @@ -1239,7 +1060,7 @@ TEST_CASE("Dye replaceSColor 1 2 avx2", "") DyePalette palette("#403020,706050", 6); uint32_t data[1]; data[0] = buildHex(0x40, 0x30, 0x20, 0x10); - palette.replaceSColorAvx2(&data[0], 1); + DYEPALETTE(palette, SColorAvx2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -1248,7 +1069,7 @@ TEST_CASE("Dye replaceSColor 1 3 avx2", "") DyePalette palette("#123456,000000,ff3020,706050", 6); uint32_t data[1]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); - palette.replaceSColorAvx2(&data[0], 1); + DYEPALETTE(palette, SColorAvx2)(&data[0], 1); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); } @@ -1258,7 +1079,7 @@ TEST_CASE("Dye replaceSColor 2 1 avx2", "") uint32_t data[2]; data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorAvx2(&data[0], 2); + DYEPALETTE(palette, SColorAvx2)(&data[0], 2); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); } @@ -1270,7 +1091,7 @@ TEST_CASE("Dye replaceSColor 3 1 avx2", "") data[0] = buildHex(0xff, 0x30, 0x20, 0x10); data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x30, 0x20, 0x30); - palette.replaceSColorAvx2(&data[0], 3); + DYEPALETTE(palette, SColorAvx2)(&data[0], 3); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0x70, 0x60, 0x50, 0x30)); @@ -1284,7 +1105,7 @@ TEST_CASE("Dye replaceSColor 4 1 avx2", "") data[1] = buildHex(0xff, 0x30, 0x20, 0x20); data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorAvx2(&data[0], 4); + DYEPALETTE(palette, SColorAvx2)(&data[0], 4); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1300,7 +1121,7 @@ TEST_CASE("Dye replaceSColor 5 1 avx2", "") data[2] = buildHex(0xff, 0x40, 0x20, 0x10); data[3] = buildHex(0xff, 0x30, 0x20, 0x30); data[4] = buildHex(0xff, 0x30, 0x20, 0x20); - palette.replaceSColorAvx2(&data[0], 5); + DYEPALETTE(palette, SColorAvx2)(&data[0], 5); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1319,7 +1140,7 @@ TEST_CASE("Dye replaceSColor 7 1 avx2", "") data[4] = buildHex(0xff, 0x30, 0x20, 0x10); data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); - palette.replaceSColorAvx2(&data[0], 7); + DYEPALETTE(palette, SColorAvx2)(&data[0], 7); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1341,7 +1162,7 @@ TEST_CASE("Dye replaceSColor 8 1 avx2", "") data[5] = buildHex(0xff, 0x30, 0x20, 0x40); data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); - palette.replaceSColorAvx2(&data[0], 8); + DYEPALETTE(palette, SColorAvx2)(&data[0], 8); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1365,7 +1186,7 @@ TEST_CASE("Dye replaceSColor 9 1 avx2", "") data[6] = buildHex(0xff, 0x40, 0x20, 0x50); data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0xff, 0x30, 0x20, 0x70); - palette.replaceSColorAvx2(&data[0], 9); + DYEPALETTE(palette, SColorAvx2)(&data[0], 9); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); @@ -1391,7 +1212,7 @@ TEST_CASE("Dye replaceSColor 10 1 avx2", "") data[7] = buildHex(0xff, 0x30, 0x20, 0x60); data[8] = buildHex(0x12, 0x34, 0x56, 0x70); data[9] = buildHex(0xff, 0x30, 0x20, 0x80); - palette.replaceSColorAvx2(&data[0], 10); + DYEPALETTE(palette, SColorAvx2)(&data[0], 10); REQUIRE(data[0] == buildHex(0x70, 0x60, 0x50, 0x10)); REQUIRE(data[1] == buildHex(0x70, 0x60, 0x50, 0x20)); REQUIRE(data[2] == buildHex(0xff, 0x40, 0x20, 0x10)); diff --git a/src/resources/dye/dyepalette.cpp b/src/resources/dye/dyepalette.cpp index dfe6e95a2..5a350c8e2 100644 --- a/src/resources/dye/dyepalette.cpp +++ b/src/resources/dye/dyepalette.cpp @@ -38,8 +38,16 @@ #include <SDL_endian.h> #endif // SDL_BYTEORDER +#ifdef SIMD_SUPPORTED +#include "utils/cpu.h" +#endif // SIMD_SUPPORTED + #include "debug.h" +DyeFunctionPtr DyePalette::funcReplaceSColor = nullptr; +DyeFunctionPtr DyePalette::funcReplaceSColorSse2 = nullptr; +DyeFunctionPtr DyePalette::funcReplaceSColorAvx2 = nullptr; + DyePalette::DyePalette(const std::string &restrict description, const uint8_t blockSize) : mColors() @@ -224,3 +232,28 @@ void DyePalette::getColor(double intensity, color[2] = CAST_S32(rest * colorI.value[2] + intensity * colorJ.value[2]); } + +void DyePalette::initFunctions() +{ +#ifdef SIMD_SUPPORTED + const uint32_t flags = Cpu::getFlags(); + if (flags & Cpu::FEATURE_AVX2) + { + funcReplaceSColor = &DyePalette::replaceSColorAvx2; + funcReplaceSColorAvx2 = &DyePalette::replaceSColorAvx2; + funcReplaceSColorSse2 = &DyePalette::replaceSColorSse2; + } + else if (flags & Cpu::FEATURE_SSE2) + { + funcReplaceSColor = &DyePalette::replaceSColorSse2; + funcReplaceSColorAvx2 = &DyePalette::replaceSColorSse2; + funcReplaceSColorSse2 = &DyePalette::replaceSColorSse2; + } + else +#endif // SIMD_SUPPORTED + { + funcReplaceSColor = &DyePalette::replaceSColorDefault; + funcReplaceSColorAvx2 = &DyePalette::replaceSColorDefault; + funcReplaceSColorSse2 = &DyePalette::replaceSColorDefault; + } +} diff --git a/src/resources/dye/dyepalette.h b/src/resources/dye/dyepalette.h index d869e39c6..da165305e 100644 --- a/src/resources/dye/dyepalette.h +++ b/src/resources/dye/dyepalette.h @@ -25,11 +25,19 @@ #include "resources/dye/dyecolor.h" +#include "resources/dye/dyepaletteptr.h" + #include <string> #include <vector> #include "localconsts.h" +#define DYEPALETTE(palette, color) \ + ((palette).*DyePalette::funcReplace##color) + +#define DYEPALETTEP(palette, color) \ + ((palette)->*DyePalette::funcReplace##color) + /** * Class for performing a linear interpolation between colors. */ @@ -62,55 +70,14 @@ class DyePalette final /** * replace colors for SDL for S dye. */ - void replaceSColor(uint32_t *restrict pixels, - const int bufSize) const restrict2; - - /** - * replace colors for SDL for S dye. - */ void replaceSColorDefault(uint32_t *restrict pixels, const int bufSize) const restrict2; - /** - * replace colors for SDL for S dye. - */ - FUNCTION_SIMD_DEFAULT - void replaceSColorSimd(uint32_t *restrict pixels, - const int bufSize) const restrict2; - - /** - * replace colors for SDL for S dye. - */ - FUNCTION_SIMD_DEFAULT - void replaceSColorSse2(uint32_t *restrict pixels, - const int bufSize) const restrict2; - - /** - * replace colors for SDL for S dye. - */ - FUNCTION_SIMD_DEFAULT - void replaceSColorAvx2(uint32_t *restrict pixels, - const int bufSize) const restrict2; - #ifdef SIMD_SUPPORTED /** * replace colors for SDL for S dye. */ __attribute__ ((target ("sse2"))) - void replaceSColorSimd(uint32_t *restrict pixels, - const int bufSize) const restrict2; - - /** - * replace colors for SDL for S dye. - */ - __attribute__ ((target ("avx2"))) - void replaceSColorSimd(uint32_t *restrict pixels, - const int bufSize) const restrict2; - - /** - * replace colors for SDL for S dye. - */ - __attribute__ ((target ("sse2"))) void replaceSColorSse2(uint32_t *restrict pixels, const int bufSize) const restrict2; @@ -313,6 +280,12 @@ class DyePalette final const uint8_t blockSize, DyeColor &color) noexcept2; + static void initFunctions(); + + static DyeFunctionPtr funcReplaceSColor; + static DyeFunctionPtr funcReplaceSColorSse2; + static DyeFunctionPtr funcReplaceSColorAvx2; + #ifndef UNITTESTS private: #endif // UNITTESTS diff --git a/src/resources/dye/dyepalette_replacescolor.cpp b/src/resources/dye/dyepalette_replacescolor.cpp index 89f58b855..3f14adb74 100644 --- a/src/resources/dye/dyepalette_replacescolor.cpp +++ b/src/resources/dye/dyepalette_replacescolor.cpp @@ -33,20 +33,94 @@ #include "debug.h" -void DyePalette::replaceSColor(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#ifdef SIMD_SUPPORTED - replaceSColorSimd(pixels, bufSize); -#else // SIMD_SUPPORTED -#include "resources/dye/dyepalette_replacescolor_default.hpp" -#endif // SIMD_SUPPORTED -} - void DyePalette::replaceSColorDefault(uint32_t *restrict pixels, const int bufSize) const restrict2 { -#include "resources/dye/dyepalette_replacescolor_default.hpp" + std::vector<DyeColor>::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + +#ifdef ENABLE_CILKPLUS + cilk_for (int ptr = 0; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int data = pixels[ptr] & 0x00ffffff; +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int data = pixels[ptr] & 0xffffff00; +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + ++ it; + } + } +#else // ENABLE_CILKPLUS + + for (const uint32_t *const p_end = pixels + CAST_SIZE(bufSize); + pixels != p_end; + ++ pixels) + { + uint8_t *const p = reinterpret_cast<uint8_t *>(pixels); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int data = (*pixels) & 0x00ffffff; +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int data = (*pixels) & 0xffffff00; +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + + ++ it; + } + } +#endif // ENABLE_CILKPLUS } #ifdef SIMD_SUPPORTED @@ -59,52 +133,165 @@ static void print256(const char *const text, const __m256i &val) */ __attribute__ ((target ("sse2"))) -void DyePalette::replaceSColorSimd(uint32_t *restrict pixels, +void DyePalette::replaceSColorSse2(uint32_t *restrict pixels, const int bufSize) const restrict2 { -#include "resources/dye/dyepalette_replacescolor_sse2.hpp" -} + std::vector<DyeColor>::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + const int mod = bufSize % 8; + const int bufEnd = bufSize - mod; -__attribute__ ((target ("avx2"))) -void DyePalette::replaceSColorSimd(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#include "resources/dye/dyepalette_replacescolor_avx2.hpp" -} + for (int ptr = 0; ptr < bufEnd; ptr += 4) + { + __m128i mask = _mm_set1_epi32(0xffffff00); +// __m128i base = _mm_load_si128(reinterpret_cast<__m128i*>(pixels)); + __m128i base = _mm_loadu_si128(reinterpret_cast<__m128i*>( + &pixels[ptr])); -__attribute__ ((target ("sse2"))) -void DyePalette::replaceSColorSse2(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#include "resources/dye/dyepalette_replacescolor_sse2.hpp" + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + + __m128i base2 = _mm_and_si128(mask, base); + __m128i newMask = _mm_set1_epi32(col2.valueS); + __m128i cmpMask = _mm_set1_epi32(col.valueS); + __m128i cmpRes = _mm_cmpeq_epi32(base2, cmpMask); + cmpRes = _mm_and_si128(mask, cmpRes); + __m128i srcAnd = _mm_andnot_si128(cmpRes, base); + __m128i dstAnd = _mm_and_si128(cmpRes, newMask); + base = _mm_or_si128(srcAnd, dstAnd); + ++ it; + } +// _mm_store_si128(reinterpret_cast<__m128i*>(pixels), base); + _mm_storeu_si128(reinterpret_cast<__m128i*>(&pixels[ptr]), base); + } + + // complete end without simd + for (int ptr = bufSize - mod; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int data = pixels[ptr] & 0x00ffffff; +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int data = pixels[ptr] & 0xffffff00; +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + + ++ it; + } + } } __attribute__ ((target ("avx2"))) void DyePalette::replaceSColorAvx2(uint32_t *restrict pixels, const int bufSize) const restrict2 { -#include "resources/dye/dyepalette_replacescolor_avx2.hpp" -} + std::vector<DyeColor>::const_iterator it_end = mColors.end(); + const size_t sz = mColors.size(); + if (!sz || !pixels) + return; + if (sz % 2) + -- it_end; + const int mod = bufSize % 8; + const int bufEnd = bufSize - mod; -#endif // SIMD_SUPPORTED + for (int ptr = 0; ptr < bufEnd; ptr += 8) + { + __m256i mask = _mm256_set1_epi32(0xffffff00); +// __m256i base = _mm256_load_si256(reinterpret_cast<__m256i*>(pixels)); + __m256i base = _mm256_loadu_si256(reinterpret_cast<__m256i*>( + &pixels[ptr])); -FUNCTION_SIMD_DEFAULT -void DyePalette::replaceSColorSimd(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#include "resources/dye/dyepalette_replacescolor_default.hpp" -} + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; -FUNCTION_SIMD_DEFAULT -void DyePalette::replaceSColorSse2(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#include "resources/dye/dyepalette_replacescolor_default.hpp" -} + __m256i base2 = _mm256_and_si256(mask, base); + __m256i newMask = _mm256_set1_epi32(col2.valueS); + __m256i cmpMask = _mm256_set1_epi32(col.valueS); + __m256i cmpRes = _mm256_cmpeq_epi32(base2, cmpMask); + cmpRes = _mm256_and_si256(mask, cmpRes); + __m256i srcAnd = _mm256_andnot_si256(cmpRes, base); + __m256i dstAnd = _mm256_and_si256(cmpRes, newMask); + base = _mm256_or_si256(srcAnd, dstAnd); + ++ it; + } +// _mm256_store_si256(reinterpret_cast<__m256i*>(pixels), base); + _mm256_storeu_si256(reinterpret_cast<__m256i*>(&pixels[ptr]), base); + } -FUNCTION_SIMD_DEFAULT -void DyePalette::replaceSColorAvx2(uint32_t *restrict pixels, - const int bufSize) const restrict2 -{ -#include "resources/dye/dyepalette_replacescolor_default.hpp" + // complete end without simd + for (int ptr = bufSize - mod; ptr < bufSize; ptr ++) + { + uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int data = pixels[ptr] & 0x00ffffff; +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int data = pixels[ptr] & 0xffffff00; +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + std::vector<DyeColor>::const_iterator it = mColors.begin(); + while (it != it_end) + { + const DyeColor &col = *it; + ++ it; + const DyeColor &col2 = *it; + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + const unsigned int coldata = (col.value[2] << 16U) + | (col.value[1] << 8U) | (col.value[0]); +#else // SDL_BYTEORDER == SDL_BIG_ENDIAN + + const unsigned int coldata = (col.value[2] << 8U) + | (col.value[1] << 16U) | (col.value[0] << 24U); +#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN + + if (data == coldata) + { + p[3] = col2.value[0]; + p[2] = col2.value[1]; + p[1] = col2.value[2]; + break; + } + + ++ it; + } + } } + +#endif // SIMD_SUPPORTED diff --git a/src/resources/dye/dyepalette_replacescolor_avx2.hpp b/src/resources/dye/dyepalette_replacescolor_avx2.hpp deleted file mode 100644 index 632bf2ca5..000000000 --- a/src/resources/dye/dyepalette_replacescolor_avx2.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - std::vector<DyeColor>::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - const int mod = bufSize % 8; - const int bufEnd = bufSize - mod; - - for (int ptr = 0; ptr < bufEnd; ptr += 8) - { - __m256i mask = _mm256_set1_epi32(0xffffff00); -// __m256i base = _mm256_load_si256(reinterpret_cast<__m256i*>(pixels)); - __m256i base = _mm256_loadu_si256(reinterpret_cast<__m256i*>( - &pixels[ptr])); - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - - __m256i base2 = _mm256_and_si256(mask, base); - __m256i newMask = _mm256_set1_epi32(col2.valueS); - __m256i cmpMask = _mm256_set1_epi32(col.valueS); - __m256i cmpRes = _mm256_cmpeq_epi32(base2, cmpMask); - cmpRes = _mm256_and_si256(mask, cmpRes); - __m256i srcAnd = _mm256_andnot_si256(cmpRes, base); - __m256i dstAnd = _mm256_and_si256(cmpRes, newMask); - base = _mm256_or_si256(srcAnd, dstAnd); - ++ it; - } -// _mm256_store_si256(reinterpret_cast<__m256i*>(pixels), base); - _mm256_storeu_si256(reinterpret_cast<__m256i*>(&pixels[ptr]), base); - } - - // complete end without simd - for (int ptr = bufSize - mod; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int data = pixels[ptr] & 0x00ffffff; -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int data = pixels[ptr] & 0xffffff00; -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - - ++ it; - } - } diff --git a/src/resources/dye/dyepalette_replacescolor_default.hpp b/src/resources/dye/dyepalette_replacescolor_default.hpp deleted file mode 100644 index 43c6cc0d1..000000000 --- a/src/resources/dye/dyepalette_replacescolor_default.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - std::vector<DyeColor>::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - -#ifdef ENABLE_CILKPLUS - cilk_for (int ptr = 0; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int data = pixels[ptr] & 0x00ffffff; -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int data = pixels[ptr] & 0xffffff00; -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - ++ it; - } - } -#else // ENABLE_CILKPLUS - - for (const uint32_t *const p_end = pixels + CAST_SIZE(bufSize); - pixels != p_end; - ++ pixels) - { - uint8_t *const p = reinterpret_cast<uint8_t *>(pixels); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int data = (*pixels) & 0x00ffffff; -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int data = (*pixels) & 0xffffff00; -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - - ++ it; - } - } -#endif // ENABLE_CILKPLUS diff --git a/src/resources/dye/dyepalette_replacescolor_sse2.hpp b/src/resources/dye/dyepalette_replacescolor_sse2.hpp deleted file mode 100644 index 9e4772ac2..000000000 --- a/src/resources/dye/dyepalette_replacescolor_sse2.hpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - std::vector<DyeColor>::const_iterator it_end = mColors.end(); - const size_t sz = mColors.size(); - if (!sz || !pixels) - return; - if (sz % 2) - -- it_end; - const int mod = bufSize % 8; - const int bufEnd = bufSize - mod; - - for (int ptr = 0; ptr < bufEnd; ptr += 4) - { - __m128i mask = _mm_set1_epi32(0xffffff00); -// __m128i base = _mm_load_si128(reinterpret_cast<__m128i*>(pixels)); - __m128i base = _mm_loadu_si128(reinterpret_cast<__m128i*>( - &pixels[ptr])); - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - - __m128i base2 = _mm_and_si128(mask, base); - __m128i newMask = _mm_set1_epi32(col2.valueS); - __m128i cmpMask = _mm_set1_epi32(col.valueS); - __m128i cmpRes = _mm_cmpeq_epi32(base2, cmpMask); - cmpRes = _mm_and_si128(mask, cmpRes); - __m128i srcAnd = _mm_andnot_si128(cmpRes, base); - __m128i dstAnd = _mm_and_si128(cmpRes, newMask); - base = _mm_or_si128(srcAnd, dstAnd); - ++ it; - } -// _mm_store_si128(reinterpret_cast<__m128i*>(pixels), base); - _mm_storeu_si128(reinterpret_cast<__m128i*>(&pixels[ptr]), base); - } - - // complete end without simd - for (int ptr = bufSize - mod; ptr < bufSize; ptr ++) - { - uint8_t *const p = reinterpret_cast<uint8_t *>(&pixels[ptr]); -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int data = pixels[ptr] & 0x00ffffff; -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int data = pixels[ptr] & 0xffffff00; -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - std::vector<DyeColor>::const_iterator it = mColors.begin(); - while (it != it_end) - { - const DyeColor &col = *it; - ++ it; - const DyeColor &col2 = *it; - -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - const unsigned int coldata = (col.value[2] << 16U) - | (col.value[1] << 8U) | (col.value[0]); -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - const unsigned int coldata = (col.value[2] << 8U) - | (col.value[1] << 16U) | (col.value[0] << 24U); -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN - - if (data == coldata) - { - p[3] = col2.value[0]; - p[2] = col2.value[1]; - p[1] = col2.value[2]; - break; - } - - ++ it; - } - } diff --git a/src/resources/dye/dyepaletteptr.h b/src/resources/dye/dyepaletteptr.h new file mode 100644 index 000000000..baf81549d --- /dev/null +++ b/src/resources/dye/dyepaletteptr.h @@ -0,0 +1,31 @@ +/* + * The ManaPlus Client + * Copyright (C) 2011-2017 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef RESOURCES_DYE_DYEPALETTEPTR_H +#define RESOURCES_DYE_DYEPALETTEPTR_H + +#include "localconsts.h" + +class DyePalette; + +typedef void (DyePalette::*DyeFunctionPtr) (uint32_t *restrict pixels, + const int bufSize) const restrict2; + +#endif // RESOURCES_DYE_DYEPALETTEPTR_H diff --git a/src/resources/imagehelper.cpp b/src/resources/imagehelper.cpp index ae5684942..c05ac5816 100644 --- a/src/resources/imagehelper.cpp +++ b/src/resources/imagehelper.cpp @@ -103,7 +103,7 @@ Image *ImageHelper::load(SDL_RWops *const rw, Dye const &dye) { const DyePalette *const pal = dye.getSPalete(); if (pal) - pal->replaceSColor(pixels, surf->w * surf->h); + DYEPALETTEP(pal, SColor)(pixels, surf->w * surf->h); break; } case 2: diff --git a/src/resources/sdlimagehelper.cpp b/src/resources/sdlimagehelper.cpp index 332a3f034..de362ef60 100644 --- a/src/resources/sdlimagehelper.cpp +++ b/src/resources/sdlimagehelper.cpp @@ -88,7 +88,7 @@ Image *SDLImageHelper::load(SDL_RWops *const rw, Dye const &dye) { const DyePalette *const pal = dye.getSPalete(); if (pal) - pal->replaceSColor(pixels, surf->w * surf->h); + DYEPALETTEP(pal, SColor)(pixels, surf->w * surf->h); break; } case 2: diff --git a/src/test/testlauncher.cpp b/src/test/testlauncher.cpp index 64ea181fb..35462499f 100644 --- a/src/test/testlauncher.cpp +++ b/src/test/testlauncher.cpp @@ -519,6 +519,7 @@ static void calcTime(const char *const msg1, int TestLauncher::testDyeSSpeed() { +/* #if defined __linux__ || defined __linux const int sz = 100000; uint32_t buf[sz]; @@ -532,12 +533,13 @@ int TestLauncher::testDyeSSpeed() runDyeTest("dye s salt", "sse2 time ", replaceSColorSse2); runDyeTest("dye s salt", "avx2 time ", replaceSColorAvx2); #endif // defined __linux__ || defined __linux - +*/ return 0; } int TestLauncher::testDyeASpeed() { +/* #if defined __linux__ || defined __linux const int sz = 100000; uint32_t buf[sz]; @@ -551,7 +553,7 @@ int TestLauncher::testDyeASpeed() runDyeTest("dye a salt", "sse2 time ", replaceAColorSse2); runDyeTest("dye a salt", "avx2 time ", replaceAColorAvx2); #endif // defined __linux__ || defined __linux - +*/ return 0; } diff --git a/src/utils/cpu.cpp b/src/utils/cpu.cpp index e57956c06..91f49f5a7 100644 --- a/src/utils/cpu.cpp +++ b/src/utils/cpu.cpp @@ -32,7 +32,10 @@ #include "debug.h" -int mCpuFlags = 0; +namespace +{ + uint32_t mCpuFlags; +} // namespace void Cpu::detect() { @@ -99,16 +102,20 @@ void Cpu::detect() } } fclose(file); - logger->log("cpu features was not detected"); + if (logger) + logger->log("cpu features was not detected"); #else // OTHER - logger->log("cpu features not supported"); + if (logger) + logger->log("cpu features not supported"); #endif // (defined(__amd64__) || defined(__i386__)) && defined(__GNUC__) // && (GCC_VERSION >= 40800) && !defined(ANDROID) } void Cpu::printFlags() { + if (!logger) + return; std::string str("CPU features:"); if (mCpuFlags & FEATURE_MMX) str.append(" mmx"); @@ -128,3 +135,8 @@ void Cpu::printFlags() str.append(" avx2"); logger->log(str); } + +uint32_t Cpu::getFlags() +{ + return mCpuFlags; +} diff --git a/src/utils/cpu.h b/src/utils/cpu.h index 2780795bd..8be6ccbc3 100644 --- a/src/utils/cpu.h +++ b/src/utils/cpu.h @@ -41,6 +41,8 @@ namespace Cpu void detect(); void printFlags(); + + uint32_t getFlags(); } // namespace Cpu #endif // UTILS_CPU_H |