[Bf-blender-cvs] [1417635388e] nodes_playground: initial node compiler data structures
Jacques Lucke
noreply at git.blender.org
Sun Jan 6 17:25:14 CET 2019
Commit: 1417635388eee0b97cd1ba53a493c3c8eac8c296
Author: Jacques Lucke
Date: Thu Jan 3 16:09:07 2019 +0100
Branches: nodes_playground
https://developer.blender.org/rB1417635388eee0b97cd1ba53a493c3c8eac8c296
initial node compiler data structures
===================================================================
M source/blender/modifiers/CMakeLists.txt
M source/blender/modifiers/intern/MOD_custom.c
M source/blender/modifiers/intern/MOD_custom_compiler.cc
A source/blender/modifiers/intern/node_compiler.cpp
A source/blender/modifiers/intern/node_compiler.hpp
A source/blender/modifiers/intern/node_compiler_testing.cpp
===================================================================
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index d47f737b121..f2909be8cab 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -115,6 +115,10 @@ set(SRC
intern/MOD_meshcache_util.h
intern/MOD_util.h
intern/MOD_weightvg_util.h
+
+ intern/node_compiler_testing.cpp
+ intern/node_compiler.cpp
+ intern/node_compiler.hpp
)
if(WITH_ALEMBIC)
diff --git a/source/blender/modifiers/intern/MOD_custom.c b/source/blender/modifiers/intern/MOD_custom.c
index 6f88f0e6285..d783e7dd1de 100644
--- a/source/blender/modifiers/intern/MOD_custom.c
+++ b/source/blender/modifiers/intern/MOD_custom.c
@@ -43,13 +43,13 @@
#include "DEG_depsgraph.h"
-void test_llvm(void);
+void run_tests(void);
static Mesh *applyModifier(
ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx),
Mesh *UNUSED(mesh))
{
- test_llvm();
+ run_tests();
Mesh *new_mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0);
new_mesh->mvert[0].co[0] = 1;
new_mesh->mvert[0].co[1] = 2;
diff --git a/source/blender/modifiers/intern/MOD_custom_compiler.cc b/source/blender/modifiers/intern/MOD_custom_compiler.cc
index 376711c2597..85895f4d095 100644
--- a/source/blender/modifiers/intern/MOD_custom_compiler.cc
+++ b/source/blender/modifiers/intern/MOD_custom_compiler.cc
@@ -5,6 +5,8 @@
#include <vector>
#include <memory>
+#include <functional>
+#include <unordered_set>
extern "C" {
void test_llvm(void);
@@ -52,7 +54,3 @@ void test_llvm() {
printf("Result: %d\n", add(43, 10));
}
-typedef llvm::Value *(*InputGetter)(llvm::IRBuilder<> *builder, int index);
-typedef void (*OutputSetter)(llvm::IRBuilder<> *builder, int index, llvm::Value *value);
-typedef llvm::Value *(*RequiredGetter)(llvm::IRBuilder<> *builder, int index);
-typedef void (*GenNodeCode)(void *data, InputGetter getters[], OutputSetter setters[], RequiredGetter required[]);
diff --git a/source/blender/modifiers/intern/node_compiler.cpp b/source/blender/modifiers/intern/node_compiler.cpp
new file mode 100644
index 00000000000..f17ea09b46a
--- /dev/null
+++ b/source/blender/modifiers/intern/node_compiler.cpp
@@ -0,0 +1,117 @@
+#include "node_compiler.hpp"
+
+#include <sstream>
+
+namespace NodeCompiler {
+
+AnySocket LinkSet::getOriginSocket(AnySocket socket) const
+{
+ assert(socket.is_input());
+
+ for (Link link : this->links) {
+ if (link.to == socket) {
+ return link.from;
+ }
+ }
+
+ assert(!"every input socket needs an origin");
+}
+
+AnySocket Graph::getOriginSocket(AnySocket socket) const
+{
+ return this->links.getOriginSocket(socket);
+}
+
+const SocketInfo *AnySocket::info() const
+{
+ if (this->is_input()) {
+ return &this->node()->inputs[this->index()];
+ }
+ else {
+ return &this->node()->outputs[this->index()];
+ }
+}
+
+const llvm::Type *AnySocket::type() const
+{
+ return this->info()->type;
+}
+
+const std::string &AnySocket::debug_name() const
+{
+ return this->info()->debug_name;
+}
+
+std::string SimpleNode::debug_id() const
+{
+ std::stringstream ss;
+ ss << this->debug_name << " at " << (void *)this;
+ return ss.str();
+}
+
+void Graph::generateCode(
+ llvm::IRBuilder<> &builder,
+ std::vector<AnySocket> &inputs, std::vector<AnySocket> &outputs, std::vector<llvm::Value *> &input_values,
+ llvm::IRBuilder<> *r_builder, std::vector<llvm::Value *> *r_output_values)
+{
+
+}
+
+SocketSet Graph::findRequiredSockets(std::vector<AnySocket> &inputs, std::vector<AnySocket> &outputs)
+{
+ SocketSet required_sockets;
+
+ for (AnySocket socket : outputs) {
+ this->findRequiredSockets(socket, inputs, required_sockets);
+ }
+
+ return required_sockets;
+}
+
+void Graph::findRequiredSockets(AnySocket socket, std::vector<AnySocket> &inputs, SocketSet &required_sockets)
+{
+ if (required_sockets.find(socket) != required_sockets.end()) {
+ // already found
+ return;
+ }
+
+ required_sockets.insert(socket);
+
+ if (std::find(inputs.begin(), inputs.end(), socket) != inputs.end()) {
+ // is input
+ return;
+ }
+
+ if (socket.is_input()) {
+ AnySocket origin = this->getOriginSocket(socket);
+ this->findRequiredSockets(origin, inputs, required_sockets);
+ }
+ else {
+ for (uint i = 0; i < socket.node()->inputs.size(); i++) {
+ AnySocket input = AnySocket::NewInput(socket.node(), i);
+ this->findRequiredSockets(input, inputs, required_sockets);
+ }
+ }
+}
+
+std::string Graph::toDotFormat(std::vector<SimpleNode *> marked_nodes) const
+{
+ std::stringstream ss;
+ ss << "digraph MyGraph {" << std::endl;
+
+ for (SimpleNode *node : this->nodes) {
+ ss << " \"" << node->debug_id() << "\" [style=\"filled\", fillcolor=\"#FFFFFF\"]" << std::endl;
+ }
+ for (Link link : this->links.links) {
+ ss << " \"" << link.from.node()->debug_id() << "\" -> \"" << link.to.node()->debug_id() << "\"" << std::endl;
+ }
+
+ for (SimpleNode *node : marked_nodes) {
+ ss << " \"" << node->debug_id() << "\" [fillcolor=\"#FFAAAA\"]" << std::endl;
+ }
+
+ ss << "}" << std::endl;
+ return ss.str();
+}
+
+} /* namespace NodeCompiler */
\ No newline at end of file
diff --git a/source/blender/modifiers/intern/node_compiler.hpp b/source/blender/modifiers/intern/node_compiler.hpp
new file mode 100644
index 00000000000..5708fb3d380
--- /dev/null
+++ b/source/blender/modifiers/intern/node_compiler.hpp
@@ -0,0 +1,118 @@
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+
+#include <vector>
+#include <memory>
+#include <functional>
+#include <unordered_set>
+
+namespace NodeCompiler {
+
+struct AnySocket;
+struct SocketInfo;
+struct SimpleNode;
+struct Link;
+struct LinkSet;
+struct Graph;
+
+struct AnySocket {
+ inline bool is_output() const { return this->_is_output; }
+ inline bool is_input() const { return !this->_is_output; }
+ inline SimpleNode *node() const { return this->_node; }
+ inline uint index() const { return this->_index; }
+
+ const llvm::Type *type() const;
+ const std::string &debug_name() const;
+
+ inline static AnySocket NewInput(SimpleNode *node, uint index)
+ { return AnySocket(node, false, index); }
+
+ inline static AnySocket NewOutput(SimpleNode *node, uint index)
+ { return AnySocket(node, true, index); }
+
+ friend bool operator==(const AnySocket &left, const AnySocket &right)
+ {
+ return (
+ left._node == right._node
+ && left._is_output == right._is_output
+ && left._index == right._index);
+ }
+
+private:
+ AnySocket(SimpleNode *node, bool is_output, uint index)
+ : _node(node), _is_output(is_output), _index(index) {}
+
+ const SocketInfo *info() const;
+
+ SimpleNode *_node;
+ bool _is_output;
+ uint _index;
+};
+
+struct SocketInfo {
+ const std::string debug_name;
+ const llvm::Type *type;
+
+ SocketInfo(std::string debug_name, llvm::Type *type)
+ : debug_name(debug_name), type(type) {}
+};
+
+struct SimpleNode {
+ std::string debug_name;
+ std::vector<SocketInfo> inputs;
+ std::vector<SocketInfo> outputs;
+ std::function<void(
+ std::vector<llvm::Value *> &inputs, llvm::IRBuilder<> *builder,
+ std::vector<llvm::Value *> &r_outputs, llvm::IRBuilder<> **r_builder)> generateCode;
+
+ std::string debug_id() const;
+
+ inline AnySocket Input(uint index)
+ { return AnySocket::NewInput(this, index); }
+ inline AnySocket Output(uint index)
+ { return AnySocket::NewOutput(this, index); }
+};
+
+struct Link {
+ AnySocket from, to;
+
+ Link(AnySocket from, AnySocket to)
+ : from(from), to(to) {}
+};
+
+struct LinkSet {
+ std::vector<Link> links;
+
+ AnySocket getOriginSocket(AnySocket socket) const;
+};
+
+struct AnySocketHash {
+ size_t operator()(const AnySocket &socket) const
+ {
+ return (size_t)socket.node() ^ (size_t)socket.is_input() ^ (size_t)socket.index();
+ }
+};
+
+typedef std::unordered_set<AnySocket, AnySocketHash> SocketSet;
+
+struct Graph {
+ std::vector<SimpleNode *> nodes;
+ LinkSet links;
+
+ void generateCode(
+ llvm::IRBuilder<> &builder,
+ std::vector<AnySocket> &inputs, std::vector<AnySocket> &outputs, std::vector<llvm::Value *> &input_values,
+ llvm::IRBuilder<> *r_builder, std::vector<llvm::Value *> *r_output_values);
+
+ AnySocket getOriginSocket(AnySocket socket) const;
+
+ std::string toDotFormat(std::vector<SimpleNode *> marked_nodes = {}) const;
+
+ SocketSet findRequiredSockets(std::vector<AnySocket> &inputs, std::vector<AnySocket> &outputs);
+private:
+ void findRequiredSockets(AnySocket socket, std::vector<AnySocket> &inputs, SocketSet &required_sockets);
+};
+
+} /* namespace NodeCompiler */
diff --git a/source/blender/modifiers/intern/node_compiler_testing.cpp b/source/blender/modifiers/intern/node_compiler_testing.cpp
new file mode 100644
index 00000000000..eaadd334808
--- /dev/null
+++ b/source/blender/modifiers/intern/node_compiler_testing.cpp
@@ -0,0 +1,91 @@
+#include "node_compiler.hpp"
+#include "BLI_utildefines.h"
+
+extern "C" {
+ void WM_clipboard_text_set(const char *buf, bool selection);
+}
+
+#include <iostream>
+
+namespace NC = NodeCompiler;
+
+static void generateCode_AddNode(
+ std::vector<llvm::Value *> &inputs, llvm::IRBuilder<> *builder,
+ std::vector<llvm::Value *> &r_outputs, llvm::IRBuilder<> **r_builder)
+{
+ llvm::Value *result = builder->CreateAdd(inputs[0], inputs[1]);
+ r_outputs.push_back(result);
+ *r_builder = builder;
+}
+
+static NC::SimpleNode *new_add_node(llvm::LLVMContext &context)
+{
+ auto node = new NC::SimpleNode();
+ node->debug_name = "Add";
+ node->inputs.push_back(NC::SocketInfo("A", llvm::Type::getInt32Ty(context)));
+ node->inputs.push_back(NC::SocketInfo("B", llvm::Type::getInt32Ty(context)));
+ node->outputs.push_back(NC::SocketInfo("Result", llvm::Type::getInt32Ty(context)));
+ node->generateCode = generateCode_AddNode;
+ return node;
+}
+
+static NC::SimpleNode *new_int_node(llvm::LLVMContext &context, int value)
+{
+ auto node = new NC::SimpleNode();
+ node->debug_name = "Int";
+ node->outputs.push_back(NC::SocketInfo("Value", llvm::Type::getInt32Ty(context)));
+ node->generateCode = [value](
+ std::vector<llvm::Value *> &UNUSED(inputs), llvm::IRBuilder<> *builder,
+ std::vector<llvm::Value *> &r_outputs, llvm::IRBuilder<> **r_builder) {
+ r_outputs.push_back(builder->getInt32
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list