Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/nihstro/parser_shbin.cpp
2 views
1
// Copyright 2014 Tony Wasserka
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// * Redistributions of source code must retain the above copyright
8
// notice, this list of conditions and the following disclaimer.
9
// * Redistributions in binary form must reproduce the above copyright
10
// notice, this list of conditions and the following disclaimer in the
11
// documentation and/or other materials provided with the distribution.
12
// * Neither the name of the owner nor the names of its contributors may
13
// be used to endorse or promote products derived from this software
14
// without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
#include "nihstro/parser_shbin.h"
29
30
using namespace nihstro;
31
32
void ShbinParser::ReadHeaders(const std::string& filename) {
33
file.exceptions(std::fstream::badbit | std::fstream::failbit | std::fstream::eofbit);
34
file.open(filename, std::fstream::in | std::fstream::binary);
35
36
file.seekg(0);
37
file.read((char*)&dvlb_header, sizeof(dvlb_header));
38
if (dvlb_header.magic_word != DVLBHeader::MAGIC_WORD) {
39
std::stringstream stream;
40
stream << "Wrong DVLB magic word: Got 0x" << std::hex << dvlb_header.magic_word;
41
throw stream.str();
42
}
43
44
dvle_offsets.resize(dvlb_header.num_programs);
45
dvle_headers.resize(dvlb_header.num_programs);
46
for (auto& offset : dvle_offsets) {
47
file.read((char*)&offset, sizeof(offset));
48
}
49
50
// DVLP comes directly after the DVLE offset table
51
dvlp_offset = (uint32_t)file.tellg();
52
file.seekg(dvlp_offset);
53
file.read((char*)&dvlp_header, sizeof(dvlp_header));
54
if (dvlp_header.magic_word != DVLPHeader::MAGIC_WORD) {
55
std::stringstream stream;
56
stream << "Wrong DVLP magic word at offset " << std::hex << dvlp_offset << ": Got " << std::hex << dvlp_header.magic_word;
57
throw stream.str();
58
}
59
60
for (int i = 0; i < dvlb_header.num_programs; ++i) {
61
auto& dvle_header = dvle_headers[i];
62
file.seekg(dvle_offsets[i]);
63
file.read((char*)&dvle_header, sizeof(dvle_header));
64
if (dvle_header.magic_word != DVLEHeader::MAGIC_WORD) {
65
std::stringstream stream;
66
stream << "Wrong DVLE header in DVLE #" << i << ": " << std::hex << dvle_header.magic_word;
67
throw stream.str();
68
}
69
}
70
71
// TODO: Is there indeed exactly one filename per DVLE?
72
dvle_filenames.resize(dvlb_header.num_programs);
73
uint32_t offset = dvlp_offset + dvlp_header.filename_symbol_offset;
74
for (int i = 0; i < dvlb_header.num_programs; ++i) {
75
auto& filename = dvle_filenames[i];
76
filename = ReadSymbol(offset);
77
offset += filename.length() + 1;
78
}
79
80
// Read shader binary code
81
shader_info.code.resize(dvlp_header.binary_size_words);
82
file.seekg(dvlp_offset + dvlp_header.binary_offset);
83
file.read((char*)shader_info.code.data(), dvlp_header.binary_size_words * sizeof(Instruction));
84
85
// Read operand descriptor table
86
shader_info.swizzle_info.resize(dvlp_header.swizzle_info_num_entries);
87
file.seekg(dvlp_offset + dvlp_header.swizzle_info_offset);
88
file.read((char*)shader_info.swizzle_info.data(), dvlp_header.swizzle_info_num_entries * sizeof(SwizzleInfo));
89
}
90
91
void ShbinParser::ReadDVLE(int dvle_index) {
92
// TODO: Check if we have called ReadHeaders() before!
93
94
if (dvle_index >= dvlb_header.num_programs) {
95
std::stringstream stream;
96
stream << "Invalid DVLE index " << dvle_index << "given";
97
throw stream.str();
98
}
99
100
auto& dvle_header = dvle_headers[dvle_index];
101
auto& dvle_offset = dvle_offsets[dvle_index];
102
103
uint32_t symbol_table_offset = dvle_offset + dvle_header.symbol_table_offset;
104
105
shader_info.constant_table.resize(dvle_header.constant_table_size);
106
uint32_t constant_table_offset = dvle_offset + dvle_header.constant_table_offset;
107
file.seekg(constant_table_offset);
108
for (int i = 0; i < dvle_header.constant_table_size; ++i)
109
file.read((char*)&shader_info.constant_table[i], sizeof(ConstantInfo));
110
111
shader_info.label_table.resize(dvle_header.label_table_size);
112
uint32_t label_table_offset = dvle_offset + dvle_header.label_table_offset;
113
file.seekg(label_table_offset);
114
for (int i = 0; i < dvle_header.label_table_size; ++i)
115
file.read((char*)&shader_info.label_table[i], sizeof(LabelInfo));
116
for (const auto& label_info : shader_info.label_table)
117
shader_info.labels.insert({label_info.program_offset, ReadSymbol(symbol_table_offset + label_info.name_offset)});
118
119
shader_info.output_register_info.resize(dvle_header.output_register_table_size);
120
file.seekg(dvle_offset + dvle_header.output_register_table_offset);
121
for (auto& info : shader_info.output_register_info)
122
file.read((char*)&info, sizeof(OutputRegisterInfo));
123
124
shader_info.uniform_table.resize(dvle_header.uniform_table_size);
125
uint32_t uniform_table_offset = dvle_offset + dvle_header.uniform_table_offset;
126
file.seekg(uniform_table_offset);
127
for (int i = 0; i < dvle_header.uniform_table_size; ++i)
128
file.read((char*)&shader_info.uniform_table[i].basic, sizeof(shader_info.uniform_table[i].basic));
129
for (auto& uniform_info : shader_info.uniform_table)
130
uniform_info.name = ReadSymbol(symbol_table_offset + uniform_info.basic.symbol_offset);
131
132
main_offset = dvlp_offset + dvlp_header.binary_offset;
133
}
134
135
std::string ShbinParser::ReadSymbol(uint32_t offset) {
136
std::string name;
137
file.seekg(offset);
138
std::getline(file, name, '\0');
139
return name;
140
};
141
142