compiler.compile(SL::Compiler::MODULE);
prepared_source = compiler.get_combined_glsl();
source_map = compiler.get_source_map();
+
#ifdef DEBUG
string diagnostics = compiler.get_diagnostics();
if(!diagnostics.empty())
code.insert(code.end(), buffer, buffer+len);
}
+ reflect();
+}
+
+void SpirVModule::compile(SL::Compiler &compiler)
+{
+ compiler.compile(SL::Compiler::SPIRV);
+ code = compiler.get_combined_spirv();
+ reflect();
+}
+
+void SpirVModule::reflect()
+{
if(code.empty())
throw invalid_module("Empty SPIR-V code");
Reflection reflection;
reflection.reflect_code(code);
+ map<const Constant *, unsigned> spec_indices;
+ for(map<unsigned, Constant>::const_iterator i=reflection.constants.begin(); i!=reflection.constants.end(); ++i)
+ if(i->second.constant_id>=0)
+ {
+ spec_indices[&i->second] = spec_constants.size();
+ spec_constants.push_back(i->second);
+ }
+
map<const Structure *, unsigned> struct_indices;
structs.reserve(reflection.structs.size());
for(map<unsigned, Structure>::const_iterator i=reflection.structs.begin(); i!=reflection.structs.end(); ++i)
map<const Structure *, unsigned>::const_iterator k = struct_indices.find(j->struct_type);
j->struct_type = (k!=struct_indices.end() ? &structs[k->second] : 0);
}
+ if(j->array_size_spec)
+ {
+ map<const Constant *, unsigned>::const_iterator k = spec_indices.find(j->array_size_spec);
+ j->array_size_spec = (k!=spec_indices.end() ? &spec_constants[k->second] : 0);
+ }
}
const StructMember *last_member = &i->members.back();
const StructMember *lm = &last_member->struct_type->members.back();
if(last_member->array_size)
last_offset += last_member->array_stride*(last_member->array_size-1);
+ else if(last_member->array_size_spec)
+ last_offset += last_member->array_stride*(last_member->array_size_spec->i_value-1);
last_offset += lm->offset;
last_member = lm;
}
}
for(vector<Variable>::iterator i=variables.begin(); i!=variables.end(); ++i)
+ {
if(i->struct_type)
{
map<const Structure *, unsigned>::const_iterator j = struct_indices.find(i->struct_type);
i->struct_type = (j!=struct_indices.end() ? &structs[j->second] : 0);
}
+ if(i->array_size_spec)
+ {
+ map<const Constant *, unsigned>::const_iterator j = spec_indices.find(i->array_size_spec);
+ i->array_size_spec = (j!=spec_indices.end() ? &spec_constants[j->second] : 0);
+ }
+ }
entry_points.reserve(reflection.entry_points.size());
for(map<unsigned, EntryPoint>::const_iterator i=reflection.entry_points.begin(); i!=reflection.entry_points.end(); ++i)
*j = (k!=var_indices.end() ? &variables[k->second] : 0);
}
}
-
- for(map<unsigned, SpecConstant>::const_iterator i=reflection.spec_constants.begin(); i!=reflection.spec_constants.end(); ++i)
- spec_constants.push_back(i->second);
-}
-
-void SpirVModule::compile(SL::Compiler &)
-{
- throw logic_error("Not implemented yet");
}
struct_type(0),
offset(0),
array_size(0),
+ array_size_spec(0),
array_stride(0),
matrix_stride(0)
{ }
SpirVModule::TypeInfo::TypeInfo():
type(VOID),
struct_type(0),
+ array_size_spec(0),
array_size(0),
array_stride(0),
storage(static_cast<StorageClass>(-1))
for(CodeIterator op=code.begin()+5; op!=code.end(); )
{
unsigned word_count = *op>>16;
- if(word_count>code.end()-op)
+ if(word_count>static_cast<unsigned>(code.end()-op))
throw invalid_module("Truncated SPIR-V instruction");
switch(get_opcode(*op))
case OP_TYPE_ARRAY: reflect_array_type(op); break;
case OP_TYPE_STRUCT: reflect_struct_type(op); break;
case OP_TYPE_POINTER: reflect_pointer_type(op); break;
- case OP_CONSTANT_TRUE: constants[*(op+2)] = true; break;
- case OP_CONSTANT_FALSE: constants[*(op+2)] = false; break;
- case OP_CONSTANT: reflect_constant(op); break;
+ case OP_CONSTANT_TRUE:
+ case OP_CONSTANT_FALSE:
+ case OP_CONSTANT:
case OP_SPEC_CONSTANT_TRUE:
case OP_SPEC_CONSTANT_FALSE:
- case OP_SPEC_CONSTANT: reflect_spec_constant(op); break;
+ case OP_SPEC_CONSTANT: reflect_constant(op); break;
case OP_VARIABLE: reflect_variable(op); break;
case OP_DECORATE: reflect_decorate(op); break;
case OP_MEMBER_DECORATE: reflect_member_decorate(op); break;
const TypeInfo &elem = types[*(op+2)];
type.type = elem.type;
type.struct_type = elem.struct_type;
- const Variant &size = constants[*(op+3)];
- if(size.check_type<int>())
- type.array_size = size.value<int>();
- else if(size.check_type<unsigned>())
- type.array_size = size.value<unsigned>();
+
+ const Constant &size = constants[*(op+3)];
+ if(size.constant_id>=0)
+ type.array_size_spec = &size;
+ else if(size.type==INT || size.type==UNSIGNED_INT)
+ type.array_size = size.i_value;
}
void SpirVModule::Reflection::reflect_struct_type(CodeIterator op)
mem->type = type.type;
mem->struct_type = type.struct_type;
mem->array_size = type.array_size;
+ mem->array_size_spec = type.array_size_spec;
mem->array_stride = type.array_stride;
}
}
}
void SpirVModule::Reflection::reflect_constant(CodeIterator op)
-{
- const TypeInfo &type = types[*(op+1)];
- unsigned id = *(op+2);
- if(type.type==INT)
- constants[id] = static_cast<int>(*(op+3));
- else if(type.type==UNSIGNED_INT)
- constants[id] = static_cast<unsigned>(*(op+3));
- else if(type.type==FLOAT)
- constants[id] = *reinterpret_cast<const float *>(&*(op+3));
-}
-
-void SpirVModule::Reflection::reflect_spec_constant(CodeIterator op)
{
unsigned id = *(op+2);
- SpecConstant &spec = spec_constants[id];
- spec.name = names[id];
- spec.type = types[*(op+1)].type;
+ Constant &cnst = constants[id];
+ cnst.name = names[id];
+ cnst.type = types[*(op+1)].type;
+ if(*op==OP_CONSTANT_TRUE || *op==OP_SPEC_CONSTANT_TRUE)
+ cnst.i_value = true;
+ else if(*op==OP_CONSTANT_FALSE || *op==OP_SPEC_CONSTANT_FALSE)
+ cnst.i_value = false;
+ else if(cnst.type==INT || cnst.type==UNSIGNED_INT)
+ cnst.i_value = *(op+3);
+ else if(cnst.type==FLOAT)
+ cnst.f_value = *reinterpret_cast<const float *>(&*(op+3));
}
void SpirVModule::Reflection::reflect_variable(CodeIterator op)
var.type = type.type;
var.struct_type = type.struct_type;
var.array_size = type.array_size;
+ var.array_size_spec = type.array_size_spec;
}
void SpirVModule::Reflection::reflect_decorate(CodeIterator op)
switch(decoration)
{
case DECO_SPEC_ID:
- spec_constants[id].constant_id = *op;
+ constants[id].constant_id = *op;
break;
case DECO_ARRAY_STRIDE:
types[id].array_stride = *op;