diff options
Diffstat (limited to 'demo/DemoAppCodeGen/loaderCodeGen.h')
| -rw-r--r-- | demo/DemoAppCodeGen/loaderCodeGen.h | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/demo/DemoAppCodeGen/loaderCodeGen.h b/demo/DemoAppCodeGen/loaderCodeGen.h new file mode 100644 index 0000000..b92beb1 --- /dev/null +++ b/demo/DemoAppCodeGen/loaderCodeGen.h @@ -0,0 +1,335 @@ +/* +* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#pragma once + +enum LoaderType +{ + eLoaderTypeDynamicLink = 0, + eLoaderTypeStaticLink = 1 +}; + +const unsigned int maxFunctionParams = 8u; + +struct FunctionParams +{ + const char* typeName; + const char* instName; +}; + +struct Function +{ + const char* retType; + const char* method; + unsigned int numParams; + FunctionParams params[maxFunctionParams]; +}; + +struct GenerateCodeParams +{ + LoaderType loaderType; + FILE* file; + Function* functions; + unsigned int numFunctions; + + const char* filenameTmp; + const char* filenameDst; + const char* moduleNameUpperCase; + const char* moduleNameLowerCase; + const char* instName; + const char* apiMarker; +}; + +void typedef_function_ptrs(const GenerateCodeParams* params) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "typedef %s (*%s_ptr_t)(", function.retType, function.method); + + for (unsigned int paramIdx = 0u; paramIdx < function.numParams; paramIdx++) + { + fprintf(params->file, "%s %s", function.params[paramIdx].typeName, function.params[paramIdx].instName); + + if (paramIdx < function.numParams - 1) fprintf(params->file, ", "); + } + + fprintf(params->file, ");\n"); + } + + fprintf(params->file, "\n"); +} + +void declare_function_ptrs(const GenerateCodeParams* params) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "\t%s_ptr_t %s_ptr;\n", function.method, function.method); + } +} + +void implement_pointer_wrappers(const GenerateCodeParams* params) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "%s %s(", function.retType, function.method); + + for (unsigned int paramIdx = 0u; paramIdx < function.numParams; paramIdx++) + { + fprintf(params->file, "%s %s", function.params[paramIdx].typeName, function.params[paramIdx].instName); + + if (paramIdx < function.numParams - 1) fprintf(params->file, ", "); + } + + fprintf(params->file, ")\n{\n"); + + fprintf(params->file, "\treturn %s.%s_ptr(", params->instName, function.method); + + for (unsigned int paramIdx = 0u; paramIdx < function.numParams; paramIdx++) + { + fprintf(params->file, "%s", function.params[paramIdx].instName); + + if (paramIdx < function.numParams - 1) fprintf(params->file, ", "); + } + + fprintf(params->file, ");\n"); + + fprintf(params->file, "}\n\n"); + } +} + +void load_function_ptrs(const GenerateCodeParams* params) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "\t%s.%s_ptr = ", params->instName, function.method); + + fprintf(params->file, "(%s_ptr_t", function.method); + + fprintf(params->file, ")(%sLoaderLoadFunction(&%s, \"%s\")", params->moduleNameLowerCase, params->instName, function.method); + + fprintf(params->file, ");\n"); + } +} + +void load_function_ptrs_static(const GenerateCodeParams* params, const char* suffix) +{ + fprintf(params->file, "\tif (type == APP_CONTEXT_%s)\n\t{\n", suffix); + + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "\t\t%s.%s_ptr = ", params->instName, function.method); + + fprintf(params->file, "%s%s;\n", function.method, suffix); + } + + fprintf(params->file, "\t}\n\n"); +} + +void unload_function_ptrs(const GenerateCodeParams* params) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "\t%s.%s_ptr = nullptr;\n", params->instName, function.method); + } +} + +void declare_backend_functions(const GenerateCodeParams* params, const char* suffix) +{ + for (unsigned int functionIdx = 0u; functionIdx < params->numFunctions; functionIdx++) + { + auto& function = params->functions[functionIdx]; + + fprintf(params->file, "%s %s %s%s(", params->apiMarker, function.retType, function.method, suffix); + + for (unsigned int paramIdx = 0u; paramIdx < function.numParams; paramIdx++) + { + fprintf(params->file, "%s %s", function.params[paramIdx].typeName, function.params[paramIdx].instName); + + if (paramIdx < function.numParams - 1) fprintf(params->file, ", "); + } + + fprintf(params->file, ");\n"); + } + + fprintf(params->file, "\n"); +} + +const char* fileHeader = +"/*\n" +"* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.\n" +"*\n" +"* NVIDIA CORPORATION and its licensors retain all intellectual property\n" +"* and proprietary rights in and to this software, related documentation\n" +"* and any modifications thereto. Any use, reproduction, disclosure or\n" +"* distribution of this software and related documentation without an express\n" +"* license agreement from NVIDIA CORPORATION is strictly prohibited.\n" +"*/\n\n"; + +void generateCode(const GenerateCodeParams* params) +{ + fprintf(params->file, fileHeader); + + typedef_function_ptrs(params); + + const char* loaderBegin = + "struct %sLoader \n" + "{ \n" + " void* module = nullptr; \n" + " const char* suffix = \"\"; \n" + " char buf[1024u]; \n\n"; + fprintf(params->file, loaderBegin, params->moduleNameUpperCase); + + declare_function_ptrs(params); + + const char* loaderEnd = + "\n" + "}%s; \n\n"; + fprintf(params->file, loaderEnd, params->instName); + + implement_pointer_wrappers(params); + + if (params->loaderType == eLoaderTypeDynamicLink) + { + const char* loaderFunction = + "void* %sLoaderLoadFunction(%sLoader* inst, const char* name)\n" + "{\n" + " snprintf(inst->buf, 1024u, \"%s%s\", name, inst->suffix);\n" + "\n" + " return SDL_LoadFunction(inst->module, inst->buf);\n" + "}\n\n"; + fprintf(params->file, loaderFunction, params->moduleNameLowerCase, params->moduleNameUpperCase, "%s", "%s"); + + const char* loadModule = + "void load%s(AppGraphCtxType type)\n" + "{\n" + " const char* moduleName = demoAppDLLName(type);\n" + "\n" + " %s.suffix = demoAppBackendSuffix(type);\n" + "\n" + " %s.module = SDL_LoadObject(moduleName);\n\n"; + fprintf(params->file, loadModule, params->moduleNameUpperCase, params->instName, params->instName); + + load_function_ptrs(params); + + const char* unloadModule = + "}\n" + "\n" + "void unload%s()\n" + "{\n"; + fprintf(params->file, unloadModule, params->moduleNameUpperCase); + + unload_function_ptrs(params); + + const char* unloadModuleEnd = + "\n" + " SDL_UnloadObject(%s.module);\n" + "}\n"; + fprintf(params->file, unloadModuleEnd, params->instName); + } + else if (params->loaderType == eLoaderTypeStaticLink) + { + const unsigned int suffixCount = 2u; + const char* suffix[suffixCount] = { "D3D11", "D3D12" }; + + for (unsigned int suffixIdx = 0u; suffixIdx < 2u; suffixIdx++) + { + declare_backend_functions(params, suffix[suffixIdx]); + } + + const char* loadModule = + "void load%s(AppGraphCtxType type)\n" + "{\n" + " %s.suffix = demoAppBackendSuffix(type);\n" + "\n"; + fprintf(params->file, loadModule, params->moduleNameUpperCase, params->instName); + + for (unsigned int suffixIdx = 0u; suffixIdx < 2u; suffixIdx++) + { + load_function_ptrs_static(params, suffix[suffixIdx]); + } + + const char* unloadModule = + "}\n" + "\n" + "void unload%s()\n" + "{\n"; + fprintf(params->file, unloadModule, params->moduleNameUpperCase); + + unload_function_ptrs(params); + + const char* unloadModuleEnd = + "\n" + "}\n"; + fprintf(params->file, unloadModuleEnd, params->instName); + } +} + +void fileDiffAndWriteIfModified(const GenerateCodeParams* params) +{ + FILE* fileTmp = nullptr; + FILE* fileDst = nullptr; + bool match = true; + + fopen_s(&fileDst, params->filenameDst, "r"); + if (fileDst) + { + fopen_s(&fileTmp, params->filenameTmp, "r"); + if (fileTmp) + { + while (1) + { + int a = fgetc(fileTmp); + int b = fgetc(fileDst); + + if (a == EOF && b == EOF) + { + break; + } + else if (a != b) + { + match = false; + break; + } + } + + fclose(fileTmp); + } + else + { + match = false; + } + fclose(fileDst); + } + else + { + match = false; + } + + if (!match) + { + remove(params->filenameDst); + rename(params->filenameTmp, params->filenameDst); + } + + // always cleanup temp file + remove(params->filenameTmp); +}
\ No newline at end of file |