Path: blob/a-new-beginning/SharedDependencies/Sources/nihstro/parser_shbin.cpp
2 views
// Copyright 2014 Tony Wasserka1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are met:5//6// * Redistributions of source code must retain the above copyright7// notice, this list of conditions and the following disclaimer.8// * Redistributions in binary form must reproduce the above copyright9// notice, this list of conditions and the following disclaimer in the10// documentation and/or other materials provided with the distribution.11// * Neither the name of the owner nor the names of its contributors may12// be used to endorse or promote products derived from this software13// without specific prior written permission.14//15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2627#include "nihstro/parser_shbin.h"2829using namespace nihstro;3031void ShbinParser::ReadHeaders(const std::string& filename) {32file.exceptions(std::fstream::badbit | std::fstream::failbit | std::fstream::eofbit);33file.open(filename, std::fstream::in | std::fstream::binary);3435file.seekg(0);36file.read((char*)&dvlb_header, sizeof(dvlb_header));37if (dvlb_header.magic_word != DVLBHeader::MAGIC_WORD) {38std::stringstream stream;39stream << "Wrong DVLB magic word: Got 0x" << std::hex << dvlb_header.magic_word;40throw stream.str();41}4243dvle_offsets.resize(dvlb_header.num_programs);44dvle_headers.resize(dvlb_header.num_programs);45for (auto& offset : dvle_offsets) {46file.read((char*)&offset, sizeof(offset));47}4849// DVLP comes directly after the DVLE offset table50dvlp_offset = (uint32_t)file.tellg();51file.seekg(dvlp_offset);52file.read((char*)&dvlp_header, sizeof(dvlp_header));53if (dvlp_header.magic_word != DVLPHeader::MAGIC_WORD) {54std::stringstream stream;55stream << "Wrong DVLP magic word at offset " << std::hex << dvlp_offset << ": Got " << std::hex << dvlp_header.magic_word;56throw stream.str();57}5859for (int i = 0; i < dvlb_header.num_programs; ++i) {60auto& dvle_header = dvle_headers[i];61file.seekg(dvle_offsets[i]);62file.read((char*)&dvle_header, sizeof(dvle_header));63if (dvle_header.magic_word != DVLEHeader::MAGIC_WORD) {64std::stringstream stream;65stream << "Wrong DVLE header in DVLE #" << i << ": " << std::hex << dvle_header.magic_word;66throw stream.str();67}68}6970// TODO: Is there indeed exactly one filename per DVLE?71dvle_filenames.resize(dvlb_header.num_programs);72uint32_t offset = dvlp_offset + dvlp_header.filename_symbol_offset;73for (int i = 0; i < dvlb_header.num_programs; ++i) {74auto& filename = dvle_filenames[i];75filename = ReadSymbol(offset);76offset += filename.length() + 1;77}7879// Read shader binary code80shader_info.code.resize(dvlp_header.binary_size_words);81file.seekg(dvlp_offset + dvlp_header.binary_offset);82file.read((char*)shader_info.code.data(), dvlp_header.binary_size_words * sizeof(Instruction));8384// Read operand descriptor table85shader_info.swizzle_info.resize(dvlp_header.swizzle_info_num_entries);86file.seekg(dvlp_offset + dvlp_header.swizzle_info_offset);87file.read((char*)shader_info.swizzle_info.data(), dvlp_header.swizzle_info_num_entries * sizeof(SwizzleInfo));88}8990void ShbinParser::ReadDVLE(int dvle_index) {91// TODO: Check if we have called ReadHeaders() before!9293if (dvle_index >= dvlb_header.num_programs) {94std::stringstream stream;95stream << "Invalid DVLE index " << dvle_index << "given";96throw stream.str();97}9899auto& dvle_header = dvle_headers[dvle_index];100auto& dvle_offset = dvle_offsets[dvle_index];101102uint32_t symbol_table_offset = dvle_offset + dvle_header.symbol_table_offset;103104shader_info.constant_table.resize(dvle_header.constant_table_size);105uint32_t constant_table_offset = dvle_offset + dvle_header.constant_table_offset;106file.seekg(constant_table_offset);107for (int i = 0; i < dvle_header.constant_table_size; ++i)108file.read((char*)&shader_info.constant_table[i], sizeof(ConstantInfo));109110shader_info.label_table.resize(dvle_header.label_table_size);111uint32_t label_table_offset = dvle_offset + dvle_header.label_table_offset;112file.seekg(label_table_offset);113for (int i = 0; i < dvle_header.label_table_size; ++i)114file.read((char*)&shader_info.label_table[i], sizeof(LabelInfo));115for (const auto& label_info : shader_info.label_table)116shader_info.labels.insert({label_info.program_offset, ReadSymbol(symbol_table_offset + label_info.name_offset)});117118shader_info.output_register_info.resize(dvle_header.output_register_table_size);119file.seekg(dvle_offset + dvle_header.output_register_table_offset);120for (auto& info : shader_info.output_register_info)121file.read((char*)&info, sizeof(OutputRegisterInfo));122123shader_info.uniform_table.resize(dvle_header.uniform_table_size);124uint32_t uniform_table_offset = dvle_offset + dvle_header.uniform_table_offset;125file.seekg(uniform_table_offset);126for (int i = 0; i < dvle_header.uniform_table_size; ++i)127file.read((char*)&shader_info.uniform_table[i].basic, sizeof(shader_info.uniform_table[i].basic));128for (auto& uniform_info : shader_info.uniform_table)129uniform_info.name = ReadSymbol(symbol_table_offset + uniform_info.basic.symbol_offset);130131main_offset = dvlp_offset + dvlp_header.binary_offset;132}133134std::string ShbinParser::ReadSymbol(uint32_t offset) {135std::string name;136file.seekg(offset);137std::getline(file, name, '\0');138return name;139};140141142