]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/module.cpp
Support compute shaders and compute operations
[libs/gl.git] / source / core / module.cpp
index 636fd13cf4a84cd623ce481b3231fb731e112b85..8c69cd7e256673bb1887c61a9f82da31539f2cfb 100644 (file)
@@ -14,6 +14,7 @@ enum SpirVConstants
        OP_NAME = 5,
        OP_MEMBER_NAME = 6,
        OP_ENTRY_POINT = 15,
+       OP_EXECUTION_MODE = 16,
        OP_TYPE_VOID = 19,
        OP_TYPE_BOOL = 20,
        OP_TYPE_INT = 21,
@@ -47,6 +48,8 @@ enum SpirVConstants
        OP_RETURN_VALUE = 254,
        OP_UNREACHABLE = 255,
 
+       EXEC_LOCAL_SIZE = 17,
+
        DECO_SPEC_ID = 1,
        DECO_ARRAY_STRIDE = 6,
        DECO_MATRIX_STRIDE = 7,
@@ -237,6 +240,8 @@ void SpirVModule::reflect()
        {
                auto i = spec_indices.find(b.condition);
                b.condition = (i!=spec_indices.end() ? &spec_constants[i->second] : 0);
+               if(b.condition)
+                       specializable = true;
 
                for(const Variable *&v: b.accessed_variables)
                {
@@ -267,6 +272,8 @@ SpirVModule *SpirVModule::specialize(const map<string, int> &spec_values) const
                }
        }
 
+       for(const EntryPoint &e: entry_points)
+               flags[e.id] = 0;
        for(const Variable &v: variables)
                flags[v.id] = 0;
        for(const InstructionBlock &b: blocks)
@@ -305,9 +312,10 @@ SpirVModule *SpirVModule::specialize(const map<string, int> &spec_values) const
                                unsigned start = new_code.size();
                                new_code.push_back(opcode);
                                new_code.push_back(*(op+1));
-                               new_code.push_back(*(op+2));
+                               unsigned func_id = *(op+2);
+                               new_code.push_back(func_id);
 
-                               unsigned i=3;
+                               unsigned i = 3;
                                while(i<word_count)
                                {
                                        unsigned word = *(op+i++);
@@ -316,17 +324,29 @@ SpirVModule *SpirVModule::specialize(const map<string, int> &spec_values) const
                                                break;
                                }
 
+                               unsigned var_count = 0;
                                for(; i<word_count; ++i)
                                {
                                        unsigned id = *(op+i);
                                        if(flags[id])
+                                       {
+                                               ++var_count;
                                                new_code.push_back(id);
+                                       }
                                }
 
-                               new_code[start] |= (new_code.size()-start)<<16;
+                               if(var_count)
+                               {
+                                       flags[func_id] = 1;
+                                       new_code[start] |= (new_code.size()-start)<<16;
+                               }
+                               else
+                                       new_code.resize(start);
 
                                copy = false;
                        }
+                       else if(opcode==OP_EXECUTION_MODE)
+                               copy = flags[*(op+1)];
                        else if(opcode==OP_SPEC_CONSTANT_TRUE || opcode==OP_SPEC_CONSTANT_FALSE)
                        {
                                unsigned id = *(op+2);
@@ -495,6 +515,7 @@ void SpirVModule::Reflection::reflect_code(const vector<uint32_t> &code)
                case OP_NAME: reflect_name(op); break;
                case OP_MEMBER_NAME: reflect_member_name(op); break;
                case OP_ENTRY_POINT: reflect_entry_point(op); break;
+               case OP_EXECUTION_MODE: reflect_execution_mode(op); break;
                case OP_TYPE_VOID: reflect_void_type(op); break;
                case OP_TYPE_BOOL: reflect_bool_type(op); break;
                case OP_TYPE_INT: reflect_int_type(op); break;
@@ -561,6 +582,18 @@ void SpirVModule::Reflection::reflect_entry_point(CodeIterator op)
                entry.globals.push_back(&variables[*op]);
 }
 
+void SpirVModule::Reflection::reflect_execution_mode(CodeIterator op)
+{
+       EntryPoint &entry = entry_points[*(op+1)];
+       unsigned mode = *(op+2);
+       if(mode==EXEC_LOCAL_SIZE)
+       {
+               entry.compute_local_size.x = *(op+3);
+               entry.compute_local_size.y = *(op+4);
+               entry.compute_local_size.z = *(op+5);
+       }
+}
+
 void SpirVModule::Reflection::reflect_void_type(CodeIterator op)
 {
        types[*(op+1)].type = VOID;
@@ -605,11 +638,13 @@ void SpirVModule::Reflection::reflect_matrix_type(CodeIterator op)
 void SpirVModule::Reflection::reflect_image_type(CodeIterator op)
 {
        TypeInfo &type = types[*(op+1)];
-       DataType sample = types[*(op+2)].type;
+       DataType sample_type = types[*(op+2)].type;
        unsigned dimensions = *(op+3);
        bool depth = *(op+4)==1;
        bool array = *(op+5);
-       type.type = static_cast<DataType>((depth*0x200000) | (array*0x80000) | ((dimensions+1)<<16) | sample);
+       bool sampled = *(op+7)==1;
+       type.type = static_cast<DataType>((depth*0x200000) | (sampled*0x100000) | (array*0x80000) |
+               ((dimensions+1)<<16) | sample_type);
 }
 
 void SpirVModule::Reflection::reflect_sampled_image_type(CodeIterator op)