#include "output.h"
#include "resolve.h"
#include "resources.h"
+#include "spirv.h"
#include "validate.h"
#undef interface
void Compiler::compile(Mode mode)
{
+ if(specialized && mode!=PROGRAM)
+ throw invalid_operation("Compiler::compile");
+
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
generate(*i);
ConstantIdAssigner().apply(*module, features);
+ for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
+ validate(*i);
+ GlobalInterfaceValidator().apply(*module);
+
bool valid = true;
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
- if(!validate(*i))
+ if(!check_errors(*i))
valid = false;
if(!valid)
throw invalid_shader_source(get_diagnostics());
- if(mode==PROGRAM && specialized)
+ if(specialized)
{
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
ConstantSpecializer().apply(*i, spec_values);
else if(result!=REDO_STAGE)
++i;
}
+
+ LocationAllocator().apply(*module, features);
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
finalize(*i, mode);
throw key_error(Stage::get_stage_name(stage_type));
}
+vector<UInt32> Compiler::get_combined_spirv() const
+{
+ if(!compiled)
+ throw invalid_operation("Compiler::get_combined_spirv");
+ SpirVGenerator gen;
+ gen.apply(*module);
+ return gen.get_code();
+}
+
const map<string, unsigned> &Compiler::get_vertex_attributes() const
{
if(!compiled)
throw invalid_operation("Compiler::get_fragment_outputs");
}
+const map<string, unsigned> &Compiler::get_texture_bindings() const
+{
+ if(!compiled)
+ throw invalid_operation("Compiler::get_texture_bindings");
+ return module->shared.texture_bindings;
+}
+
+const map<string, unsigned> &Compiler::get_uniform_block_bindings() const
+{
+ if(!compiled)
+ throw invalid_operation("Compiler::get_uniform_block_bindings");
+ return module->shared.uniform_block_bindings;
+}
+
const SourceMap &Compiler::get_source_map() const
{
return module->source_map;
}
}
-bool Compiler::validate(Stage &stage)
+void Compiler::validate(Stage &stage)
{
DeclarationValidator().apply(stage);
IdentifierValidator().apply(stage);
ReferenceValidator().apply(stage);
ExpressionValidator().apply(stage);
+ FlowControlValidator().apply(stage);
+ StageInterfaceValidator().apply(stage);
+}
+bool Compiler::check_errors(Stage &stage)
+{
stable_sort(stage.diagnostics, &diagnostic_line_order);
for(vector<Diagnostic>::const_iterator i=stage.diagnostics.begin(); i!=stage.diagnostics.end(); ++i)
/* Removing variables or functions may cause things from the previous stage
to become unused. */
- bool any_removed = UnusedVariableRemover().apply(stage);
+ bool any_removed = UnreachableCodeRemover().apply(stage);
+ any_removed |= UnusedVariableRemover().apply(stage);
any_removed |= UnusedFunctionRemover().apply(stage);
any_removed |= UnusedTypeRemover().apply(stage);
resolve(stage, RESOLVE_VARIABLES|RESOLVE_FUNCTIONS);
PrecisionConverter().apply(stage);
}
+ else if(mode==SPIRV)
+ StructOrganizer().apply(stage);
+
+ // Collect bindings from all stages into the shared stage's maps
+ module->shared.texture_bindings.insert(stage.texture_bindings.begin(), stage.texture_bindings.end());
+ module->shared.uniform_block_bindings.insert(stage.uniform_block_bindings.begin(), stage.uniform_block_bindings.end());
}
void Compiler::inject_block(Block &target, const Block &source)