diff --git a/src/xenia/gpu/gl4/gl4_shader.cc b/src/xenia/gpu/gl4/gl4_shader.cc index 256964575..16875c1ba 100644 --- a/src/xenia/gpu/gl4/gl4_shader.cc +++ b/src/xenia/gpu/gl4/gl4_shader.cc @@ -338,8 +338,18 @@ bool GL4Shader::CompileProgram(std::string source) { xe::filesystem::CreateFolder(dump_shaders_path); } + char bin_file_name[kMaxPath]; + snprintf(bin_file_name, xe::countof(file_name), "%s/gl4_gen_%.16llX.bin.%s", + base_path, data_hash_, + shader_type_ == ShaderType::kVertex ? "vert" : "frag"); + FILE* f = fopen(bin_file_name, "w"); + if (f) { + fwrite(data_.data(), 4, data_.size(), f); + fclose(f); + } + // Note that we put the translated source first so we get good line numbers. - FILE* f = fopen(file_name, "w"); + f = fopen(file_name, "w"); if (f) { fprintf(f, "%s", translated_disassembly_.c_str()); fprintf(f, "/*\n"); diff --git a/src/xenia/gpu/shader_compiler_main.cc b/src/xenia/gpu/shader_compiler_main.cc index 1e8102c2a..4f9d34d9e 100644 --- a/src/xenia/gpu/shader_compiler_main.cc +++ b/src/xenia/gpu/shader_compiler_main.cc @@ -9,6 +9,7 @@ #include +#include #include #include @@ -17,11 +18,57 @@ #include "xenia/base/string.h" #include "xenia/gpu/shader_translator.h" +DEFINE_string(input_shader, "", "Input shader binary file path."); +DEFINE_string( + shader_type, "", + "'vert', 'frag', or unspecified to infer from the given filename."); + namespace xe { namespace gpu { int shader_compiler_main(const std::vector& args) { - ShaderTranslator c; + bool is_vertex_shader = false; + if (!FLAGS_shader_type.empty()) { + if (FLAGS_shader_type == "vs") { + is_vertex_shader = false; + } + } else { + auto last_dot = FLAGS_input_shader.find_last_of('.'); + bool valid_type = false; + if (last_dot != std::string::npos) { + if (FLAGS_input_shader.substr(last_dot) == ".vert") { + is_vertex_shader = true; + valid_type = true; + } else if (FLAGS_input_shader.substr(last_dot) == ".frag") { + valid_type = true; + } + } + if (!valid_type) { + XELOGE( + "File type not recognized (use .vert, .frag or " + "--shader_type=vert|frag)."); + return 1; + } + } + + auto input_file = fopen(FLAGS_input_shader.c_str(), "r"); + if (!input_file) { + XELOGE("Unable to open input file: %s", FLAGS_input_shader.c_str()); + return 1; + } + fseek(input_file, 0, SEEK_END); + size_t input_file_size = ftell(input_file); + fseek(input_file, 0, SEEK_SET); + std::vector ucode_words(input_file_size / 4); + fread(ucode_words.data(), 4, ucode_words.size(), input_file); + fclose(input_file); + + XELOGI("Opened %s as a %s shader, %" PRId64 " words (%" PRId64 " bytes).", + FLAGS_input_shader.c_str(), is_vertex_shader ? "vertex" : "fragment", + ucode_words.size(), ucode_words.size() * 4); + + ShaderTranslator translator; + return 0; }