diff --git a/bldsys/cmake/module/FindAVX2.cmake b/bldsys/cmake/module/FindAVX2.cmake new file mode 100644 index 0000000000..f88763a411 --- /dev/null +++ b/bldsys/cmake/module/FindAVX2.cmake @@ -0,0 +1,361 @@ +# Adapted from https://github.com/jeffdaily/parasail/blob/600fb26151ff19899ee39a214972dcf2b9b11ed7/cmake/FindAVX2.cmake +#[[ + Copyright (c) 2015-2024, Battelle Memorial Institute + + +1. Battelle Memorial Institute (hereinafter Battelle) hereby grants + permission to any person or entity lawfully obtaining a copy of this + software and associated documentation files (hereinafter “the + Software”) to redistribute and use the Software in source and binary + forms, with or without modification. Such person or entity may use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and may permit others to do so, subject to + the following conditions: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Other than as used herein, neither the name Battelle Memorial + Institute or Battelle may be used in any form whatsoever without + the express written consent of Battelle. + + - Redistributions of the software in any form, and publications + based on work performed using the software should include the + following citation as a reference: + + Daily, Jeff. (2016). Parasail: SIMD C library for global, + semi-global, and local pairwise sequence alignments. *BMC + Bioinformatics*, 17(1), 1-11. doi:10.1186/s12859-016-0930-z + +2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BATTELLE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +]] + + + +# .rst: +# FindAVX2 +# -------- +# +# Finds AVX2 support +# +# This module can be used to detect AVX2 support in a C compiler. If +# the compiler supports AVX2, the flags required to compile with +# AVX2 support are returned in variables for the different languages. +# The variables may be empty if the compiler does not need a special +# flag to support AVX2. +# +# The following variables are set: +# +# :: +# +# AVX2_C_FLAGS - flags to add to the C compiler for AVX2 support +# AVX2_FOUND - true if AVX2 is detected +# ============================================================================= + +set(_AVX2_REQUIRED_VARS) +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${AVX2_FIND_QUIETLY}) + +# sample AVX2 source code to test +set(AVX2_C_TEST_SOURCE +" +#include +void parasail_memset___m256i(__m256i *b, __m256i c, size_t len) +{ + size_t i; + for (i=0; i +#include +__m256i foo() { + __m256i vOne = _mm256_set1_epi64x(1); + return vOne; +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_SET1_EPI64X}" HAVE_AVX2_MM256_SET1_EPI64X) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_SET_EPI64X +" +#include +#include +__m256i foo() { + __m256i vOne = _mm256_set_epi64x(1,1,1,1); + return vOne; +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_SET_EPI64X}" HAVE_AVX2_MM256_SET_EPI64X) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_INSERT64 +" +#include +#include +__m256i foo() { + __m256i vOne = _mm256_set1_epi8(1); + return _mm256_insert_epi64(vOne,INT64_MIN,0); +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_INSERT64}" HAVE_AVX2_MM256_INSERT_EPI64) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_INSERT32 +" +#include +#include +__m256i foo() { + __m256i vOne = _mm256_set1_epi8(1); + return _mm256_insert_epi32(vOne,INT32_MIN,0); +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_INSERT32}" HAVE_AVX2_MM256_INSERT_EPI32) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_INSERT16 +" +#include +#include +__m256i foo() { + __m256i vOne = _mm256_set1_epi8(1); + return _mm256_insert_epi16(vOne,INT16_MIN,0); +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_INSERT16}" HAVE_AVX2_MM256_INSERT_EPI16) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_INSERT8 +" +#include +#include +__m256i foo() { + __m256i vOne = _mm256_set1_epi8(1); + return _mm256_insert_epi8(vOne,INT8_MIN,0); +} +int main(void) { foo(); return 0; } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_INSERT8}" HAVE_AVX2_MM256_INSERT_EPI8) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + + +set(AVX2_C_TEST_SOURCE_EXTRACT64 +" +#include +#include +int64_t foo() { + __m256i vOne = _mm256_set1_epi8(1); + return (int64_t)_mm256_extract_epi64(vOne,0); +} +int main(void) { return (int)foo(); } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_EXTRACT64}" HAVE_AVX2_MM256_EXTRACT_EPI64) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_EXTRACT32 +" +#include +#include +int32_t foo() { + __m256i vOne = _mm256_set1_epi8(1); + return (int32_t)_mm256_extract_epi32(vOne,0); +} +int main(void) { return (int)foo(); } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_EXTRACT32}" HAVE_AVX2_MM256_EXTRACT_EPI32) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_EXTRACT16 +" +#include +#include +int16_t foo() { + __m256i vOne = _mm256_set1_epi8(1); + return (int16_t)_mm256_extract_epi16(vOne,0); +} +int main(void) { return (int)foo(); } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_EXTRACT16}" HAVE_AVX2_MM256_EXTRACT_EPI16) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(AVX2_C_TEST_SOURCE_EXTRACT8 +" +#include +#include +int8_t foo() { + __m256i vOne = _mm256_set1_epi8(1); + return (int8_t)_mm256_extract_epi8(vOne,0); +} +int main(void) { return (int)foo(); } +") + +if(AVX2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${AVX2_C_FLAGS}") + check_c_source_compiles("${AVX2_C_TEST_SOURCE_EXTRACT8}" HAVE_AVX2_MM256_EXTRACT_EPI8) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(CMAKE_C_FLAGS "${SAFE_CMAKE_C_FLAGS}") +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_C_FLAGS "${SAFE_CMAKE_C_FLAGS}") +endif() \ No newline at end of file diff --git a/bldsys/cmake/module/FindNEON.cmake b/bldsys/cmake/module/FindNEON.cmake new file mode 100644 index 0000000000..4377fbe9fb --- /dev/null +++ b/bldsys/cmake/module/FindNEON.cmake @@ -0,0 +1,145 @@ +# Adapted from https://github.com/jeffdaily/parasail/blob/600fb26151ff19899ee39a214972dcf2b9b11ed7/cmake/FindNEON.cmake +#[[ + Copyright (c) 2015-2024, Battelle Memorial Institute + + +1. Battelle Memorial Institute (hereinafter Battelle) hereby grants + permission to any person or entity lawfully obtaining a copy of this + software and associated documentation files (hereinafter “the + Software”) to redistribute and use the Software in source and binary + forms, with or without modification. Such person or entity may use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and may permit others to do so, subject to + the following conditions: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Other than as used herein, neither the name Battelle Memorial + Institute or Battelle may be used in any form whatsoever without + the express written consent of Battelle. + + - Redistributions of the software in any form, and publications + based on work performed using the software should include the + following citation as a reference: + + Daily, Jeff. (2016). Parasail: SIMD C library for global, + semi-global, and local pairwise sequence alignments. *BMC + Bioinformatics*, 17(1), 1-11. doi:10.1186/s12859-016-0930-z + +2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BATTELLE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +]] + +#.rst: +# FindNEON +# -------- +# +# Finds NEON support +# +# This module can be used to detect NEON support in a C compiler. If +# the compiler supports NEON, the flags required to compile with +# NEON support are returned in variables for the different languages. +# The variables may be empty if the compiler does not need a special +# flag to support NEON. +# +# The following variables are set: +# +# :: +# +# NEON_C_FLAGS - flags to add to the C compiler for NEON support +# NEON_FOUND - true if NEON is detected +# +#============================================================================= + +set(_NEON_REQUIRED_VARS) +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${NEON_FIND_QUIETLY}) + +# sample NEON source code to test +set(NEON_C_TEST_SOURCE +" +#include +uint32x4_t double_elements(uint32x4_t input) +{ + return(vaddq_u32(input, input)); +} +int main(void) +{ + uint32x4_t one; + uint32x4_t two = double_elements(one); + return 0; +} +") + +# if these are set then do not try to find them again, +# by avoiding any try_compiles for the flags +if((DEFINED NEON_C_FLAGS) OR (DEFINED HAVE_NEON)) +else() + if(WIN32) + set(NEON_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts NEON + " ") + else() + set(NEON_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts NEON + " " + "-mfpu=neon" + "-mfpu=neon -mfloat-abi=softfp" + ) + endif() + + include(CheckCSourceCompiles) + + foreach(FLAG IN LISTS NEON_C_FLAG_CANDIDATES) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(HAVE_NEON CACHE) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try NEON C flag = [${FLAG}]") + endif() + check_c_source_compiles("${NEON_C_TEST_SOURCE}" HAVE_NEON) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(HAVE_NEON) + set(NEON_C_FLAGS_INTERNAL "${FLAG}") + break() + endif() + endforeach() + + unset(NEON_C_FLAG_CANDIDATES) + + set(NEON_C_FLAGS "${NEON_C_FLAGS_INTERNAL}" + CACHE STRING "C compiler flags for NEON intrinsics") +endif() + +list(APPEND _NEON_REQUIRED_VARS NEON_C_FLAGS) + +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) + +if(_NEON_REQUIRED_VARS) + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(NEON + REQUIRED_VARS ${_NEON_REQUIRED_VARS}) + + mark_as_advanced(${_NEON_REQUIRED_VARS}) + + unset(_NEON_REQUIRED_VARS) +else() + message(SEND_ERROR "FindNEON requires C or CXX language to be enabled") +endif() diff --git a/bldsys/cmake/module/FindSSE2.cmake b/bldsys/cmake/module/FindSSE2.cmake new file mode 100644 index 0000000000..6a4cf849bb --- /dev/null +++ b/bldsys/cmake/module/FindSSE2.cmake @@ -0,0 +1,194 @@ +# Adapted from https://github.com/jeffdaily/parasail/blob/600fb26151ff19899ee39a214972dcf2b9b11ed7/cmake/FindSSE2.cmake +#[[ + Copyright (c) 2015-2024, Battelle Memorial Institute + + +1. Battelle Memorial Institute (hereinafter Battelle) hereby grants + permission to any person or entity lawfully obtaining a copy of this + software and associated documentation files (hereinafter “the + Software”) to redistribute and use the Software in source and binary + forms, with or without modification. Such person or entity may use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and may permit others to do so, subject to + the following conditions: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Other than as used herein, neither the name Battelle Memorial + Institute or Battelle may be used in any form whatsoever without + the express written consent of Battelle. + + - Redistributions of the software in any form, and publications + based on work performed using the software should include the + following citation as a reference: + + Daily, Jeff. (2016). Parasail: SIMD C library for global, + semi-global, and local pairwise sequence alignments. *BMC + Bioinformatics*, 17(1), 1-11. doi:10.1186/s12859-016-0930-z + +2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BATTELLE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +]] + +#.rst: +# FindSSE2 +# -------- +# +# Finds SSE2 support +# +# This module can be used to detect SSE2 support in a C compiler. If +# the compiler supports SSE2, the flags required to compile with +# SSE2 support are returned in variables for the different languages. +# The variables may be empty if the compiler does not need a special +# flag to support SSE2. +# +# The following variables are set: +# +# :: +# +# SSE2_C_FLAGS - flags to add to the C compiler for SSE2 support +# SSE2_FOUND - true if SSE2 is detected +# +#============================================================================= + +set(_SSE2_REQUIRED_VARS) +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${SSE2_FIND_QUIETLY}) + +# sample SSE2 source code to test +set(SSE2_C_TEST_SOURCE +" +#if defined(_MSC_VER) +#include +#else +#include +#endif +int foo() { + __m128i vOne = _mm_set1_epi16(1); + __m128i result = _mm_add_epi16(vOne,vOne); + return _mm_extract_epi16(result, 0); +} +int main(void) { return foo(); } +") + +# if these are set then do not try to find them again, +# by avoiding any try_compiles for the flags +if((DEFINED SSE2_C_FLAGS) OR (DEFINED HAVE_SSE2)) +else() + if(WIN32) + set(SSE2_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts SSE2 + " " + "/arch:SSE2") + else() + set(SSE2_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts SSE2 + " " + #GNU, Intel + "-march=core2" + #clang + "-msse2" + ) + endif() + + include(CheckCSourceCompiles) + + foreach(FLAG IN LISTS SSE2_C_FLAG_CANDIDATES) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(HAVE_SSE2 CACHE) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try SSE2 C flag = [${FLAG}]") + endif() + check_c_source_compiles("${SSE2_C_TEST_SOURCE}" HAVE_SSE2) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(HAVE_SSE2) + set(SSE2_C_FLAGS_INTERNAL "${FLAG}") + break() + endif() + endforeach() + + unset(SSE2_C_FLAG_CANDIDATES) + + set(SSE2_C_FLAGS "${SSE2_C_FLAGS_INTERNAL}" + CACHE STRING "C compiler flags for SSE2 intrinsics") +endif() + +list(APPEND _SSE2_REQUIRED_VARS SSE2_C_FLAGS) + +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) + +if(_SSE2_REQUIRED_VARS) + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(SSE2 + REQUIRED_VARS ${_SSE2_REQUIRED_VARS}) + + mark_as_advanced(${_SSE2_REQUIRED_VARS}) + + unset(_SSE2_REQUIRED_VARS) +else() + message(SEND_ERROR "FindSSE2 requires C or CXX language to be enabled") +endif() + +set(SSE2_C_TEST_SOURCE_SET1_EPI64X +" +#include +#if defined(_MSC_VER) +#include +#else +#include +#endif +__m128i foo() { + __m128i vOne = _mm_set1_epi64x(1); + return vOne; +} +int main(void) { foo(); return 0; } +") + +if(SSE2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${SSE2_C_FLAGS}") + check_c_source_compiles("${SSE2_C_TEST_SOURCE_SET1_EPI64X}" HAVE_SSE2_MM_SET1_EPI64X) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(SSE2_C_TEST_SOURCE_SET_EPI64X +" +#include +#if defined(_MSC_VER) +#include +#else +#include +#endif +__m128i foo() { + __m128i vOne = _mm_set_epi64x(1,1); + return vOne; +} +int main(void) { foo(); return 0; } +") + +if(SSE2_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${SSE2_C_FLAGS}") + check_c_source_compiles("${SSE2_C_TEST_SOURCE_SET_EPI64X}" HAVE_SSE2_MM_SET_EPI64X) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() diff --git a/bldsys/cmake/module/FindSSE41.cmake b/bldsys/cmake/module/FindSSE41.cmake new file mode 100644 index 0000000000..59b896618b --- /dev/null +++ b/bldsys/cmake/module/FindSSE41.cmake @@ -0,0 +1,198 @@ +# Adapted from https://github.com/jeffdaily/parasail/blob/600fb26151ff19899ee39a214972dcf2b9b11ed7/cmake/FindSSE41.cmake +#[[ + Copyright (c) 2015-2024, Battelle Memorial Institute + + +1. Battelle Memorial Institute (hereinafter Battelle) hereby grants + permission to any person or entity lawfully obtaining a copy of this + software and associated documentation files (hereinafter “the + Software”) to redistribute and use the Software in source and binary + forms, with or without modification. Such person or entity may use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and may permit others to do so, subject to + the following conditions: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + - Other than as used herein, neither the name Battelle Memorial + Institute or Battelle may be used in any form whatsoever without + the express written consent of Battelle. + + - Redistributions of the software in any form, and publications + based on work performed using the software should include the + following citation as a reference: + + Daily, Jeff. (2016). Parasail: SIMD C library for global, + semi-global, and local pairwise sequence alignments. *BMC + Bioinformatics*, 17(1), 1-11. doi:10.1186/s12859-016-0930-z + +2. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BATTELLE + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +]] + +#.rst: +# FindSSE41 +# --------- +# +# Finds SSE41 support +# +# This module can be used to detect SSE41 support in a C compiler. If +# the compiler supports SSE41, the flags required to compile with +# SSE41 support are returned in variables for the different languages. +# The variables may be empty if the compiler does not need a special +# flag to support SSE41. +# +# The following variables are set: +# +# :: +# +# SSE41_C_FLAGS - flags to add to the C compiler for SSE41 support +# SSE41_FOUND - true if SSE41 is detected +# +#============================================================================= + +set(_SSE41_REQUIRED_VARS) +set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET}) +set(CMAKE_REQUIRED_QUIET ${SSE41_FIND_QUIETLY}) + +# sample SSE41 source code to test +set(SSE41_C_TEST_SOURCE +" +#if defined(_MSC_VER) +#include +#else +#include +#endif +int foo() { + __m128i vOne = _mm_set1_epi8(1); + __m128i result = _mm_max_epi8(vOne,vOne); + return _mm_extract_epi8(result, 0); +} +int main(void) { return foo(); } +") + +# if these are set then do not try to find them again, +# by avoiding any try_compiles for the flags +if((DEFINED SSE41_C_FLAGS) OR (DEFINED HAVE_SSE41)) +else() + if(WIN32) + set(SSE41_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts SSE41 + " " + "/arch:SSE2") + else() + set(SSE41_C_FLAG_CANDIDATES + #Empty, if compiler automatically accepts SSE41 + " " + #GNU, Intel + "-march=corei7" + #clang + "-msse4" + #GNU 4.4.7 ? + "-msse4.1" + ) + endif() + + include(CheckCSourceCompiles) + + foreach(FLAG IN LISTS SSE41_C_FLAG_CANDIDATES) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(HAVE_SSE41 CACHE) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try SSE41 C flag = [${FLAG}]") + endif() + check_c_source_compiles("${SSE41_C_TEST_SOURCE}" HAVE_SSE41) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") + if(HAVE_SSE41) + set(SSE41_C_FLAGS_INTERNAL "${FLAG}") + break() + endif() + endforeach() + + unset(SSE41_C_FLAG_CANDIDATES) + + set(SSE41_C_FLAGS "${SSE41_C_FLAGS_INTERNAL}" + CACHE STRING "C compiler flags for SSE41 intrinsics") +endif() + +list(APPEND _SSE41_REQUIRED_VARS SSE41_C_FLAGS) + +set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) + +if(_SSE41_REQUIRED_VARS) + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(SSE41 + REQUIRED_VARS ${_SSE41_REQUIRED_VARS}) + + mark_as_advanced(${_SSE41_REQUIRED_VARS}) + + unset(_SSE41_REQUIRED_VARS) +else() + message(SEND_ERROR "FindSSE41 requires C or CXX language to be enabled") +endif() + +# begin tests for SSE4.1 specfic features + +set(SSE41_C_TEST_SOURCE_INSERT64 +" +#include +#if defined(_MSC_VER) +#include +#else +#include +#endif +__m128i foo() { + __m128i vOne = _mm_set1_epi8(1); + return _mm_insert_epi64(vOne,INT64_MIN,0); +} +int main(void) { foo(); return 0; } +") + +if(SSE41_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${SSE41_C_FLAGS}") + check_c_source_compiles("${SSE41_C_TEST_SOURCE_INSERT64}" HAVE_SSE41_MM_INSERT_EPI64) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() + +set(SSE41_C_TEST_SOURCE_EXTRACT64 +" +#include +#if defined(_MSC_VER) +#include +#else +#include +#endif +int64_t foo() { + __m128i vOne = _mm_set1_epi8(1); + return (int64_t)_mm_extract_epi64(vOne,0); +} +int main(void) { return (int)foo(); } +") + +if(SSE41_C_FLAGS) + include(CheckCSourceCompiles) + set(SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${SSE41_C_FLAGS}") + check_c_source_compiles("${SSE41_C_TEST_SOURCE_EXTRACT64}" HAVE_SSE41_MM_EXTRACT_EPI64) + set(CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}") +endif() diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 094dabee47..d0ef2c9c54 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -78,7 +78,7 @@ set(COMMON_FILES common/ktx_common.h common/vk_common.h common/vk_initializers.h - common/glm_common.h + common/glm_common.h common/resource_caching.h common/logging.h common/helpers.h @@ -387,7 +387,7 @@ set(LINUX_D2D_FILES platform/unix/direct_window.h # Source Files platform/unix/unix_d2d_platform.cpp - platform/unix/direct_window.cpp) + platform/unix/direct_window.cpp) source_group("\\" FILES ${FRAMEWORK_FILES}) source_group("common\\" FILES ${COMMON_FILES}) @@ -514,7 +514,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC volk ktx stb - astc + ${ASTC_TARGET} imgui tinygltf glm @@ -532,6 +532,10 @@ if(${NEED_LINK_ATOMIC}) target_link_libraries(${PROJECT_NAME} PUBLIC atomic) endif() +# I'm uncertain why this has to be done explicitly, when the target_link_libraries call above should do it +get_target_property(ASTC_INCLUDE_DIRS ${ASTC_TARGET} INTERFACE_INCLUDE_DIRECTORIES) +target_include_directories(${PROJECT_NAME} PRIVATE ${ASTC_INCLUDE_DIRS}) + # Link platform specific libraries if(ANDROID) # Import game-activity static lib inside the game-activity_static prefab module. diff --git a/framework/scene_graph/components/image.cpp b/framework/scene_graph/components/image.cpp index 8ab8f68d6a..4c2a037e14 100644 --- a/framework/scene_graph/components/image.cpp +++ b/framework/scene_graph/components/image.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2018-2023, Arm Limited and Contributors +/* Copyright (c) 2018-2024, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -236,6 +236,24 @@ Mipmap &Image::get_mipmap(const size_t index) return mipmaps[index]; } +// Note that this function returns the required size for ALL mip levels, *including* the base level. +uint32_t get_required_mipmaps_size(const VkExtent3D &extent) +{ + constexpr uint32_t channels = 4; + auto width = std::max(1, extent.width); + auto height = std::max(1, extent.height); + auto size = width * height * channels; + auto result = size; + while (size != channels) + { + width = std::max(1u, width >> 1); + height = std::max(1u, height >> 1); + size = width * height * channels; + result += size; + } + return result; +} + void Image::generate_mipmaps() { assert(mipmaps.size() == 1 && "Mipmaps already generated"); @@ -251,6 +269,10 @@ void Image::generate_mipmaps() auto channels = 4; auto next_size = next_width * next_height * channels; + // Allocate for all the mips at once. The function returns the total size needed for the + // existing base mip as well as all the mips that will be generated. + data.reserve(get_required_mipmaps_size(extent)); + while (true) { // Make space for next mipmap diff --git a/framework/scene_graph/components/image/astc.cpp b/framework/scene_graph/components/image/astc.cpp index 8b98156646..67d6f2607e 100644 --- a/framework/scene_graph/components/image/astc.cpp +++ b/framework/scene_graph/components/image/astc.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2019-2022, Arm Limited and Contributors +/* Copyright (c) 2019-2024, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -27,7 +27,7 @@ VKBP_DISABLE_WARNINGS() // Windows.h defines IGNORE, so we must #undef it to avoid clashes with astc header # undef IGNORE #endif -#include +#include VKBP_ENABLE_WARNINGS() #define MAGIC_FILE_CONSTANT 0x5CA1AB13 @@ -100,80 +100,62 @@ struct AstcHeader void Astc::init() { - // Initializes ASTC library - static bool initialized{false}; - static std::mutex initialization; - std::unique_lock lock{initialization}; - if (!initialized) - { - // Init stuff - prepare_angular_tables(); - build_quantization_mode_table(); - initialized = true; - } } -void Astc::decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *data_) +void Astc::decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *compressed_data, uint32_t compressed_size) { // Actual decoding - astc_decode_mode decode_mode = DECODE_LDR_SRGB; - uint32_t bitness = 8; - swizzlepattern swz_decode = {0, 1, 2, 3}; - - int xdim = blockdim.x; - int ydim = blockdim.y; - int zdim = blockdim.z; - - if ((xdim < 3 || xdim > 6 || ydim < 3 || ydim > 6 || zdim < 3 || zdim > 6) && - (xdim < 4 || xdim == 7 || xdim == 9 || xdim == 11 || xdim > 12 || - ydim < 4 || ydim == 7 || ydim == 9 || ydim == 11 || ydim > 12 || zdim != 1)) + astcenc_swizzle swizzle = {ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A}; + // Configure the compressor run + astcenc_config astc_config; + auto atscresult = astcenc_config_init( + ASTCENC_PRF_LDR_SRGB, + blockdim.x, + blockdim.y, + blockdim.z, + ASTCENC_PRE_FAST, + ASTCENC_FLG_DECOMPRESS_ONLY, + &astc_config); + + if (atscresult != ASTCENC_SUCCESS) { - throw std::runtime_error{"Error reading astc: invalid block"}; + throw std::runtime_error{"Error initializing astc"}; } - int xsize = extent.width; - int ysize = extent.height; - int zsize = extent.depth; - - if (xsize == 0 || ysize == 0 || zsize == 0) + if (extent.width == 0 || extent.height == 0 || extent.depth == 0) { throw std::runtime_error{"Error reading astc: invalid size"}; } - int xblocks = (xsize + xdim - 1) / xdim; - int yblocks = (ysize + ydim - 1) / ydim; - int zblocks = (zsize + zdim - 1) / zdim; - - auto astc_image = allocate_image(bitness, xsize, ysize, zsize, 0); - initialize_image(astc_image); - - imageblock pb; - for (int z = 0; z < zblocks; z++) + // Allocate working state given config and thread_count + astcenc_context *astc_context; + astcenc_context_alloc(&astc_config, 1, &astc_context); + + astcenc_image decoded{}; + decoded.dim_x = extent.width; + decoded.dim_y = extent.height; + decoded.dim_z = extent.depth; + decoded.data_type = ASTCENC_TYPE_U8; + + // allocate storage for the decoded image + // The astcenc_decompress_image function will write directly to the image data vector + auto uncompressed_size = decoded.dim_x * decoded.dim_y * decoded.dim_z * 4; + auto &decoded_data = get_mut_data(); + decoded_data.resize(uncompressed_size); + void *data_ptr = static_cast(decoded_data.data()); + decoded.data = &data_ptr; + + atscresult = astcenc_decompress_image(astc_context, compressed_data, compressed_size, &decoded, &swizzle, 0); + if (atscresult != ASTCENC_SUCCESS) { - for (int y = 0; y < yblocks; y++) - { - for (int x = 0; x < xblocks; x++) - { - int offset = (((z * yblocks + y) * xblocks) + x) * 16; - const uint8_t *bp = data_ + offset; - - physical_compressed_block pcb = *reinterpret_cast(bp); - symbolic_compressed_block scb; - - physical_to_symbolic(xdim, ydim, zdim, pcb, &scb); - decompress_symbolic_block(decode_mode, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, &scb, &pb); - write_imageblock(astc_image, &pb, xdim, ydim, zdim, x * xdim, y * ydim, z * zdim, swz_decode); - } - } + throw std::runtime_error("Error decoding astc"); } + astcenc_context_free(astc_context); - set_data(astc_image->imagedata8[0][0], astc_image->xsize * astc_image->ysize * astc_image->zsize * 4); set_format(VK_FORMAT_R8G8B8A8_SRGB); - set_width(static_cast(astc_image->xsize)); - set_height(static_cast(astc_image->ysize)); - set_depth(static_cast(astc_image->zsize)); - - destroy_image(astc_image); + set_width(decoded.dim_x); + set_height(decoded.dim_y); + set_depth(decoded.dim_z); } Astc::Astc(const Image &image) : @@ -189,8 +171,10 @@ Astc::Astc(const Image &image) : // When decoding ASTC on CPU (as it is the case in here), we don't decode all mips in the mip chain. // Instead, we just decode mip #0 and re-generate the other LODs later (via image->generate_mipmaps()). const auto blockdim = to_blockdim(image.get_format()); + const auto &extent = mip_it->extent; + auto size = extent.width * extent.height * extent.depth * 4; const uint8_t *data_ptr = image.get_data().data() + mip_it->offset; - decode(blockdim, mip_it->extent, data_ptr); + decode(blockdim, mip_it->extent, data_ptr, size); } Astc::Astc(const std::string &name, const std::vector &data) : @@ -221,7 +205,7 @@ Astc::Astc(const std::string &name, const std::vector &data) : /* height = */ static_cast(header.ysize[0] + 256 * header.ysize[1] + 65536 * header.ysize[2]), /* depth = */ static_cast(header.zsize[0] + 256 * header.zsize[1] + 65536 * header.zsize[2])}; - decode(blockdim, extent, data.data() + sizeof(AstcHeader)); + decode(blockdim, extent, data.data() + sizeof(AstcHeader), to_u32(data.size() - sizeof(AstcHeader))); } } // namespace sg diff --git a/framework/scene_graph/components/image/astc.h b/framework/scene_graph/components/image/astc.h index 106d815659..7b5c452bed 100644 --- a/framework/scene_graph/components/image/astc.h +++ b/framework/scene_graph/components/image/astc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, Arm Limited and Contributors +/* Copyright (c) 2019-2024, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * @@ -56,7 +56,7 @@ class Astc : public Image * @param extent Extent of the image * @param data Pointer to ASTC image data */ - void decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *data); + void decode(BlockDim blockdim, VkExtent3D extent, const uint8_t *data, uint32_t size); /** * @brief Initializes ASTC library diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index 6404b733ff..41a007f51d 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -290,44 +290,61 @@ endif() add_library(stb INTERFACE) target_include_directories(stb INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stb") + +# On an x86_64 macbook, AVX2 is selected, but then I get an error during the final link +# ld: object file .../libastcdec-avx2-static.a was built for different x86_64 sub-type (8) than link command line (3) +# There's no point in checking if we're on an ARM based mac as they support ASTC_LDR natively, so this library +# won't even be used. +if (APPLE) + set(ASTC_ARCH NATIVE) +else() + include( FindAVX2 ) + include( FindSSE41 ) + include( FindSSE2 ) + include( FindNEON ) + if (${AVX2_FOUND}) + set(ASTC_ARCH AVX2) + elseif(${SSE41_FOUND}) + set(ASTC_ARCH SSE41) + elseif(${SSE2_FOUND}) + set(ASTC_ARCH SSE2) + elseif(${NEON_FOUND}) + set(ASTC_ARCH NEON) + else() + set(ASTC_ARCH NATIVE) + endif() +endif() + +string(TOLOWER ${ASTC_ARCH} ASTC_ARCH_LOWER) + + +set(ASTCENC_ISA_${ASTC_ARCH} ON) +set(ASTCENC_CLI OFF) +set(ASTCENC_UNITTEST OFF) +set(ASTCENC_DECOMPRESSOR ON) +set(ASTCENC_UNIVERSAL_BUILD OFF) +set(ASTC_RAW_TARGET astcdec-${ASTC_ARCH_LOWER}-static) +set(ASTC_TARGET ${ASTC_RAW_TARGET} PARENT_SCOPE) + # astc -set(ASTC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/astc) -set(ASTC_INCLUDE_DIR ${ASTC_DIR}/Source) -set(ASTC_SOURCE_DIR ${ASTC_DIR}/Source) - -set(ASTC_SOURCES - ${ASTC_SOURCE_DIR}/astc_image_load_store.cpp - ${ASTC_SOURCE_DIR}/astc_pick_best_endpoint_format.cpp - ${ASTC_SOURCE_DIR}/astc_color_quantize.cpp - ${ASTC_SOURCE_DIR}/astc_weight_align.cpp - ${ASTC_SOURCE_DIR}/astc_integer_sequence.cpp - ${ASTC_SOURCE_DIR}/astc_ideal_endpoints_and_weights.cpp - ${ASTC_SOURCE_DIR}/astc_find_best_partitioning.cpp - ${ASTC_SOURCE_DIR}/astc_compress_symbolic.cpp - ${ASTC_SOURCE_DIR}/astc_decompress_symbolic.cpp - ${ASTC_SOURCE_DIR}/astc_symbolic_physical.cpp - ${ASTC_SOURCE_DIR}/astc_toplevel.cpp - ${ASTC_SOURCE_DIR}/astc_stb_tga.cpp - ${ASTC_SOURCE_DIR}/softfloat.cpp - ${ASTC_SOURCE_DIR}/mathlib.cpp - ${ASTC_SOURCE_DIR}/astc_quantization.cpp - ${ASTC_SOURCE_DIR}/astc_block_sizes2.cpp - ${ASTC_SOURCE_DIR}/astc_percentile_tables.cpp - ${ASTC_SOURCE_DIR}/astc_averages_and_directions.cpp - ${ASTC_SOURCE_DIR}/astc_partition_tables.cpp - ${ASTC_SOURCE_DIR}/astc_color_unquantize.cpp - ${ASTC_SOURCE_DIR}/astc_encoding_choice_error.cpp - ${ASTC_SOURCE_DIR}/astc_kmeans_partitioning.cpp - ${ASTC_SOURCE_DIR}/astc_weight_quant_xfer_tables.cpp - ${ASTC_SOURCE_DIR}/astc_compute_variance.cpp - ${ASTC_SOURCE_DIR}/astc_ktx_dds.cpp -) +add_subdirectory(astc) + +# astc doesn't have separate directories for it's source code and public interface. Additionally, it includes it's +# own copy of STB. In order to avoid conflicts, we copy the only header we need to the build directory and alter the +# INTERFACE_INCLUDE_DIRECTORIES of the target +if (NOT TARGET ${ASTC_RAW_TARGET}) + message(FATAL_ERROR "Couldn't find expected ASTC library target") +endif() + +get_target_property(ASTC_BINARY_DIR ${ASTC_RAW_TARGET} BINARY_DIR) +file( + COPY astc/Source/astcenc.h + DESTINATION ${ASTC_BINARY_DIR}/Include) +set_target_properties( + ${ASTC_RAW_TARGET} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${ASTC_BINARY_DIR}/Include) +set_property(TARGET ${ASTC_RAW_TARGET} PROPERTY FOLDER "ThirdParty") -add_library(astc STATIC ${ASTC_SOURCES}) -target_include_directories(astc PUBLIC ${ASTC_INCLUDE_DIR}) -target_compile_definitions(astc PRIVATE -DNO_STB_IMAGE_IMPLEMENTATION) -set_target_properties(astc PROPERTIES FOLDER "ThirdParty" POSITION_INDEPENDENT_CODE ON) -target_link_libraries(astc PUBLIC stb) if(NOT ANDROID) if (NOT DIRECT_TO_DISPLAY) diff --git a/third_party/astc b/third_party/astc index 4861c3db1c..1a51f29151 160000 --- a/third_party/astc +++ b/third_party/astc @@ -1 +1 @@ -Subproject commit 4861c3db1ca50eb5f5767d95d1cd1bacb98ac8a5 +Subproject commit 1a51f2915121275038677317c8bf61f1a78b590c