[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