]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/spirv.cpp
Add a cached load when initializing a variable
[libs/gl.git] / source / glsl / spirv.cpp
index 52885342b004492a11cb8e4bb8c61d54801cea79..6ef58e909f1f2345c4468e5567da282749facfcb 100644 (file)
@@ -237,8 +237,28 @@ SpirVGenerator::Id SpirVGenerator::get_id(Node &node) const
 
 SpirVGenerator::Id SpirVGenerator::allocate_id(Node &node, Id type_id)
 {
+       map<Node *, Declaration>::iterator i = declared_ids.find(&node);
+       if(i!=declared_ids.end())
+       {
+               if(i->second.type_id)
+                       throw key_error(&node);
+               i->second.type_id = type_id;
+               return i->second.id;
+       }
+
+       Id id = next_id++;
+       declared_ids.insert(make_pair(&node, Declaration(id, type_id)));
+       return id;
+}
+
+SpirVGenerator::Id SpirVGenerator::allocate_forward_id(Node &node)
+{
+       map<Node *, Declaration>::iterator i = declared_ids.find(&node);
+       if(i!=declared_ids.end())
+               return i->second.id;
+
        Id id = next_id++;
-       insert_unique(declared_ids, &node, Declaration(id, type_id));
+       declared_ids.insert(make_pair(&node, Declaration(id, 0)));
        return id;
 }
 
@@ -1051,6 +1071,7 @@ void SpirVGenerator::visit(FunctionCall &call)
                throw internal_error("function call in constant expression");
 
        Id result_type_id = get_id(*call.type);
+       r_constant_result = false;
 
        if(call.constructor)
                visit_constructor(call, argument_ids, all_args_const);
@@ -1574,6 +1595,7 @@ void SpirVGenerator::visit(VariableDeclaration &var)
                {
                        SetFlag set_const(constant_expression, !current_function);
                        r_expression_result_id = 0;
+                       r_constant_result = false;
                        var.init_expression->visit(*this);
                        init_id = r_expression_result_id;
                }
@@ -1601,7 +1623,10 @@ void SpirVGenerator::visit(VariableDeclaration &var)
                }
 
                if(init_id && current_function)
+               {
                        writer.write_op(content.function_body, OP_STORE, var_id, init_id);
+                       variable_load_ids[&var] = init_id;
+               }
        }
 
        writer.write_op_name(var_id, var.name);
@@ -1704,8 +1729,14 @@ void SpirVGenerator::visit_entry_point(FunctionDeclaration &func, Id func_id)
 
 void SpirVGenerator::visit(FunctionDeclaration &func)
 {
-       if(func.source==BUILTIN_SOURCE || func.definition!=&func)
+       if(func.source==BUILTIN_SOURCE)
+               return;
+       else if(func.definition!=&func)
+       {
+               if(func.definition)
+                       allocate_forward_id(*func.definition);
                return;
+       }
 
        Id return_type_id = get_id(*func.return_type_declaration);
        vector<unsigned> param_type_ids;
@@ -1804,6 +1835,8 @@ void SpirVGenerator::visit(Iteration &iter)
        if(iter.init_statement)
                iter.init_statement->visit(*this);
 
+       variable_load_ids.clear();
+
        Id header_id = next_id++;
        Id continue_id = next_id++;
        Id merge_block_id = next_id++;
@@ -1831,7 +1864,6 @@ void SpirVGenerator::visit(Iteration &iter)
        writer.write_op(content.function_body, OP_BRANCH, header_id);
 
        writer.write_op_label(merge_block_id);
-       prune_loads(header_id);
        reachable = true;
 }