First pass ShaderTranslator base type, able to disasm in msft style.

This commit is contained in:
Ben Vanik
2015-11-28 16:19:04 -08:00
parent bea8870700
commit 65130edaa1
11 changed files with 2796 additions and 716 deletions

View File

@@ -18,68 +18,83 @@
#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.");
DEFINE_string(shader_input, "", "Input shader binary file path.");
DEFINE_string(shader_input_type, "",
"'vs', 'ps', or unspecified to infer from the given filename.");
DEFINE_string(shader_output, "", "Output shader file path.");
DEFINE_string(shader_output_type, "ucode",
"Translator to use: [ucode, spirvtext].");
namespace xe {
namespace gpu {
int shader_compiler_main(const std::vector<std::wstring>& args) {
ShaderType shader_type;
if (!FLAGS_shader_type.empty()) {
if (FLAGS_shader_type == "vert") {
if (!FLAGS_shader_input_type.empty()) {
if (FLAGS_shader_input_type == "vs") {
shader_type = ShaderType::kVertex;
} else if (FLAGS_shader_type == "frag") {
} else if (FLAGS_shader_input_type == "ps") {
shader_type = ShaderType::kPixel;
} else {
XELOGE("Invalid --shader_type; must be 'vert' or 'frag'.");
XELOGE("Invalid --shader_input_type; must be 'vs' or 'ps'.");
return 1;
}
} else {
auto last_dot = FLAGS_input_shader.find_last_of('.');
auto last_dot = FLAGS_shader_input.find_last_of('.');
bool valid_type = false;
if (last_dot != std::string::npos) {
if (FLAGS_input_shader.substr(last_dot) == ".vert") {
if (FLAGS_shader_input.substr(last_dot) == ".vs") {
shader_type = ShaderType::kVertex;
valid_type = true;
} else if (FLAGS_input_shader.substr(last_dot) == ".frag") {
} else if (FLAGS_shader_input.substr(last_dot) == ".ps") {
shader_type = ShaderType::kPixel;
valid_type = true;
}
}
if (!valid_type) {
XELOGE(
"File type not recognized (use .vert, .frag or "
"--shader_type=vert|frag).");
"File type not recognized (use .vs, .ps or "
"--shader_input_type=vs|ps).");
return 1;
}
}
auto input_file = fopen(FLAGS_input_shader.c_str(), "r");
auto input_file = fopen(FLAGS_shader_input.c_str(), "rb");
if (!input_file) {
XELOGE("Unable to open input file: %s", FLAGS_input_shader.c_str());
XELOGE("Unable to open input file: %s", FLAGS_shader_input.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<uint32_t> ucode_words(input_file_size / 4);
fread(ucode_words.data(), 4, ucode_words.size(), input_file);
std::vector<uint32_t> ucode_dwords(input_file_size / 4);
fread(ucode_dwords.data(), 4, ucode_dwords.size(), input_file);
fclose(input_file);
XELOGI("Opened %s as a %s shader, %" PRId64 " words (%" PRId64 " bytes).",
FLAGS_input_shader.c_str(),
shader_type == ShaderType::kVertex ? "vertex" : "fragment",
ucode_words.size(), ucode_words.size() * 4);
FLAGS_shader_input.c_str(),
shader_type == ShaderType::kVertex ? "vertex" : "pixel",
ucode_dwords.size(), ucode_dwords.size() * 4);
ShaderTranslator translator;
std::unique_ptr<ShaderTranslator> translator;
if (FLAGS_shader_output_type == "spirvtext") {
// TODO(benvanik): SPIRV translator.
translator = std::make_unique<UcodeShaderTranslator>();
} else {
translator = std::make_unique<UcodeShaderTranslator>();
}
// TODO(benvanik): hash? need to return the data to big-endian format first.
uint64_t ucode_data_hash = 0;
auto translated_shader = translator.Translate(
shader_type, ucode_data_hash, ucode_words.data(), ucode_words.size());
auto translated_shader = translator->Translate(
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
if (!FLAGS_shader_output.empty()) {
auto output_file = fopen(FLAGS_shader_output.c_str(), "w");
fwrite(translated_shader->binary().data(),
translated_shader->binary().size(), 1, output_file);
fclose(output_file);
}
return 0;
}