]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/module.cpp
Redesign depth and stencil test and blend state management
[libs/gl.git] / source / core / module.cpp
index 374ef8ae4d71537fcfa36b37cdba910e63b7faf9..2474feaeb4cfffc8907caf4c1de730d40e5718cd 100644 (file)
@@ -127,6 +127,18 @@ void SpirVModule::load_code(IO::Base &io)
                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");
 
@@ -141,6 +153,14 @@ void SpirVModule::load_code(IO::Base &io)
        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)
@@ -158,6 +178,11 @@ void SpirVModule::load_code(IO::Base &io)
                                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();
@@ -167,6 +192,8 @@ void SpirVModule::load_code(IO::Base &io)
                        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;
                }
@@ -194,11 +221,18 @@ void SpirVModule::load_code(IO::Base &io)
        }
 
        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)
@@ -211,14 +245,6 @@ void SpirVModule::load_code(IO::Base &io)
                        *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");
 }
 
 
@@ -232,6 +258,7 @@ SpirVModule::StructMember::StructMember():
        struct_type(0),
        offset(0),
        array_size(0),
+       array_size_spec(0),
        array_stride(0),
        matrix_stride(0)
 { }
@@ -260,6 +287,7 @@ bool SpirVModule::Variable::operator==(const Variable &other) const
 SpirVModule::TypeInfo::TypeInfo():
        type(VOID),
        struct_type(0),
+       array_size_spec(0),
        array_size(0),
        array_stride(0),
        storage(static_cast<StorageClass>(-1))
@@ -303,7 +331,7 @@ void SpirVModule::Reflection::reflect_code(const vector<UInt32> &code)
        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))
@@ -322,12 +350,12 @@ void SpirVModule::Reflection::reflect_code(const vector<UInt32> &code)
                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;
@@ -433,11 +461,12 @@ void SpirVModule::Reflection::reflect_array_type(CodeIterator op)
        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)
@@ -457,6 +486,7 @@ 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;
        }
 }
@@ -469,23 +499,19 @@ void SpirVModule::Reflection::reflect_pointer_type(CodeIterator op)
 }
 
 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)
@@ -498,6 +524,7 @@ 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)
@@ -509,7 +536,7 @@ 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;