| /////////////////////////////////////////////////////////////////////////////// |
| /* |
| * Copyright (c) 2019, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sublicense, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #include <iostream> |
| #include <fstream> |
| #include <sstream> |
| #include <iomanip> |
| #include <string> |
| #include <algorithm> |
| #include <sys/stat.h> |
| #include <bits/stdc++.h> |
| |
| static const int32_t MAJ_VERSION = 1; |
| static const int32_t MIN_VERSION = 1; |
| static const char *HEADER_EXT = ".h"; |
| static const char *SOURCE_EXT = ".c"; |
| static const char *PARAM_I = "-i"; |
| static const char *PARAM_O = "-o"; |
| static const char *PARAM_V = "-v"; |
| static const char *PARAM_INDEX = "-index"; |
| static const char *PARAM_TOTAL = "-t"; |
| |
| #ifdef LINUX_ |
| static const char *FILE_SEP = "/"; |
| #else |
| static const char *FILE_SEP = "\\"; |
| #endif |
| |
| static const char *COPYRIGHT = |
| "/*\n" |
| " * Copyright (c) 2019, Intel Corporation\n" |
| " *\n" |
| " * Permission is hereby granted, free of charge, to any person obtaining a\n" |
| " * copy of this software and associated documentation files (the\n" |
| " * 'Software'), to deal in the Software without restriction, including\n" |
| " * without limitation the rights to use, copy, modify, merge, publish,\n" |
| " * distribute, sublicense, and/or sell copies of the Software, and to\n" |
| " * permit persons to whom the Software is furnished to do so, subject to\n" |
| " * the following conditions:\n" |
| " *\n" |
| " * The above copyright notice and this permission notice shall be included\n" |
| " * in all copies or substantial portions of the Software.\n" |
| " *\n" |
| " * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS\n" |
| " * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" |
| " * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n" |
| " * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n" |
| " * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n" |
| " * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n" |
| " * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n" |
| "*/\n" |
| "\n" |
| "////////////////////////////////////////////////////////////////////////////////\n" |
| "// !!! WARNING - AUTO GENERATED FILE. DO NOT EDIT DIRECTLY. !!!\n" |
| "// Generated by KernelBinToSource.exe tool\n" |
| "////////////////////////////////////////////////////////////////////////////////\n" |
| ; |
| |
| //----------------------------------------------------------------------------- |
| // String EndsWith |
| //----------------------------------------------------------------------------- |
| bool strEndsWith( |
| const std::string &str, |
| const std::string &substr) |
| { |
| size_t i = str.rfind(substr); |
| return (i != std::string::npos) && (i == (str.length() - substr.length())); |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Append Path |
| //----------------------------------------------------------------------------- |
| std::string appendPath( |
| const std::string &sPath, |
| const std::string &sSubPath) |
| { |
| std::string strAppendPath = sPath; |
| if (!strEndsWith(sPath, FILE_SEP)) |
| { |
| strAppendPath += FILE_SEP; |
| } |
| strAppendPath += sSubPath; |
| |
| return strAppendPath; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Get the filename from file path |
| //----------------------------------------------------------------------------- |
| std::string getFileName(const std::string &sFilePath) |
| { |
| #ifdef LINUX_ |
| std::string::size_type uiLoc = sFilePath.rfind("/"); |
| #else |
| std::string::size_type uiLoc = sFilePath.rfind("\\"); |
| #endif |
| |
| if (uiLoc != std::string::npos) |
| { |
| return sFilePath.substr(uiLoc+1, sFilePath.length()); |
| } |
| |
| return sFilePath; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Writes the Header file |
| //----------------------------------------------------------------------------- |
| int32_t writeHeaderFile( |
| const uint32_t *pBuffer, |
| uint32_t uiSize, |
| const std::string &sFileName, |
| const std::string &sVarName) |
| { |
| int32_t iStatus = -1; |
| std::ofstream oOutStream; |
| std::stringstream oSs; |
| std::string sHeaderSentry; |
| std::string sSizeName; |
| |
| oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc ); |
| if (!oOutStream.is_open()) |
| { |
| printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str()); |
| goto finish; |
| } |
| |
| sHeaderSentry = "__" + sVarName + "_H__"; |
| sSizeName = "extern const unsigned int " + sVarName + "_SIZE"; |
| |
| oSs << COPYRIGHT |
| << "#ifndef " << sHeaderSentry << std::endl |
| << "#define " << sHeaderSentry << std::endl << std::endl |
| << sSizeName.c_str() << ";" << std::endl |
| << "extern const unsigned int " << sVarName.c_str() << "[]" << ";" |
| << std::endl << std::endl; |
| |
| oSs << "#endif // " << sHeaderSentry << std::endl; |
| |
| oOutStream << oSs.rdbuf(); |
| |
| printf("Header file '%s' generated successfully!\n", sFileName.c_str()); |
| |
| iStatus = 0; |
| |
| finish: |
| if (oOutStream.is_open()) |
| { |
| oOutStream.close(); |
| } |
| |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Writes Partial Source file |
| //----------------------------------------------------------------------------- |
| int32_t writePartialSourceFile( |
| const uint32_t *pBuffer, |
| uint32_t uiSize, |
| const std::string &sFileName, |
| const std::string &sVarName, |
| const uint32_t &index, |
| const uint32_t &total) |
| { |
| int32_t iStatus = -1; |
| std::ofstream oOutStream; |
| std::stringstream oSs; |
| std::string sSizeName; |
| std::string sPlatformName; |
| const uint32_t uiHexLen = 11; |
| char sHex[uiHexLen]; |
| uint32_t offset_size = 0; |
| uint32_t final_size = (uiSize + total) * sizeof(uint32_t); |
| uint32_t stub = 0; |
| |
| oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc ); |
| if (!oOutStream.is_open()) |
| { |
| printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str()); |
| goto finish; |
| } |
| |
| sSizeName = "extern const unsigned int " + sVarName + "_SIZE"; |
| |
| sPlatformName = sVarName; |
| sPlatformName.erase(0, sPlatformName.find_first_of('G',3) + 1); |
| |
| oSs << COPYRIGHT << std::endl; |
| oSs << "#ifdef IGFX_GEN" << sPlatformName.c_str() << "_SUPPORTED" << std::endl; |
| oSs << sSizeName.c_str() << " = " << final_size << ";" << std::endl |
| << "extern const unsigned int " << sVarName.c_str() << "[] =" |
| << std::endl << "{"; |
| |
| for(stub = 0; stub < total; stub++) |
| { |
| if (stub % 8 == 0) |
| { |
| oSs << std::endl << " "; |
| } |
| |
| if( stub == index + 1) |
| { |
| offset_size = uiSize * sizeof(uint32_t); |
| } |
| |
| snprintf(sHex, uiHexLen, "0x%08x", offset_size); |
| |
| sHex[uiHexLen - 1] = '\0'; |
| |
| if (stub % 8 == 7) |
| { |
| oSs << sHex << ","; |
| }else |
| { |
| oSs << sHex << ", "; |
| } |
| } |
| |
| for (uint32_t i = 0; i < uiSize; i++) |
| { |
| if ((i + stub) % 8 == 0) |
| { |
| oSs << std::endl << " "; |
| } |
| |
| snprintf(sHex, uiHexLen, "0x%08x", pBuffer[i]); |
| sHex[uiHexLen - 1] = '\0'; |
| oSs << sHex; |
| |
| if (i < (uiSize - 1)) |
| { |
| if ((i + stub) % 8 == 7) |
| { |
| oSs << ","; |
| } |
| else |
| { |
| oSs << ", "; |
| } |
| } |
| } |
| |
| oSs << std::endl << "};" << std::endl; |
| |
| //Dummy kernel filled with 216 bytes |
| oSs << "#else" << std::endl |
| << sSizeName.c_str() << " = 216;" << std::endl |
| << "extern const unsigned int " << sVarName.c_str() << "[] = {" << std::endl |
| << " 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000," << std::endl |
| << "};" << std::endl |
| << "#endif" << std::endl; |
| |
| oOutStream << oSs.rdbuf(); |
| |
| printf("Source file '%s' generated successfully!\n", sFileName.c_str()); |
| |
| iStatus = 0; |
| |
| finish: |
| if (oOutStream.is_open()) |
| { |
| oOutStream.close(); |
| } |
| |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Writes the Source file |
| //----------------------------------------------------------------------------- |
| int32_t writeSourceFile( |
| const uint32_t *pBuffer, |
| uint32_t uiSize, |
| const std::string &sFileName, |
| const std::string &sVarName) |
| { |
| int32_t iStatus = -1; |
| std::ofstream oOutStream; |
| std::stringstream oSs; |
| std::string sSizeName; |
| std::string sPlatformName; |
| const uint32_t uiHexLen = 11; |
| char sHex[uiHexLen]; |
| |
| oOutStream.open(sFileName.c_str(), std::ios::out | std::ios::trunc ); |
| if (!oOutStream.is_open()) |
| { |
| printf("Error: Unable to open file '%s' for writing\n", sFileName.c_str()); |
| goto finish; |
| } |
| |
| sSizeName = "extern const unsigned int " + sVarName + "_SIZE"; |
| |
| sPlatformName = sVarName; |
| sPlatformName.erase(0, sPlatformName.find_first_of('G',3) + 1); |
| |
| oSs << COPYRIGHT << std::endl; |
| oSs << "#ifdef IGFX_GEN" << sPlatformName.c_str() << "_SUPPORTED" << std::endl; |
| |
| oSs << sSizeName.c_str() << " = " << uiSize * sizeof(uint32_t) << ";" << std::endl |
| << "extern const unsigned int " << sVarName.c_str() << "[] =" |
| << std::endl << "{"; |
| |
| for (uint32_t i = 0; i < uiSize; i++) |
| { |
| if (i % 8 == 0) |
| { |
| oSs << std::endl << " "; |
| } |
| |
| snprintf(sHex, uiHexLen, "0x%08x", pBuffer[i]); |
| sHex[uiHexLen - 1] = '\0'; |
| oSs << sHex; |
| |
| if (i < (uiSize - 1)) |
| { |
| oSs << ", "; |
| } |
| } |
| oSs << std::endl << "};" << std::endl; |
| |
| //Dummy kernel filled with 216 bytes |
| oSs << "#else" << std::endl |
| << sSizeName.c_str() << " = 216;" << std::endl |
| << "extern const unsigned int " << sVarName.c_str() << "[] = {" << std::endl |
| << " 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000," << std::endl |
| << "};" << std::endl |
| << "#endif" << std::endl; |
| |
| oOutStream << oSs.rdbuf(); |
| |
| printf("Source file '%s' generated successfully!\n", sFileName.c_str()); |
| |
| iStatus = 0; |
| |
| finish: |
| if (oOutStream.is_open()) |
| { |
| oOutStream.close(); |
| } |
| |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Creates the Source file |
| //----------------------------------------------------------------------------- |
| int32_t createSourceFile( |
| const std::string &sInputFile, |
| const std::string &sOutputDir, |
| const std::string &sVar, |
| const uint32_t &index, |
| const uint32_t &total) |
| { |
| struct stat StatResult; |
| int32_t iStatus = -1; |
| std::ifstream oInStream; |
| std::string sInputFileName; |
| std::string sOutputFile; |
| std::string sVarName; |
| uint32_t *pBuffer = nullptr; |
| uint32_t uiSize = 0; |
| float fSize = (ceil)(0.0f); |
| uint32_t uiIntSize = 0; |
| |
| // Check if input file exists |
| if (0 != stat(sInputFile.c_str(), &StatResult)) |
| { |
| printf("Error: Unable to read file '%s'\n", sInputFile.c_str()); |
| goto finish; |
| } |
| uiSize = StatResult.st_size; |
| |
| if (sOutputDir.length() > 0) |
| { |
| // Check if out direction exists and validate it is a directory |
| if (0 != stat(sOutputDir.c_str(), &StatResult)) |
| { |
| printf("Error: Unable to find directory '%s'\n", sOutputDir.c_str()); |
| goto finish; |
| } |
| if (0 == (StatResult.st_mode & S_IFDIR)) |
| { |
| printf("Error: Path '%s' is a valid directory\n", sOutputDir.c_str()); |
| goto finish; |
| } |
| } |
| |
| sInputFileName = getFileName(sInputFile); |
| |
| { |
| // Set the Output path |
| std::string::size_type uiLoc = sInputFileName.find(".", 0 ); |
| sOutputFile = (uiLoc != std::string::npos) ? sInputFileName.substr(0, uiLoc) : sInputFileName; |
| sVarName = (sVar.length() == 0) ? sOutputFile : sVar; |
| } |
| |
| sOutputFile += SOURCE_EXT; |
| sOutputFile = appendPath(sOutputDir, sOutputFile); |
| |
| // Read the File |
| oInStream.open(sInputFile.c_str(), std::ios::in | std::ios::binary); |
| if (! oInStream.is_open()) |
| { |
| printf("Error: Unable to open file '%s' for reading\n", sInputFile.c_str()); |
| goto finish; |
| } |
| |
| // Read from the file |
| fSize = (ceil)(uiSize / 4.0f); |
| uiIntSize = static_cast<uint32_t>(fSize); |
| |
| pBuffer = new uint32_t[uiIntSize]; |
| pBuffer[uiIntSize - 1] = 0; // set the last entry as 0 for handling non uint32_t file sizes. |
| oInStream.read(reinterpret_cast<char*>(pBuffer), uiSize); |
| |
| if (oInStream.bad()) |
| { |
| printf("Error: Unable to read from file '%s'\n", sInputFile.c_str()); |
| goto finish; |
| } |
| |
| { |
| std::transform(sVarName.begin(), sVarName.end(), sVarName.begin(), ::toupper); |
| |
| if(index == -1) |
| { |
| iStatus = writeSourceFile(pBuffer, uiIntSize, sOutputFile, sVarName); |
| }else{ |
| iStatus = writePartialSourceFile(pBuffer, uiIntSize, sOutputFile, sVarName, index, total); |
| } |
| } |
| |
| finish: |
| if (oInStream.is_open()) |
| { |
| oInStream.close(); |
| } |
| |
| if (pBuffer) |
| { |
| delete [] pBuffer; |
| pBuffer = nullptr; |
| } |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Creates the Header file |
| //----------------------------------------------------------------------------- |
| int32_t createHeaderFile( |
| const std::string &sInputFile, |
| const std::string &sOutputDir, |
| const std::string &sVar) |
| { |
| struct stat StatResult; |
| int32_t iStatus = -1; |
| std::ifstream oInStream; |
| std::string sInputFileName; |
| std::string sOutputFile; |
| std::string sVarName; |
| uint32_t *pBuffer = nullptr; |
| uint32_t uiSize = 0; |
| float fSize = (ceil)(0.0f); |
| uint32_t uiIntSize = 0; |
| |
| // Check if input file exists |
| if (0 != stat(sInputFile.c_str(), &StatResult)) |
| { |
| printf("Error: Unable to read file '%s'\n", sInputFile.c_str()); |
| goto finish; |
| } |
| uiSize = StatResult.st_size; |
| |
| if (sOutputDir.length() > 0) |
| { |
| // Check if out direction exists and validate it is a directory |
| if (0 != stat(sOutputDir.c_str(), &StatResult)) |
| { |
| printf("Error: Unable to find directory '%s'\n", sOutputDir.c_str()); |
| goto finish; |
| } |
| if (0 == (StatResult.st_mode & S_IFDIR)) |
| { |
| printf("Error: Path '%s' is a valid directory\n", sOutputDir.c_str()); |
| goto finish; |
| } |
| } |
| |
| sInputFileName = getFileName(sInputFile); |
| |
| { |
| // Set the Output path |
| std::string::size_type uiLoc = sInputFileName.find(".", 0 ); |
| sOutputFile = (uiLoc != std::string::npos) ? sInputFileName.substr(0, uiLoc) : sInputFileName; |
| sVarName = (sVar.length() == 0) ? sOutputFile : sVar; |
| } |
| |
| sOutputFile += HEADER_EXT; |
| sOutputFile = appendPath(sOutputDir, sOutputFile); |
| |
| // Read the File |
| oInStream.open(sInputFile.c_str(), std::ios::in | std::ios::binary); |
| if (! oInStream.is_open()) |
| { |
| printf("Error: Unable to open file '%s' for reading\n", sInputFile.c_str()); |
| goto finish; |
| } |
| |
| // Read from the file |
| fSize = (ceil)(uiSize / 4.0f); |
| uiIntSize = static_cast<uint32_t>(fSize); |
| |
| pBuffer = new uint32_t[uiIntSize]; |
| pBuffer[uiIntSize - 1] = 0; // set the last entry as 0 for handling non uint32_t file sizes. |
| oInStream.read(reinterpret_cast<char*>(pBuffer), uiSize); |
| |
| if (oInStream.bad()) |
| { |
| printf("Error: Unable to read from file '%s'\n", sInputFile.c_str()); |
| goto finish; |
| } |
| |
| std::transform(sVarName.begin(), sVarName.end(), sVarName.begin(), ::toupper); |
| iStatus = writeHeaderFile(pBuffer, uiIntSize, sOutputFile, sVarName); |
| |
| finish: |
| if (oInStream.is_open()) |
| { |
| oInStream.close(); |
| } |
| |
| if (pBuffer) |
| { |
| delete [] pBuffer; |
| pBuffer = nullptr; |
| } |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Prints Usage |
| //----------------------------------------------------------------------------- |
| void printUsage(const std::string &sProgram) |
| { |
| std::cout << "Usage: " |
| << sProgram.c_str() |
| << " (" << PARAM_I << " InPath)" |
| << " [" << PARAM_O << " OutPath]" |
| << " [" << PARAM_V << " VarName]" |
| << " [" << PARAM_INDEX << " Kernel Index]" |
| << " [" << PARAM_TOTAL << " Kernel Total]" |
| << std::endl |
| << " " << PARAM_I << " Path to Kernel binary input file (required)" << std::endl |
| << " " << PARAM_O << " Path to Kernel binary output directory (optional)" << std::endl |
| << " " << PARAM_V << " Variable Name on the generated source file (optional)" << std::endl |
| << " " << PARAM_INDEX << " Variable kernel Index (optional)" << std::endl |
| << " " << PARAM_TOTAL << " Variable kernel total count (optional)" << std::endl; |
| |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Parses input |
| //----------------------------------------------------------------------------- |
| int32_t parseInput( |
| int32_t argc, |
| char *argv[], |
| const std::string &sProgram, |
| std::string &sInput, |
| std::string &sOutput, |
| std::string &sVarName, |
| uint32_t &index, |
| uint32_t &total) |
| { |
| int32_t iStatus = -1; |
| |
| // Must have even number of arguments (excluding argv[0]) |
| if (argc % 2 == 0) |
| { |
| goto finish; |
| } |
| |
| for (int i = 1; i < argc; i += 2) |
| { |
| if (0 == strcmp(PARAM_I, argv[i])) |
| { |
| sInput = argv[i+1]; |
| } |
| else if (0 == strcmp(PARAM_O, argv[i])) |
| { |
| sOutput = argv[i+1]; |
| } |
| else if (0 == strcmp(PARAM_V, argv[i])) |
| { |
| sVarName = argv[i+1]; |
| } |
| else if (0 == strcmp(PARAM_INDEX, argv[i])) |
| { |
| index = atoi(argv[i+1]); |
| } |
| else if (0 == strcmp(PARAM_TOTAL, argv[i])) |
| { |
| total = atoi(argv[i+1]) + 1; |
| } |
| else |
| { |
| std::cout << "Error: Invalid option " << argv[i] << std::endl; |
| goto finish; |
| } |
| } |
| |
| if (sInput.length() == 0) |
| { |
| goto finish; |
| } |
| |
| iStatus = 0; |
| |
| finish: |
| if (iStatus != 0) |
| { |
| printUsage(sProgram); |
| } |
| |
| return iStatus; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Prints time |
| //----------------------------------------------------------------------------- |
| void printTime(int64_t lFreq, int64_t lTime) |
| { |
| double dsec = ((double)lTime) / ((double)lFreq); |
| double dms = dsec * 1000; |
| std::cout << "Time Took " << std::setw(2) << dsec << "s " |
| << "(" << dms << "ms)" |
| << std::endl; |
| } |
| |
| //----------------------------------------------------------------------------- |
| // Main Function |
| //----------------------------------------------------------------------------- |
| int32_t main(int argc, char *argv[]) |
| { |
| std::string sProgram = getFileName(argv[0]); |
| std::cout << std::endl |
| << sProgram.c_str() << " v" << MAJ_VERSION << "." << MIN_VERSION << std::endl |
| << "(c) Intel Corporation 2019. All rights reserved." << std::endl << std::endl; |
| |
| int32_t iStatus = -1; |
| std::string sInputPath; |
| std::string sOutputDir; |
| std::string sVarName; |
| uint32_t index=-1; |
| uint32_t total=-1; |
| |
| iStatus = parseInput(argc, argv, sProgram, sInputPath, sOutputDir, sVarName, index, total); |
| if (iStatus != 0) |
| { |
| goto finish; |
| } |
| |
| iStatus = createHeaderFile(sInputPath, sOutputDir, sVarName); |
| |
| iStatus = createSourceFile(sInputPath, sOutputDir, sVarName, index, total); |
| |
| finish: |
| return iStatus; |
| } |