metaforce/hecl/shaderc/main.cpp

140 lines
3.7 KiB
C++
Raw Normal View History

2018-10-07 02:53:57 +00:00
#include "shaderc.hpp"
#include "logvisor/logvisor.hpp"
#include "athena/FileWriter.hpp"
#include "glslang/Public/ShaderLang.h"
#include "hecl/hecl.hpp"
2019-07-20 04:22:58 +00:00
#include <sstream>
#include <nowide/args.hpp>
2018-10-07 02:53:57 +00:00
static logvisor::Module Log("shaderc");
#if _WIN32
2018-10-14 20:09:15 +00:00
#include <d3dcompiler.h>
extern pD3DCompile D3DCompilePROC;
pD3DCompile D3DCompilePROC = nullptr;
2018-12-08 05:18:42 +00:00
static bool FindBestD3DCompile() {
HMODULE d3dCompilelib = LoadLibraryW(L"D3DCompiler_47.dll");
if (!d3dCompilelib) {
d3dCompilelib = LoadLibraryW(L"D3DCompiler_46.dll");
if (!d3dCompilelib) {
d3dCompilelib = LoadLibraryW(L"D3DCompiler_45.dll");
if (!d3dCompilelib) {
d3dCompilelib = LoadLibraryW(L"D3DCompiler_44.dll");
if (!d3dCompilelib) {
d3dCompilelib = LoadLibraryW(L"D3DCompiler_43.dll");
2018-10-14 20:09:15 +00:00
}
2018-12-08 05:18:42 +00:00
}
2018-10-14 20:09:15 +00:00
}
2018-12-08 05:18:42 +00:00
}
if (d3dCompilelib) {
D3DCompilePROC = (pD3DCompile)GetProcAddress(d3dCompilelib, "D3DCompile");
return D3DCompilePROC != nullptr;
}
return false;
2018-10-14 20:09:15 +00:00
}
#endif
2018-10-14 20:09:15 +00:00
int main(int argc, char** argv) {
#if _WIN32
nowide::args _(argc, argv);
2018-10-07 02:53:57 +00:00
#endif
2018-12-08 05:18:42 +00:00
logvisor::RegisterConsoleLogger();
logvisor::RegisterStandardExceptions();
2018-10-07 02:53:57 +00:00
2018-10-14 20:09:15 +00:00
#if _WIN32
2018-12-08 05:18:42 +00:00
if (!FindBestD3DCompile()) {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Info, FMT_STRING("Unable to find D3DCompiler dll"));
2018-12-08 05:18:42 +00:00
return 1;
}
2018-10-14 20:09:15 +00:00
#endif
2018-12-08 05:18:42 +00:00
if (argc == 1) {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Info, FMT_STRING("Usage: shaderc -o <out-base> [-D definevar=defineval]... <in-files>..."));
2018-12-08 05:18:42 +00:00
return 0;
}
2018-10-07 02:53:57 +00:00
std::string outPath;
2018-12-08 05:18:42 +00:00
hecl::shaderc::Compiler c;
for (int i = 1; i < argc; ++i) {
if (argv[i][0] == '-') {
if (argv[i][1] == 'o') {
if (argv[i][2]) {
outPath = &argv[i][2];
} else if (i + 1 < argc) {
++i;
outPath = argv[i];
} else {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Error, FMT_STRING("Invalid -o argument"));
2018-12-08 05:18:42 +00:00
return 1;
2018-10-07 02:53:57 +00:00
}
2018-12-08 05:18:42 +00:00
} else if (argv[i][1] == 'D') {
const char* define;
2018-12-08 05:18:42 +00:00
if (argv[i][2]) {
define = &argv[i][2];
} else if (i + 1 < argc) {
++i;
define = argv[i];
} else {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Error, FMT_STRING("Invalid -D argument"));
2018-12-08 05:18:42 +00:00
return 1;
2018-10-07 02:53:57 +00:00
}
if (const char* equals = strchr(define, '='))
c.addDefine(std::string(define, equals - define), equals + 1);
2018-12-08 05:18:42 +00:00
else
c.addDefine(define, "");
2018-12-08 05:18:42 +00:00
} else {
Log.report(logvisor::Error, FMT_STRING("Unrecognized flag option '{:c}'"), argv[i][1]);
2018-10-07 02:53:57 +00:00
return 1;
2018-12-08 05:18:42 +00:00
}
} else {
c.addInputFile(argv[i]);
2018-10-07 02:53:57 +00:00
}
2018-12-08 05:18:42 +00:00
}
2018-10-07 02:53:57 +00:00
2018-12-08 05:18:42 +00:00
if (outPath.empty()) {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Error, FMT_STRING("-o option is required"));
2018-12-08 05:18:42 +00:00
return 1;
}
2018-10-07 02:53:57 +00:00
std::string_view baseName;
auto slashPos = outPath.find_last_of("/\\");
if (slashPos != std::string::npos)
2018-12-08 05:18:42 +00:00
baseName = outPath.data() + slashPos + 1;
else
baseName = outPath;
2018-10-07 02:53:57 +00:00
2018-12-08 05:18:42 +00:00
if (!glslang::InitializeProcess()) {
2020-04-11 22:48:11 +00:00
Log.report(logvisor::Error, FMT_STRING("Unable to initialize glslang"));
2018-12-08 05:18:42 +00:00
return 1;
}
2018-10-07 02:53:57 +00:00
2019-07-20 04:22:58 +00:00
std::pair<std::stringstream, std::stringstream> ret;
if (!c.compile(baseName, ret))
2018-12-08 05:18:42 +00:00
return 1;
{
std::string headerPath = outPath + ".hpp";
2018-12-08 05:18:42 +00:00
athena::io::FileWriter w(headerPath);
if (w.hasError()) {
Log.report(logvisor::Error, FMT_STRING("Error opening '{}' for writing"), headerPath);
2018-12-08 05:18:42 +00:00
return 1;
2018-10-07 02:53:57 +00:00
}
2019-07-20 04:22:58 +00:00
std::string header = ret.first.str();
w.writeBytes(header.data(), header.size());
2018-12-08 05:18:42 +00:00
}
2018-10-07 02:53:57 +00:00
2018-12-08 05:18:42 +00:00
{
std::string impPath = outPath + ".cpp";
2018-12-08 05:18:42 +00:00
athena::io::FileWriter w(impPath);
if (w.hasError()) {
Log.report(logvisor::Error, FMT_STRING("Error opening '{}' for writing"), impPath);
2018-12-08 05:18:42 +00:00
return 1;
2018-10-07 02:53:57 +00:00
}
2019-07-20 04:22:58 +00:00
std::string source = ret.second.str();
w.writeBytes(source.data(), source.size());
2018-12-08 05:18:42 +00:00
}
2018-10-07 02:53:57 +00:00
2018-12-08 05:18:42 +00:00
return 0;
2018-10-07 02:53:57 +00:00
}