diff --git a/ShaderRecomp/.gitignore b/ShaderRecomp/.gitignore deleted file mode 100644 index 73a9f39..0000000 --- a/ShaderRecomp/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.hlsli.h \ No newline at end of file diff --git a/ShaderRecomp/CMakeLists.txt b/ShaderRecomp/CMakeLists.txt index 84ac3aa..8fbef91 100644 --- a/ShaderRecomp/CMakeLists.txt +++ b/ShaderRecomp/CMakeLists.txt @@ -1,8 +1,5 @@ project(ShaderRecomp) -include(bin2h.cmake) -bin2h(SOURCE_FILE shader_common.hlsli HEADER_FILE shader_common.hlsli.h VARIABLE_NAME SHADER_COMMON_HLSLI) - add_executable(ShaderRecomp constant_table.h dxc_compiler.cpp @@ -11,7 +8,6 @@ add_executable(ShaderRecomp pch.h shader.h shader_code.h - shader_common.hlsli.h shader_recompiler.cpp shader_recompiler.h) diff --git a/ShaderRecomp/bin2h.cmake b/ShaderRecomp/bin2h.cmake deleted file mode 100644 index e1f5e98..0000000 --- a/ShaderRecomp/bin2h.cmake +++ /dev/null @@ -1,83 +0,0 @@ -# https://github.com/sivachandran/cmake-bin2h -include(CMakeParseArguments) - -# 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}) - - 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() - -# Function to embed contents of a file as byte array in C/C++ header file(.h). The header file -# will contain a byte array and integer variable holding the size of the array. -# Parameters -# SOURCE_FILE - The path of source file whose contents will be embedded in the header file. -# VARIABLE_NAME - The name of the variable for the byte array. The string "_SIZE" will be append -# to this name and will be used a variable name for size variable. -# HEADER_FILE - The path of header file. -# APPEND - If specified appends to the header file instead of overwriting it -# NULL_TERMINATE - If specified a null byte(zero) will be append to the byte array. This will be -# useful if the source file is a text file and we want to use the file contents -# as string. But the size variable holds size of the byte array without this -# null byte. -# Usage: -# bin2h(SOURCE_FILE "Logo.png" HEADER_FILE "Logo.h" VARIABLE_NAME "LOGO_PNG") -function(BIN2H) - set(options APPEND NULL_TERMINATE) - set(oneValueArgs SOURCE_FILE VARIABLE_NAME HEADER_FILE) - cmake_parse_arguments(BIN2H "${options}" "${oneValueArgs}" "" ${ARGN}) - - # reads source file contents as hex string - file(READ ${BIN2H_SOURCE_FILE} hexString HEX) - string(LENGTH ${hexString} hexStringLength) - - # appends null byte if asked - if(BIN2H_NULL_TERMINATE) - set(hexString "${hexString}00") - endif() - - # wraps the hex string into multiple lines at column 32(i.e. 16 bytes per line) - wrap_string(VARIABLE hexString AT_COLUMN 32) - math(EXPR arraySize "${hexStringLength} / 2") - - # adds '0x' prefix and comma suffix before and after every byte respectively - string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " arrayValues ${hexString}) - # removes trailing comma - string(REGEX REPLACE ", $" "" arrayValues ${arrayValues}) - - # converts the variable name into proper C identifier - string(MAKE_C_IDENTIFIER "${BIN2H_VARIABLE_NAME}" BIN2H_VARIABLE_NAME) - - # declares byte array and the length variables - set(arrayDefinition "const char ${BIN2H_VARIABLE_NAME}[] = { ${arrayValues} };") - set(arraySizeDefinition "const size_t ${BIN2H_VARIABLE_NAME}_SIZE = ${arraySize};") - - set(declarations "${arrayDefinition}\n\n${arraySizeDefinition}\n\n") - if(BIN2H_APPEND) - file(APPEND ${BIN2H_HEADER_FILE} "${declarations}") - else() - file(WRITE ${BIN2H_HEADER_FILE} "${declarations}") - endif() -endfunction() diff --git a/ShaderRecomp/main.cpp b/ShaderRecomp/main.cpp index 3bb2cfd..0f36b5f 100644 --- a/ShaderRecomp/main.cpp +++ b/ShaderRecomp/main.cpp @@ -45,6 +45,18 @@ int main(int argc, char** argv) argv[2] #endif ; + + const char* includeInput = +#ifdef SHADER_RECOMP_INCLUDE_INPUT + SHADER_RECOMP_INCLUDE_INPUT +#else + argv[3] +#endif + ; + + size_t includeSize = 0; + auto includeData = readAllBytes(includeInput, includeSize); + std::string_view include(reinterpret_cast(includeData.get()), includeSize); if (std::filesystem::is_directory(input)) { @@ -63,7 +75,7 @@ int main(int argc, char** argv) size_t dataSize = shaderContainer->virtualSize + shaderContainer->physicalSize; if ((shaderContainer->flags & 0xFFFFFF00) == 0x102A1100 && - dataSize < (fileSize - i) && + dataSize <= (fileSize - i) && shaderContainer->field1C == 0 && shaderContainer->field20 == 0) { @@ -95,7 +107,7 @@ int main(int argc, char** argv) thread_local ShaderRecompiler recompiler; recompiler = {}; - recompiler.recompile(shader.data); + recompiler.recompile(shader.data, include); thread_local DxcCompiler dxcCompiler; shader.dxil = dxcCompiler.compile(recompiler.out, recompiler.isPixelShader, false); @@ -170,7 +182,7 @@ int main(int argc, char** argv) { ShaderRecompiler recompiler; size_t fileSize; - recompiler.recompile(readAllBytes(input, fileSize).get()); + recompiler.recompile(readAllBytes(input, fileSize).get(), include); writeAllBytes(output, recompiler.out.data(), recompiler.out.size()); } diff --git a/ShaderRecomp/shader_recompiler.cpp b/ShaderRecomp/shader_recompiler.cpp index 17fc256..7169cc0 100644 --- a/ShaderRecomp/shader_recompiler.cpp +++ b/ShaderRecomp/shader_recompiler.cpp @@ -1,5 +1,4 @@ #include "shader_recompiler.h" -#include "shader_common.hlsli.h" static constexpr char SWIZZLES[] = { @@ -1042,14 +1041,16 @@ void ShaderRecompiler::recompile(const AluInstruction& instr) } } -void ShaderRecompiler::recompile(const uint8_t* shaderData) +void ShaderRecompiler::recompile(const uint8_t* shaderData, const std::string_view& include) { const auto shaderContainer = reinterpret_cast(shaderData); assert((shaderContainer->flags & 0xFFFFFF00) == 0x102A1100); assert(shaderContainer->constantTableOffset != NULL); - out += std::string_view(SHADER_COMMON_HLSLI, SHADER_COMMON_HLSLI_SIZE); + out += include; + out += '\n'; + isPixelShader = (shaderContainer->flags & 0x1) == 0; const auto constantTableContainer = reinterpret_cast(shaderData + shaderContainer->constantTableOffset); diff --git a/ShaderRecomp/shader_recompiler.h b/ShaderRecomp/shader_recompiler.h index 20ca6eb..a59a8b4 100644 --- a/ShaderRecomp/shader_recompiler.h +++ b/ShaderRecomp/shader_recompiler.h @@ -46,5 +46,5 @@ struct ShaderRecompiler : StringBuffer void recompile(const TextureFetchInstruction& instr, bool bicubic); void recompile(const AluInstruction& instr); - void recompile(const uint8_t* shaderData); + void recompile(const uint8_t* shaderData, const std::string_view& include); };