Fixed shader to header endianness

Signed-off-by: Fabian Sauter <sauter.fabian@mailbox.org>
This commit is contained in:
Fabian Sauter 2022-05-19 14:25:18 +02:00
parent 34f9d58722
commit a53d2b9a4e
5 changed files with 88 additions and 33 deletions

View file

@ -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})

View file

@ -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()

View file

@ -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<uint32_t> spirv = compileSource(shader);
std::vector<uint32_t> 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)
{

View file

@ -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 $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)

View file

@ -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;
}