1 #include "glsl_error.h"
2 #include "spirvwriter.h"
10 SpirVWriter::SpirVWriter(SpirVContent &c):
17 void SpirVWriter::append(vector<Word> &target, const vector<Word> &source)
19 target.insert(target.end(), source.begin(), source.end());
22 void SpirVWriter::write(Word word)
25 throw logic_error("write without begin_op");
26 op_target->push_back(word);
29 void SpirVWriter::write_float(float value)
40 void SpirVWriter::write_string(const string &str)
42 for(unsigned i=0; i<=str.size(); i+=4)
45 for(unsigned j=0; (j<4 && i+j<str.size()); ++j)
46 word |= static_cast<unsigned char>(str[i+j])<<(j*8);
51 void SpirVWriter::begin_op(vector<Word> &target, Opcode opcode, unsigned size)
54 throw logic_error("begin_op without end_op");
55 if(&target==&content.function_body && !current_block_id)
56 throw logic_error("no open block in function");
58 op_head_pos = target.size();
60 write(opcode | (size<<16));
62 if(opcode==OP_BRANCH || opcode==OP_BRANCH_CONDITIONAL || opcode==OP_KILL ||
63 opcode==OP_RETURN || opcode==OP_RETURN_VALUE || opcode==OP_UNREACHABLE)
67 void SpirVWriter::end_op(Opcode opcode)
70 throw logic_error("end_op without begin_op");
71 Word &op_head = (*op_target)[op_head_pos];
72 if(opcode!=(op_head&0xFFFF))
73 throw logic_error("opcode mismatch");
75 unsigned words = op_target->size()-op_head_pos;
76 unsigned op_size = op_head>>16;
80 throw logic_error("incorred number of words written");
83 op_head |= (words<<16);
89 void SpirVWriter::write_op(vector<Word> &target, Opcode opcode)
91 begin_op(target, opcode, 1);
95 void SpirVWriter::write_op(vector<Word> &target, Opcode opcode, Word arg0)
97 begin_op(target, opcode, 2);
102 void SpirVWriter::write_op(vector<Word> &target, Opcode opcode, Word arg0, Word arg1)
104 begin_op(target, opcode, 3);
110 void SpirVWriter::write_op(vector<Word> &target, Opcode opcode, Word arg0, Word arg1, Word arg2)
112 begin_op(target, opcode, 4);
119 void SpirVWriter::write_op_name(Id id, const string &name)
121 begin_op(content.names, OP_NAME);
127 void SpirVWriter::write_op_member_name(Id id, unsigned index, const string &name)
129 begin_op(content.names, OP_MEMBER_NAME);
133 end_op(OP_MEMBER_NAME);
136 void SpirVWriter::write_op_decorate(Id id, Decoration decoration)
138 write_op(content.decorations, OP_DECORATE, id, decoration);
141 void SpirVWriter::write_op_decorate(Id id, Decoration decoration, Word value)
143 write_op(content.decorations, OP_DECORATE, id, decoration, value);
146 void SpirVWriter::write_op_member_decorate(Id id, unsigned index, Decoration decoration)
148 write_op(content.decorations, OP_MEMBER_DECORATE, id, index, decoration);
151 void SpirVWriter::write_op_member_decorate(Id id, unsigned index, Decoration decoration, Word value)
153 begin_op(content.decorations, OP_MEMBER_DECORATE, 5);
158 end_op(OP_MEMBER_DECORATE);
161 void SpirVWriter::write_op_label(Id label_id)
164 write_op(content.function_body, OP_BRANCH, label_id);
165 current_block_id = label_id;
166 write_op(content.function_body, OP_LABEL, label_id);
169 void SpirVWriter::begin_function_body(Id first_block_id)
171 if(!content.function_body.empty() || current_block_id)
172 throw internal_error("begin_function without end_function");
174 current_block_id = first_block_id;
175 write_op(content.functions, OP_LABEL, first_block_id);
178 void SpirVWriter::end_function_body()
180 if(content.function_body.empty())
181 throw internal_error("end_function without begin_function");
183 throw internal_error("end_function with open block");
185 append(content.functions, content.locals);
186 append(content.functions, content.function_body);
187 write_op(content.functions, OP_FUNCTION_END);
189 content.locals.clear();
190 content.function_body.clear();
193 void SpirVWriter::finalize(unsigned generator, Id id_bound)
195 content.code.push_back(SPIRV_MAGIC);
196 content.code.push_back(0x00010500);
197 content.code.push_back(generator<<16);
198 content.code.push_back(id_bound);
199 content.code.push_back(0); // Reserved
200 append(content.code, content.capabilities);
201 append(content.code, content.extensions);
202 write_op(content.code, OP_MEMORY_MODEL, 0, 1); // Logical, GLSL450
203 append(content.code, content.entry_points);
204 append(content.code, content.exec_modes);
205 append(content.code, content.names);
206 append(content.code, content.decorations);
207 append(content.code, content.globals);
208 append(content.code, content.functions);