blob: 9e606998774fc5111f7281d7d6f0cc4de2703041 [file] [log] [blame]
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +01001/*
2 * Copyright 2015-2016 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Hans-Kristian Arntzen147e53a2016-04-04 09:36:04 +020017#include "spirv_cpp.hpp"
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010018
19using namespace spv;
Hans-Kristian Arntzen147e53a2016-04-04 09:36:04 +020020using namespace spirv_cross;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010021using namespace std;
22
23void CompilerCPP::emit_buffer_block(const SPIRVariable &var)
24{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020025 auto &type = get<SPIRType>(var.basetype);
26 auto instance_name = to_name(var.self);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010027
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020028 uint32_t descriptor_set = meta[var.self].decoration.set;
29 uint32_t binding = meta[var.self].decoration.binding;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010030
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020031 emit_struct(type);
32 statement("internal::Resource<", type_to_glsl(type), type_to_array_glsl(type), "> ", instance_name, "__;");
33 statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
34 resource_registrations.push_back(
35 join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");"));
36 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010037}
38
39void CompilerCPP::emit_interface_block(const SPIRVariable &var)
40{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020041 auto &type = get<SPIRType>(var.basetype);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010042
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020043 const char *qual = var.storage == StorageClassInput ? "StageInput" : "StageOutput";
44 const char *lowerqual = var.storage == StorageClassInput ? "stage_input" : "stage_output";
45 auto instance_name = to_name(var.self);
46 uint32_t location = meta[var.self].decoration.location;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010047
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020048 auto flags = meta[type.self].decoration.decoration_flags;
49 if (flags & (1ull << DecorationBlock))
50 emit_struct(type);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010051
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020052 statement("internal::", qual, "<", type_to_glsl(type), type_to_array_glsl(type), "> ", instance_name, "__;");
53 statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
54 resource_registrations.push_back(join("s.register_", lowerqual, "(", instance_name, "__", ", ", location, ");"));
55 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010056}
57
58void CompilerCPP::emit_shared(const SPIRVariable &var)
59{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020060 auto instance_name = to_name(var.self);
61 statement(variable_decl(var), ";");
62 statement_no_indent("#define ", instance_name, " __res->", instance_name);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010063}
64
65void CompilerCPP::emit_uniform(const SPIRVariable &var)
66{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020067 auto &type = get<SPIRType>(var.basetype);
68 auto instance_name = to_name(var.self);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010069
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020070 uint32_t descriptor_set = meta[var.self].decoration.set;
71 uint32_t binding = meta[var.self].decoration.binding;
72 uint32_t location = meta[var.self].decoration.location;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010073
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020074 if (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage ||
75 type.basetype == SPIRType::AtomicCounter)
76 {
77 statement("internal::Resource<", type_to_glsl(type), type_to_array_glsl(type), "> ", instance_name, "__;");
78 statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
79 resource_registrations.push_back(
80 join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");"));
81 }
82 else
83 {
84 statement("internal::UniformConstant<", type_to_glsl(type), type_to_array_glsl(type), "> ", instance_name,
85 "__;");
86 statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()");
87 resource_registrations.push_back(
88 join("s.register_uniform_constant(", instance_name, "__", ", ", location, ");"));
89 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010090
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020091 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +010092}
93
94void CompilerCPP::emit_push_constant_block(const SPIRVariable &var)
95{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +020096 auto &type = get<SPIRType>(var.basetype);
97 auto &flags = meta[var.self].decoration.decoration_flags;
98 if ((flags & (1ull << DecorationBinding)) || (flags & (1ull << DecorationDescriptorSet)))
99 throw CompilerError("Push constant blocks cannot be compiled to GLSL with Binding or Set syntax. "
100 "Remap to location with reflection API first or disable these decorations.");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100101
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200102 emit_struct(type);
103 auto instance_name = to_name(var.self);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100104
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200105 statement("internal::PushConstant<", type_to_glsl(type), type_to_array_glsl(type), "> ", instance_name, ";");
106 statement_no_indent("#define ", instance_name, " __res->", instance_name, ".get()");
107 resource_registrations.push_back(join("s.register_push_constant(", instance_name, "__", ");"));
108 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100109}
110
111void CompilerCPP::emit_resources()
112{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200113 // Output all basic struct types which are not Block or BufferBlock as these are declared inplace
114 // when such variables are instantiated.
115 for (auto &id : ids)
116 {
117 if (id.get_type() == TypeType)
118 {
119 auto &type = id.get<SPIRType>();
120 if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer &&
121 (meta[type.self].decoration.decoration_flags &
122 ((1ull << DecorationBlock) | (1ull << DecorationBufferBlock))) == 0)
123 {
124 emit_struct(type);
125 }
126 }
127 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100128
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200129 statement("struct Resources : ", resource_type);
130 begin_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100131
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200132 // Output UBOs and SSBOs
133 for (auto &id : ids)
134 {
135 if (id.get_type() == TypeVariable)
136 {
137 auto &var = id.get<SPIRVariable>();
138 auto &type = get<SPIRType>(var.basetype);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100139
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200140 if (type.pointer && type.storage == StorageClassUniform && !is_builtin_variable(var) &&
141 (meta[type.self].decoration.decoration_flags &
142 ((1ull << DecorationBlock) | (1ull << DecorationBufferBlock))))
143 {
144 emit_buffer_block(var);
145 }
146 }
147 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100148
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200149 // Output push constant blocks
150 for (auto &id : ids)
151 {
152 if (id.get_type() == TypeVariable)
153 {
154 auto &var = id.get<SPIRVariable>();
155 auto &type = get<SPIRType>(var.basetype);
156 if (type.pointer && type.storage == StorageClassPushConstant)
157 emit_push_constant_block(var);
158 }
159 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100160
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200161 // Output in/out interfaces.
162 for (auto &id : ids)
163 {
164 if (id.get_type() == TypeVariable)
165 {
166 auto &var = id.get<SPIRVariable>();
167 auto &type = get<SPIRType>(var.basetype);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100168
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200169 if (!is_builtin_variable(var) && !var.remapped_variable && type.pointer &&
170 (var.storage == StorageClassInput || var.storage == StorageClassOutput))
171 {
172 emit_interface_block(var);
173 }
174 }
175 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100176
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200177 // Output Uniform Constants (values, samplers, images, etc).
178 for (auto &id : ids)
179 {
180 if (id.get_type() == TypeVariable)
181 {
182 auto &var = id.get<SPIRVariable>();
183 auto &type = get<SPIRType>(var.basetype);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100184
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200185 if (!is_builtin_variable(var) && !var.remapped_variable && type.pointer &&
186 (type.storage == StorageClassUniformConstant || type.storage == StorageClassAtomicCounter))
187 {
188 emit_uniform(var);
189 }
190 }
191 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100192
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200193 // Global variables.
194 bool emitted = false;
195 for (auto global : global_variables)
196 {
197 auto &var = get<SPIRVariable>(global);
198 if (var.storage == StorageClassWorkgroup)
199 {
200 emit_shared(var);
201 emitted = true;
202 }
203 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100204
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200205 if (emitted)
206 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100207
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200208 statement("inline void init(spirv_cross_shader& s)");
209 begin_scope();
210 statement(resource_type, "::init(s);");
211 for (auto &reg : resource_registrations)
212 statement(reg);
213 end_scope();
214 resource_registrations.clear();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100215
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200216 end_scope_decl();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100217
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200218 statement("");
219 statement("Resources* __res;");
220 if (execution.model == ExecutionModelGLCompute)
221 statement("ComputePrivateResources __priv_res;");
222 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100223
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200224 // Emit regular globals which are allocated per invocation.
225 emitted = false;
226 for (auto global : global_variables)
227 {
228 auto &var = get<SPIRVariable>(global);
229 if (var.storage == StorageClassPrivate)
230 {
231 if (var.storage == StorageClassWorkgroup)
232 emit_shared(var);
233 else
234 statement(variable_decl(var), ";");
235 emitted = true;
236 }
237 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100238
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200239 if (emitted)
240 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100241}
242
243string CompilerCPP::compile()
244{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200245 // Do not deal with ES-isms like precision, older extensions and such.
246 options.es = false;
247 options.version = 450;
248 backend.float_literal_suffix = true;
249 backend.uint32_t_literal_suffix = true;
250 backend.basic_int_type = "int32_t";
251 backend.basic_uint_type = "uint32_t";
252 backend.swizzle_is_function = true;
253 backend.shared_is_implied = true;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100254
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200255 uint32_t pass_count = 0;
256 do
257 {
258 if (pass_count >= 3)
259 throw CompilerError("Over 3 compilation loops detected. Must be a bug!");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100260
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200261 resource_registrations.clear();
262 reset();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100263
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200264 // Move constructor for this type is broken on GCC 4.9 ...
265 buffer = unique_ptr<ostringstream>(new ostringstream());
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100266
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200267 emit_header();
268 emit_resources();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100269
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200270 emit_function(get<SPIRFunction>(execution.entry_point), 0);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100271
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200272 pass_count++;
273 } while (force_recompile);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100274
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200275 // Match opening scope of emit_header().
276 end_scope_decl();
277 // namespace
278 end_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100279
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200280 // Emit C entry points
281 emit_c_linkage();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100282
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200283 return buffer->str();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100284}
285
286void CompilerCPP::emit_c_linkage()
287{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200288 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100289
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200290 statement("spirv_cross_shader_t* spirv_cross_construct(void)");
291 begin_scope();
292 statement("return new ", impl_type, "();");
293 end_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100294
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200295 statement("");
296 statement("void spirv_cross_destruct(spirv_cross_shader_t *shader)");
297 begin_scope();
298 statement("delete static_cast<", impl_type, "*>(shader);");
299 end_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100300
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200301 statement("");
302 statement("void spirv_cross_invoke(spirv_cross_shader_t *shader)");
303 begin_scope();
304 statement("static_cast<", impl_type, "*>(shader)->invoke();");
305 end_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100306
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200307 statement("");
308 statement("static const struct spirv_cross_interface vtable =");
309 begin_scope();
310 statement("spirv_cross_construct,");
311 statement("spirv_cross_destruct,");
312 statement("spirv_cross_invoke,");
313 end_scope_decl();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100314
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200315 statement("");
316 statement("const struct spirv_cross_interface* spirv_cross_get_interface(void)");
317 begin_scope();
318 statement("return &vtable;");
319 end_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100320}
321
papostoloue108d852016-05-18 10:46:33 +0300322string CompilerCPP::constant_expression(const SPIRConstant &c)
323{
324 if (!c.subconstants.empty())
325 {
326 // Handles Arrays and structures.
327 string res = "{";
328 for (auto &elem : c.subconstants)
329 {
330 res += constant_expression(get<SPIRConstant>(elem));
331 if (&elem != &c.subconstants.back())
332 res += ", ";
333 }
334 res += "}";
335 return res;
336 }
337 else if (c.columns() == 1)
338 {
339 return constant_expression_vector(c, 0);
340 }
341 else
342 {
343 string res = "{";
344 for (uint32_t col = 0; col < c.columns(); col++)
345 {
346 res += constant_expression_vector(c, col);
347 if (col + 1 < c.columns())
348 res += ", ";
349 }
350 res += "}";
351 return res;
352 }
353}
354
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100355void CompilerCPP::emit_function_prototype(SPIRFunction &func, uint64_t)
356{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200357 local_variables.clear();
358 string decl;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100359
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200360 auto &type = get<SPIRType>(func.return_type);
361 decl += "inline ";
362 decl += type_to_glsl(type);
363 decl += " ";
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100364
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200365 if (func.self == execution.entry_point)
366 {
367 decl += "main";
368 processing_entry_point = true;
369 }
370 else
371 decl += to_name(func.self);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100372
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200373 decl += "(";
374 for (auto &arg : func.arguments)
375 {
376 add_local_variable(arg.id);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100377
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200378 decl += argument_decl(arg);
379 if (&arg != &func.arguments.back())
380 decl += ", ";
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100381
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200382 // Hold a pointer to the parameter so we can invalidate the readonly field if needed.
383 auto *var = maybe_get<SPIRVariable>(arg.id);
384 if (var)
385 var->parameter = &arg;
386 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100387
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200388 decl += ")";
389 statement(decl);
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100390}
391
392string CompilerCPP::argument_decl(const SPIRFunction::Parameter &arg)
393{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200394 auto &type = expression_type(arg.id);
395 bool constref = !type.pointer || arg.write_count == 0;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100396
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200397 auto &var = get<SPIRVariable>(arg.id);
398 return join(constref ? "const " : "", type_to_glsl(type), "& ", to_name(var.self), type_to_array_glsl(type));
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100399}
400
401void CompilerCPP::emit_header()
402{
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200403 statement("// This C++ shader is autogenerated by spirv-cross.");
404 statement("#include \"spirv_cross/internal_interface.hpp\"");
405 statement("#include \"spirv_cross/external_interface.h\"");
406 statement("#include <stdint.h>");
407 statement("");
408 statement("using namespace spirv_cross;");
409 statement("using namespace glm;");
410 statement("");
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100411
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200412 statement("namespace Impl");
413 begin_scope();
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100414
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200415 switch (execution.model)
416 {
417 case ExecutionModelGeometry:
418 case ExecutionModelTessellationControl:
419 case ExecutionModelTessellationEvaluation:
420 case ExecutionModelGLCompute:
421 case ExecutionModelFragment:
422 case ExecutionModelVertex:
423 statement("struct Shader");
424 begin_scope();
425 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100426
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200427 default:
428 throw CompilerError("Unsupported execution model.");
429 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100430
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200431 switch (execution.model)
432 {
433 case ExecutionModelGeometry:
434 impl_type = "GeometryShader<Impl::Shader, Impl::Shader::Resources>";
435 resource_type = "GeometryResources";
436 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100437
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200438 case ExecutionModelVertex:
439 impl_type = "VertexShader<Impl::Shader, Impl::Shader::Resources>";
440 resource_type = "VertexResources";
441 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100442
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200443 case ExecutionModelFragment:
444 impl_type = "FragmentShader<Impl::Shader, Impl::Shader::Resources>";
445 resource_type = "FragmentResources";
446 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100447
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200448 case ExecutionModelGLCompute:
449 impl_type = join("ComputeShader<Impl::Shader, Impl::Shader::Resources, ", execution.workgroup_size.x, ", ",
450 execution.workgroup_size.y, ", ", execution.workgroup_size.z, ">");
451 resource_type = "ComputeResources";
452 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100453
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200454 case ExecutionModelTessellationControl:
455 impl_type = "TessControlShader<Impl::Shader, Impl::Shader::Resources>";
456 resource_type = "TessControlResources";
457 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100458
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200459 case ExecutionModelTessellationEvaluation:
460 impl_type = "TessEvaluationShader<Impl::Shader, Impl::Shader::Resources>";
461 resource_type = "TessEvaluationResources";
462 break;
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100463
Hans-Kristian Arntzen4b8ed532016-05-05 09:33:18 +0200464 default:
465 throw CompilerError("Unsupported execution model.");
466 }
Hans-Kristian Arntzen75471fb2016-03-02 18:09:16 +0100467}