Switch shader storage to char arrays

This commit is contained in:
Marek Roszko 2022-05-14 11:39:14 -04:00
parent bf4b3a1ff8
commit 6d7835e742
2 changed files with 79 additions and 50 deletions

View File

@ -1,54 +1,83 @@
file( READ ${SOURCE} SOURCE_TEXT )
file( SIZE ${SOURCE} SOURCE_FILESIZE )
#
# Converts provided shader files into the gal namespaced shaders
#
# The goal here is to convert the contents of shaders in the source tree
# into strings to embed into the binaries rather than loading from disk.
#
# We convert the shaders to binary form in the header due limitations of string literal
# lengths and also because future development options such as moving to bgfx
# results in precompiled binary shaders we need to store
#
# This file is structured to be invoked from add_custom_command in order
# to have GENERATED marked output files that can be rebuilt on change.
#
# Required Arguments:
# SOURCE_FILE - Path to source shader file
# OUT_CPP_DIR - Destination path for cpp file
# OUT_HEADER_DIR - Destination path for header file
# OUT_CPP_FILENAME - cpp filename
# OUT_HEADER_FILENAME - header filename
# OUT_VAR_NAME - Name of variable containing shader to be created
#
# Parts taken from https://github.com/sivachandran/cmake-bin2h
# Copyright 2020 Sivachandran Paramasivam
#
set( MAX_BYTES_PER_LITERAL 16000 )
# Function to wrap a given string into multiple lines at the given column position.
# Parameters:
# VARIABLE - The name of the CMake variable holding the string.
# AT_COLUMN - The column position at which string will be wrapped.
function(WRAP_STRING)
set(oneValueArgs VARIABLE AT_COLUMN)
cmake_parse_arguments(WRAP_STRING "${options}" "${oneValueArgs}" "" ${ARGN})
math(EXPR NUMBER_LITERALS "${SOURCE_FILESIZE}/${MAX_BYTES_PER_LITERAL}")
string(LENGTH ${${WRAP_STRING_VARIABLE}} stringLength)
math(EXPR offset "0")
while(stringLength GREATER 0)
if(stringLength GREATER ${WRAP_STRING_AT_COLUMN})
math(EXPR length "${WRAP_STRING_AT_COLUMN}")
else()
math(EXPR length "${stringLength}")
endif()
string(SUBSTRING ${${WRAP_STRING_VARIABLE}} ${offset} ${length} line)
set(lines "${lines}\n${line}")
math(EXPR stringLength "${stringLength} - ${length}")
math(EXPR offset "${offset} + ${length}")
endwhile()
set(${WRAP_STRING_VARIABLE} "${lines}" PARENT_SCOPE)
endfunction()
set( outCppTextStdString "std::string ${OUTVARNAME} = ")
file( READ ${SOURCE_FILE} _SOURCE_BINARY HEX )
string(LENGTH ${_SOURCE_BINARY} _SOURCE_BINARY_LENGTH)
set(SOURCE_BINARY "${_SOURCE_BINARY}00") # null terminate for the sake of it
wrap_string(VARIABLE _SOURCE_BINARY AT_COLUMN 32)
math(EXPR _ARRAY_SIZE "${_SOURCE_BINARY_LENGTH} / 2")
# adds '0x' prefix and comma suffix before and after every byte respectively
string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " _ARRAY_VALUES ${_SOURCE_BINARY})
# removes trailing comma
string(REGEX REPLACE ", $" "" _ARRAY_VALUES ${_ARRAY_VALUES})
set( outCppTextByteArray "unsigned char ${OUT_VAR_NAME}_bytes[] = { ${_ARRAY_VALUES} };")
set( outCppTextStdString "std::string ${OUT_VAR_NAME} = std::string( reinterpret_cast<char const*>(${OUT_VAR_NAME}_bytes), ${_ARRAY_SIZE} ) ;")
set( outCppText
"
#include <string>
#include <${OUTHEADERFILE}>
#include <${OUT_HEADER_FILENAME}>
namespace KIGFX {
namespace BUILTIN_SHADERS {
")
MATH(EXPR LAST_LITERAL_ITER "${NUMBER_LITERALS}-1")
foreach(LITERAL_ITER RANGE 0 ${NUMBER_LITERALS} 1)
set( CHUNK_TEXT "" )
MATH(EXPR TEXT_OFFSET "${LITERAL_ITER}*${MAX_BYTES_PER_LITERAL}")
string(SUBSTRING "${SOURCE_TEXT}" ${TEXT_OFFSET} ${MAX_BYTES_PER_LITERAL} CHUNK_TEXT)
set( outCppText
"
${outCppText}
const char ${OUTVARNAME}_p${LITERAL_ITER}[] = R\"SHADER_SOURCE(
${CHUNK_TEXT}
)SHADER_SOURCE\";
" )
set( outCppTextStdString "${outCppTextStdString} std::string(${OUTVARNAME}_p${LITERAL_ITER})")
if( ${LITERAL_ITER} LESS_EQUAL ${LAST_LITERAL_ITER})
set( outCppTextStdString " ${outCppTextStdString} +")
endif()
endforeach()
set( outCppTextStdString "${outCppTextStdString};")
set( outCppText
"
${outCppText}
${outCppTextByteArray}
${outCppTextStdString}
}
@ -56,7 +85,7 @@ ${outCppTextStdString}
" )
file(
WRITE ${DESTINATION_SOURCE_DIR}/${OUTCPPFILE}
WRITE ${OUT_CPP_DIR}/${OUT_CPP_FILENAME}
"${outCppText}"
)
@ -64,14 +93,14 @@ file(
set( outHeaderText
"namespace KIGFX {
namespace BUILTIN_SHADERS {
extern std::string ${OUTVARNAME};
extern std::string ${OUT_VAR_NAME};
}
}"
)
file(
WRITE ${DESTINATION_HEADER_DIR}/${OUTHEADERFILE}
WRITE ${OUT_HEADER_DIR}/${OUT_HEADER_FILENAME}
"${outHeaderText}"
)
message(STATUS "Shader ${SOURCE} converted to ${DESTINATION_SOURCE_DIR}/${OUTCPPFILE}")
message(STATUS "Shader ${SOURCE_FILE} converted to ${OUT_CPP_DIR}/${OUT_CPP_FILENAME}")

View File

@ -65,12 +65,12 @@ function( add_shader outTarget inFile shaderName )
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${outCppName}
${CMAKE_BINARY_DIR}/include/gal/shaders/${outHeaderName}
COMMAND ${CMAKE_COMMAND}
-DSOURCE="${CMAKE_CURRENT_SOURCE_DIR}/shaders/${inFile}"
-DDESTINATION_SOURCE_DIR="${CMAKE_CURRENT_BINARY_DIR}/"
-DDESTINATION_HEADER_DIR="${CMAKE_BINARY_DIR}/include/gal/shaders/"
-DOUTCPPFILE="${outCppName}"
-DOUTHEADERFILE="${outHeaderName}"
-DOUTVARNAME="${shaderName}"
-DSOURCE_FILE="${CMAKE_CURRENT_SOURCE_DIR}/shaders/${inFile}"
-DOUT_CPP_DIR="${CMAKE_CURRENT_BINARY_DIR}/"
-DOUT_HEADER_DIR="${CMAKE_BINARY_DIR}/include/gal/shaders/"
-DOUT_CPP_FILENAME="${outCppName}"
-DOUT_HEADER_FILENAME="${outHeaderName}"
-DOUT_VAR_NAME="${shaderName}"
-P ${CMAKE_MODULE_PATH}/BuildSteps/CreateShaderCpp.cmake
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/shaders/${inFile}
${CMAKE_MODULE_PATH}/BuildSteps/CreateShaderCpp.cmake