diff --git a/cmake/bin2h.cmake b/cmake/bin2h.cmake index deea3923a..21ad56cb1 100644 --- a/cmake/bin2h.cmake +++ b/cmake/bin2h.cmake @@ -54,6 +54,8 @@ endfunction() # as string. But the size variable holds size of the byte array without this # null byte. # HEADER_NAMESPACE - The namespace, where the array should be located in. +# IS_BIG_ENDIAN - If set to true, will not revers the byte order for the uint32_t to match the +# big endian system architecture # Usage: # bin2h(SOURCE_FILE "Logo.png" HEADER_FILE "Logo.h" VARIABLE_NAME "LOGO_PNG") function(BIN2H) @@ -75,7 +77,13 @@ function(BIN2H) math(EXPR arraySize "${hexStringLength} / 8") # adds '0x' prefix and comma suffix before and after every byte respectively - string(REGEX REPLACE "([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])" "0x\\1, " arrayValues ${hexString}) + if(IS_BIG_ENDIAN) + message(STATUS "Interpreting shader in big endian...") + string(REGEX REPLACE "([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])" "0x\\1\\2\\3\\4, " arrayValues ${hexString}) + else() + message(STATUS "Interpreting shader in little endian...") + string(REGEX REPLACE "([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])" "0x\\4\\3\\2\\1, " arrayValues ${hexString}) + endif() # removes trailing comma string(REGEX REPLACE ", $" "" arrayValues ${arrayValues}) diff --git a/cmake/vulkan_shader_compiler.cmake b/cmake/vulkan_shader_compiler.cmake index e09ff4381..bce7fdab9 100644 --- a/cmake/vulkan_shader_compiler.cmake +++ b/cmake/vulkan_shader_compiler.cmake @@ -1,36 +1,39 @@ function(vulkan_compile_shader) - find_program(GLS_LANG_VALIDATOR_PATH NAMES glslangValidator) - if(${GLS_LANG_VALIDATOR_PATH}) - message(FATAL_ERROR "glslangValidator not found.") - return() - endif() + find_program(GLS_LANG_VALIDATOR_PATH NAMES glslangValidator) + if(${GLS_LANG_VALIDATOR_PATH}) + message(FATAL_ERROR "glslangValidator not found.") + return() + endif() - cmake_parse_arguments(SHADER_COMPILE "" "INFILE;OUTFILE;NAMESPACE" "" ${ARGN}) - set(SHADER_COMPILE_INFILE_FULL "${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_COMPILE_INFILE}") - set(SHADER_COMPILE_SPV_FILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${SHADER_COMPILE_INFILE}.spv") - set(SHADER_COMPILE_HEADER_FILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${SHADER_COMPILE_OUTFILE}") + cmake_parse_arguments(SHADER_COMPILE "" "INFILE;OUTFILE;NAMESPACE" "" ${ARGN}) + set(SHADER_COMPILE_INFILE_FULL "${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_COMPILE_INFILE}") + set(SHADER_COMPILE_SPV_FILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${SHADER_COMPILE_INFILE}.spv") + set(SHADER_COMPILE_HEADER_FILE_FULL "${CMAKE_CURRENT_BINARY_DIR}/${SHADER_COMPILE_OUTFILE}") - # .comp -> .spv - add_custom_command(OUTPUT "${SHADER_COMPILE_SPV_FILE_FULL}" - COMMAND "${GLS_LANG_VALIDATOR_PATH}" - ARGS "-V" - "-o" - "${SHADER_COMPILE_SPV_FILE_FULL}" - "--target-env" - "vulkan1.1" - "${SHADER_COMPILE_INFILE_FULL}" - COMMENT "Compile vulkan compute shader from file '${SHADER_COMPILE_INFILE_FULL}' to '${SHADER_COMPILE_SPV_FILE_FULL}'." - MAIN_DEPENDENCY "${SHADER_COMPILE_INFILE_FULL}") + # .comp -> .spv + add_custom_command(OUTPUT "${SHADER_COMPILE_SPV_FILE_FULL}" + COMMAND "${GLS_LANG_VALIDATOR_PATH}" + ARGS "-V" + "${SHADER_COMPILE_INFILE_FULL}" + "-o" + "${SHADER_COMPILE_SPV_FILE_FULL}" + COMMENT "Compile vulkan compute shader from file '${SHADER_COMPILE_INFILE_FULL}' to '${SHADER_COMPILE_SPV_FILE_FULL}'." + MAIN_DEPENDENCY "${SHADER_COMPILE_INFILE_FULL}") - # .spv -> .hpp - add_custom_command(OUTPUT "${SHADER_COMPILE_HEADER_FILE_FULL}" - COMMAND ${CMAKE_COMMAND} - ARGS "-DINPUT_SHADER_FILE=${SHADER_COMPILE_SPV_FILE_FULL}" - "-DOUTPUT_HEADER_FILE=${SHADER_COMPILE_HEADER_FILE_FULL}" - "-DHEADER_NAMESPACE=${SHADER_COMPILE_NAMESPACE}" - "-P" - "${CMAKE_SOURCE_DIR}/cmake/bin_file_to_header.cmake" - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake" - COMMENT "Converting compiled shader '${SHADER_COMPILE_SPV_FILE_FULL}' to header file '${SHADER_COMPILE_HEADER_FILE_FULL}'." - MAIN_DEPENDENCY "${SHADER_COMPILE_SPV_FILE_FULL}") + # Check if big or little endian + include (TestBigEndian) + TEST_BIG_ENDIAN(IS_BIG_ENDIAN) + + # .spv -> .hpp + add_custom_command(OUTPUT "${SHADER_COMPILE_HEADER_FILE_FULL}" + COMMAND ${CMAKE_COMMAND} + ARGS "-DINPUT_SHADER_FILE=${SHADER_COMPILE_SPV_FILE_FULL}" + "-DOUTPUT_HEADER_FILE=${SHADER_COMPILE_HEADER_FILE_FULL}" + "-DHEADER_NAMESPACE=${SHADER_COMPILE_NAMESPACE}" + "-DIS_BIG_ENDIAN=${IS_BIG_ENDIAN}" + "-P" + "${CMAKE_SOURCE_DIR}/cmake/bin_file_to_header.cmake" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/cmake" + COMMENT "Converting compiled shader '${SHADER_COMPILE_SPV_FILE_FULL}' to header file '${SHADER_COMPILE_HEADER_FILE_FULL}'." + MAIN_DEPENDENCY "${SHADER_COMPILE_SPV_FILE_FULL}") endfunction() diff --git a/test/TestOpShadersFromStringAndFile.cpp b/test/TestOpShadersFromStringAndFile.cpp index b4431e041..ea1a924de 100644 --- a/test/TestOpShadersFromStringAndFile.cpp +++ b/test/TestOpShadersFromStringAndFile.cpp @@ -6,6 +6,33 @@ #include "shaders/Utils.hpp" #include "test_op_custom_shader.hpp" +#include "test_shader.hpp" + +TEST(TestShaderEndianness, ShaderRawDataFromConstructor) +{ + std::string shader(R"( + #version 450 + + layout (local_size_x = 1) in; + + layout(set = 0, binding = 0) buffer a { float pa[]; }; + layout(set = 0, binding = 1) buffer b { float pb[]; }; + + void main() { + uint index = gl_GlobalInvocationID.x; + pb[index] = pa[index]; + pa[index] = index; + } + )"); + + std::vector spirv = compileSource(shader); + std::vector spirv2(kp::TEST_SHADER_COMP_SPV.begin(), + kp::TEST_SHADER_COMP_SPV.end()); + EXPECT_EQ(spirv.size(), spirv2.size()); + for (size_t i = 0; i < spirv.size(); i++) { + EXPECT_EQ(spirv[i], spirv2[i]); + } +} TEST(TestOpAlgoCreate, ShaderRawDataFromConstructor) { diff --git a/test/shaders/glsl/CMakeLists.txt b/test/shaders/glsl/CMakeLists.txt index 579a73841..171e6c23a 100644 --- a/test/shaders/glsl/CMakeLists.txt +++ b/test/shaders/glsl/CMakeLists.txt @@ -14,9 +14,14 @@ vulkan_compile_shader(INFILE test_workgroup_shader.comp OUTFILE test_workgroup_shader.hpp NAMESPACE "kp") +vulkan_compile_shader(INFILE test_shader.comp + OUTFILE test_shader.hpp + NAMESPACE "kp") + add_library(test_shaders_glsl "${CMAKE_CURRENT_BINARY_DIR}/test_logistic_regression_shader.hpp" "${CMAKE_CURRENT_BINARY_DIR}/test_op_custom_shader.hpp" - "${CMAKE_CURRENT_BINARY_DIR}/test_workgroup_shader.hpp") + "${CMAKE_CURRENT_BINARY_DIR}/test_workgroup_shader.hpp" + "${CMAKE_CURRENT_BINARY_DIR}/test_shader.hpp") set_target_properties(test_shaders_glsl PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(test_shaders_glsl PUBLIC $) diff --git a/test/shaders/glsl/test_shader.comp b/test/shaders/glsl/test_shader.comp new file mode 100644 index 000000000..fb4a7ab62 --- /dev/null +++ b/test/shaders/glsl/test_shader.comp @@ -0,0 +1,12 @@ +#version 450 + +layout (local_size_x = 1) in; + +layout(set = 0, binding = 0) buffer a { float pa[]; }; +layout(set = 0, binding = 1) buffer b { float pb[]; }; + +void main() { + uint index = gl_GlobalInvocationID.x; + pb[index] = pa[index]; + pa[index] = index; +} \ No newline at end of file