Commit: 2030217042ef4ad83ce292f3ec80308689d00ab9
Author: Lukas Tönne
Date:   Tue May 24 18:14:11 2016 +0200
Branches: object_nodes
https://developer.blender.org/rB2030217042ef4ad83ce292f3ec80308689d00ab9

Use derivative functions for calculating dual values using the forward 
accumulation method.

Only a few functions have derivatives defined yet.

===================================================================

M       source/blender/blenvm/llvm/llvm_compiler.h
M       source/blender/blenvm/llvm/llvm_compiler_dual.cc
M       source/blender/blenvm/llvm/llvm_engine.cc
M       source/blender/blenvm/llvm/llvm_engine.h
M       source/blender/blenvm/llvm/llvm_modules.cc
M       source/blender/blenvm/llvm/llvm_modules.h
M       source/blender/blenvm/modules/mod_defines.h
M       source/blender/blenvm/modules/mod_math.h

===================================================================

diff --git a/source/blender/blenvm/llvm/llvm_compiler.h 
b/source/blender/blenvm/llvm/llvm_compiler.h
index 4579095..535150a 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.h
+++ b/source/blender/blenvm/llvm/llvm_compiler.h
@@ -72,8 +72,7 @@ struct LLVMCompilerBase {
        FunctionLLVM *compile_function(const string &name, const NodeGraph 
&graph, int opt_level);
        void debug_function(const string &name, const NodeGraph &graph, int 
opt_level, FILE *file);
        
-       /* XXX TODO some methods are used by static template functions, which 
require public access ... */
-//protected:
+protected:
        LLVMCompilerBase();
        
        llvm::LLVMContext &context() const;
@@ -130,7 +129,9 @@ private:
 
 struct LLVMTextureCompiler : public LLVMCompilerBase {
        llvm::Type *get_value_type(const TypeSpec *spec, bool is_constant);
-       llvm::Function *declare_elementary_node_function(llvm::Module *mod, 
const NodeType *nodetype, const string &name);
+       llvm::Function *declare_elementary_node_function(
+               llvm::Module *mod, const NodeType *nodetype, const string &name,
+               bool with_derivatives);
        
        llvm::Module *get_nodes_module() const { return m_nodes_module; }
        
@@ -140,8 +141,8 @@ struct LLVMTextureCompiler : public LLVMCompilerBase {
        llvm::Constant *create_node_value_constant(const NodeValue *node_value);
        
        bool set_node_function_impl(OpCode op, const NodeType *nodetype,
-                                   llvm::Function *value_func,
-                                   std::vector<llvm::Function*> deriv_funcs);
+                                   llvm::Function *value_func, llvm::Function 
* dual_func);
+       void define_elementary_functions(OpCode op, llvm::Module *mod, const 
string &nodetype_name);
        void define_dual_function_wrapper(llvm::Module *mod, const string 
&nodetype_name);
        void define_nodes_module();
        
diff --git a/source/blender/blenvm/llvm/llvm_compiler_dual.cc 
b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
index 91ebb0e..340f979 100644
--- a/source/blender/blenvm/llvm/llvm_compiler_dual.cc
+++ b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
@@ -127,31 +127,46 @@ llvm::Constant 
*LLVMTextureCompiler::create_node_value_constant(const NodeValue
        return bvm_create_llvm_constant(context(), node_value);
 }
 
-llvm::Function 
*LLVMTextureCompiler::declare_elementary_node_function(llvm::Module *mod, const 
NodeType *nodetype, const string &name)
+llvm::Function *LLVMTextureCompiler::declare_elementary_node_function(
+        llvm::Module *mod, const NodeType *nodetype, const string &name,
+        bool with_derivatives)
 {
        using namespace llvm;
        
+       bool error;
+       
        std::vector<Type *> input_types, output_types;
        for (int i = 0; i < nodetype->num_inputs(); ++i) {
                const NodeInput *input = nodetype->find_input(i);
                const TypeSpec *typespec = input->typedesc.get_typespec();
+               
                Type *type = bvm_get_llvm_type(context(), typespec, false);
-               if (type == NULL)
+               if (type == NULL) {
+                       error = true;
                        break;
+               }
                if (use_elementary_argument_pointer(typespec))
                        type = type->getPointerTo();
+               
                input_types.push_back(type);
+               if (with_derivatives && bvm_type_has_dual_value(typespec)) {
+                       /* second argument for derivative */
+                       input_types.push_back(type);
+               }
        }
        for (int i = 0; i < nodetype->num_outputs(); ++i) {
                const NodeOutput *output = nodetype->find_output(i);
                const TypeSpec *typespec = output->typedesc.get_typespec();
+               
                Type *type = bvm_get_llvm_type(context(), typespec, false);
-               if (type == NULL)
+               if (type == NULL) {
+                       error = true;
                        break;
+               }
+               
                output_types.push_back(type);
        }
-       if (input_types.size() != nodetype->num_inputs() ||
-           output_types.size() != nodetype->num_outputs()) {
+       if (error) {
                /* some arguments could not be handled */
                return NULL;
        }
@@ -162,28 +177,22 @@ llvm::Function 
*LLVMTextureCompiler::declare_elementary_node_function(llvm::Modu
        return func;
 }
 
-bool LLVMTextureCompiler::set_node_function_impl(OpCode op, const NodeType 
*nodetype,
-                                                     llvm::Function 
*value_func,
-                                                     
std::vector<llvm::Function*> deriv_funcs)
+bool LLVMTextureCompiler::set_node_function_impl(OpCode op, const NodeType 
*UNUSED(nodetype),
+                                                 llvm::Function *value_func, 
llvm::Function *deriv_func)
 {
        using namespace llvm;
        
        typedef std::vector<Value*> ValueList;
        
+       /* XXX TODO needs implementation for derivatives */
+       UNUSED_VARS(deriv_func);
+       return false;
+       
        ValueList value_args;
        value_args.reserve(value_func->arg_size());
        for (Function::arg_iterator a = value_func->arg_begin(); a != 
value_func->arg_end(); ++a)
                value_args.push_back(a);
        
-#if 0 /* TODO only do the value function for now */
-       std::vector<ValueList> deriv_args(nodetype->num_inputs());
-       for (int n = 0; n < nodetype->num_inputs(); ++n) {
-               deriv_args[n].reserve(deriv_funcs[n]->arg_size());
-               for (Function::arg_iterator a = deriv_funcs[n]->arg_begin(); a 
!= deriv_funcs[n]->arg_end(); ++a)
-                       deriv_args[n].push_back(a);
-       }
-#endif
-       
        switch (op) {
                case OP_VALUE_FLOAT: {
                        BasicBlock *block = BasicBlock::Create(context(), 
"entry", value_func);
@@ -216,8 +225,7 @@ bool LLVMTextureCompiler::set_node_function_impl(OpCode op, 
const NodeType *node
        }
 }
 
-template <OpCode op>
-static void define_elementary_functions(LLVMTextureCompiler &C, llvm::Module 
*mod, const string &nodetype_name)
+void LLVMTextureCompiler::define_elementary_functions(OpCode op, llvm::Module 
*mod, const string &nodetype_name)
 {
        using namespace llvm;
        
@@ -225,19 +233,18 @@ static void 
define_elementary_functions(LLVMTextureCompiler &C, llvm::Module *mo
        if (nodetype == NULL)
                return;
        
-       string value_name = llvm_value_function_name(nodetype->name());
        /* declare function */
-       Function *value_func = C.declare_elementary_node_function(mod, 
nodetype, value_name);
-       /* declare partial derivatives wrt. the input arguments */
-       std::vector<Function *> deriv_funcs(nodetype->num_inputs());
-#if 0 /* TODO only do the value function for now */
-       for (int arg_n = -1; arg_n < nodetype->num_inputs(); ++arg_n) {
-               string deriv_name = llvm_deriv_function_name(nodetype->name(), 
arg_n);
-               deriv_funcs[arg_n] = C.declare_elementary_node_function(mod, 
nodetype, deriv_name);
+       BLI_assert(llvm_has_external_impl_value(op));
+       Function *value_func = declare_elementary_node_function(
+                                  mod, nodetype, 
llvm_value_function_name(nodetype->name()), false);
+       
+       Function *deriv_func = NULL;
+       if (llvm_has_external_impl_deriv(op)) {
+               deriv_func = declare_elementary_node_function(
+                               mod, nodetype, 
llvm_deriv_function_name(nodetype->name()), true);
        }
-#endif
        
-       C.set_node_function_impl(op, nodetype, value_func, deriv_funcs);
+       set_node_function_impl(op, nodetype, value_func, deriv_func);
 }
 
 void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, 
const string &nodetype_name)
@@ -253,13 +260,8 @@ void 
LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const
        Function *value_func = llvm_find_external_function(mod, value_name);
        BLI_assert(value_func != NULL && "Could not find node function!");
        
-#if 0 /* TODO only do the value function for now */
-       std::vector<Function *> deriv_funcs(nodetype->num_inputs());
-       for (int n = -1; n < nodetype->num_inputs(); ++n) {
-               string deriv_name = llvm_deriv_function_name(nodetype->name(), 
n);
-               deriv_funcs[n] = llvm_find_external_function(mod, deriv_name);
-       }
-#endif
+       string deriv_name = llvm_deriv_function_name(nodetype->name());
+       Function *deriv_func = llvm_find_external_function(mod, deriv_name);
        
        /* wrapper function */
        Function *func = declare_node_function(mod, nodetype);
@@ -275,7 +277,7 @@ void 
LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const
        std::vector<Value*> in_value, in_dx, in_dy;
        std::vector<Value*> out_value, out_dx, out_dy; 
        /* arguments for calculating main value and partial derivatives */
-       std::vector<Value*> call_args;
+       std::vector<Value*> call_args_value, call_args_dx, call_args_dy;
        
        Function::arg_iterator arg_it = func->arg_begin();
        /* output arguments */
@@ -297,7 +299,10 @@ void 
LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const
                out_value.push_back(val);
                out_dx.push_back(dx);
                out_dy.push_back(dy);
-               call_args.push_back(val);
+               
+               call_args_value.push_back(val);
+               call_args_dx.push_back(dx);
+               call_args_dy.push_back(dy);
        }
        /* input arguments */
        for (int i = 0; i < nodetype->num_inputs(); ++i, ++arg_it) {
@@ -325,22 +330,27 @@ void 
LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod, const
                in_value.push_back(val);
                in_dx.push_back(dx);
                in_dy.push_back(dy);
-               call_args.push_back(val);
+               
+               call_args_value.push_back(val);
+               
+               /* derivative functions take input value as well as its 
derivative */
+               call_args_dx.push_back(val);
+               call_args_dx.push_back(dx);
+               
+               call_args_dy.push_back(val);
+               call_args_dy.push_back(dy);
        }
        
        /* calculate value */
-       builder.CreateCall(value_func, call_args);
-#if 0 /* TODO only do the value function for now */
-       /* calculate partial derivatives wrt. each input */
-       for (int i = 0; i < nodetype->num_inputs(); ++i, ++arg_it) {
-               const NodeInput *input = nodetype->find_input(i);
-               const TypeSpec *typespec = input->typedesc.get_typespec();
+       builder.CreateCall(value_func, call_args_value);
+       
+       if (deriv_func) {
+               builder.CreateCall(deriv_func, call_args_dx);
+               builder.CreateCall(deriv_func, call_args_dy);
+       }
+       else {
                
-               if (deriv_funcs[i] != NULL) {
-                       
-               }
        }
-#endif
        
        builder.CreateRetVoid();
 }
@@ -352,7 +362,7 @@ void LLVMTextureCompiler::define_nodes_module()
        Module *mod = new llvm::Module("texture_nodes", context());
        
 #define DEF_OPCODE(op) \
-       define_elementary_functions<OP_##op>(*this, mod, STRINGIFY(op));
+       define_elementary_functions(OP_##op, mod, STRINGIFY(op));
        
        BVM_DEFINE_OPCODES
        
diff --git a/source/blender/blenvm/llvm/llvm_engine.cc 
b/source/blender/blenvm/llvm/llvm_engine.cc
index a5f1f8a..7223f0c 100644
--- a/source/blender/blenvm/llvm/llvm_engine.cc
+++ b/source/blender/blenvm/llvm/l

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to