[Bf-blender-cvs] [18815cf] object_nodes: First test of the VM evaluation function.

Lukas Tönne noreply at git.blender.org
Tue Nov 24 09:43:00 CET 2015


Commit: 18815cfaaff301c9124160f4fb1391e18c026ba7
Author: Lukas Tönne
Date:   Sun Oct 18 15:48:09 2015 +0200
Branches: object_nodes
https://developer.blender.org/rB18815cfaaff301c9124160f4fb1391e18c026ba7

First test of the VM evaluation function.

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

M	source/blender/blenvm/CMakeLists.txt
M	source/blender/blenvm/intern/bvm_api.cc
M	source/blender/blenvm/intern/bvm_codegen.cc
M	source/blender/blenvm/intern/bvm_codegen.h
M	source/blender/blenvm/intern/bvm_eval.cc
M	source/blender/blenvm/intern/bvm_eval.h
M	source/blender/blenvm/intern/bvm_expression.cc
M	source/blender/blenvm/intern/bvm_expression.h
M	source/blender/blenvm/intern/bvm_nodegraph.h
A	source/blender/blenvm/intern/bvm_opcode.h
M	source/blender/blenvm/intern/bvm_type_desc.h

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

diff --git a/source/blender/blenvm/CMakeLists.txt b/source/blender/blenvm/CMakeLists.txt
index 762cc10..6964a80 100644
--- a/source/blender/blenvm/CMakeLists.txt
+++ b/source/blender/blenvm/CMakeLists.txt
@@ -52,6 +52,7 @@ set(SRC
 	intern/bvm_function.h
 	intern/bvm_module.h
 	intern/bvm_nodegraph.h
+	intern/bvm_opcode.h
 	intern/bvm_schedule.h
 	intern/bvm_type_desc.h
 
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index cc242d2..18af7e2 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -131,10 +131,10 @@ struct BVMExpression *BVM_gen_forcefield_expression(bNodeTree *btree)
 	using namespace bvm;
 	
 	NodeGraph graph;
-	
 	gen_forcefield_nodegraph(btree, graph);
 	
-	Expression *expr = codegen_expression(graph);
+	BVMCompiler compiler;
+	Expression *expr = compiler.codegen_expression(graph);
 	
 	return (BVMExpression *)expr;
 }
diff --git a/source/blender/blenvm/intern/bvm_codegen.cc b/source/blender/blenvm/intern/bvm_codegen.cc
index 206ceef..ff8a4ba 100644
--- a/source/blender/blenvm/intern/bvm_codegen.cc
+++ b/source/blender/blenvm/intern/bvm_codegen.cc
@@ -29,22 +29,90 @@
  *  \ingroup bvm
  */
 
+#include <cstdio>
+
 #include "bvm_codegen.h"
-#include "bvm_expression.h"
+#include "bvm_eval.h"
 #include "bvm_nodegraph.h"
 
 namespace bvm {
 
-Expression *codegen_expression(const NodeGraph &graph)
+BVMCompiler::BVMCompiler() :
+    expr(NULL)
+{
+	stack_users.resize(BVM_STACK_SIZE, 0);
+}
+
+BVMCompiler::~BVMCompiler()
+{
+}
+
+StackIndex BVMCompiler::find_stack_index(int size) const
+{
+	int unused = 0;
+	
+	for (int i = 0; i < BVM_STACK_SIZE; ++i) {
+		if (stack_users[i] == 0) {
+			++unused;
+			if (unused == size)
+				return i + 1 - size;
+		}
+		else
+			unused = 0;
+	}
+	
+	// TODO better reporting ...
+	printf("ERROR: out of stack space");
+	
+	return BVM_STACK_INVALID;
+}
+
+void BVMCompiler::assign_stack_index(ReturnValue &rval)
+{
+	int size = rval.typedesc.stack_size();
+	
+	rval.stack_offset = find_stack_index(size);
+	for (int i = 0; i < size; ++i) {
+		// TODO keep track of value users
+		stack_users[rval.stack_offset + i] += 1;
+	}
+}
+
+void BVMCompiler::push_opcode(OpCode op)
+{
+	expr->add_instruction(op);
+}
+
+void BVMCompiler::push_stack_index(StackIndex arg)
 {
-	Expression *expr = new Expression();
+	if (arg != BVM_STACK_INVALID)
+		expr->add_instruction(arg);
+}
+
+void BVMCompiler::push_float(float f)
+{
+	expr->add_instruction(float_to_instruction(f));
+}
+
+void BVMCompiler::push_float3(float3 f)
+{
+	expr->add_instruction(float_to_instruction(f.x));
+	expr->add_instruction(float_to_instruction(f.y));
+	expr->add_instruction(float_to_instruction(f.z));
+}
+
+Expression *BVMCompiler::codegen_expression(const NodeGraph &graph)
+{
+	expr = new Expression();
 	
 	for (NodeGraph::OutputList::const_iterator it = graph.outputs.begin();
 	     it != graph.outputs.end();
 	     ++it) {
 		const NodeGraphOutput &output = *it;
 		
-		expr->add_return_value(TypeDesc(output.type), output.name);
+		ReturnValue &rval = expr->add_return_value(TypeDesc(output.type), output.name);
+		
+		assign_stack_index(rval);
 	}
 	
 	for (NodeGraph::NodeInstanceMap::const_iterator it = graph.nodes.begin();
@@ -54,7 +122,19 @@ Expression *codegen_expression(const NodeGraph &graph)
 		
 	}
 	
-	return expr;
+	// XXX TESTING
+	{
+		push_opcode(OP_VALUE_FLOAT3);
+		push_float3(float3(0.3, -0.6, 0.0));
+		push_stack_index(expr->return_value(0).stack_offset);
+//		push_stack_index(0x0F);
+//		push_opcode(OP_ASSIGN_FLOAT3);
+		push_opcode(OP_END);
+	}
+	
+	Expression *result = expr;
+	expr = NULL;
+	return result;
 }
 
 } /* namespace bvm */
diff --git a/source/blender/blenvm/intern/bvm_codegen.h b/source/blender/blenvm/intern/bvm_codegen.h
index 79d6063..5eec0c5 100644
--- a/source/blender/blenvm/intern/bvm_codegen.h
+++ b/source/blender/blenvm/intern/bvm_codegen.h
@@ -32,14 +32,39 @@
  *  \ingroup bvm
  */
 
+#include <vector>
+
+#include "bvm_expression.h"
+#include "bvm_opcode.h"
 #include "bvm_util_string.h"
 
 namespace bvm {
 
 struct Expression;
 struct NodeGraph;
+struct TypeDesc;
+struct ReturnValue;
 
-Expression *codegen_expression(const NodeGraph &graph);
+struct BVMCompiler {
+	typedef std::vector<int> StackUsers;
+	
+	BVMCompiler();
+	~BVMCompiler();
+	
+	StackIndex find_stack_index(int size) const;
+	void assign_stack_index(ReturnValue &rval);
+	
+	void push_opcode(OpCode op);
+	void push_stack_index(StackIndex arg);
+	void push_float(float f);
+	void push_float3(float3 f);
+	
+	Expression *codegen_expression(const NodeGraph &graph);
+	
+private:
+	StackUsers stack_users;
+	Expression *expr;
+};
 
 } /* namespace bvm */
 
diff --git a/source/blender/blenvm/intern/bvm_eval.cc b/source/blender/blenvm/intern/bvm_eval.cc
index ebb06d3..2c1aef8 100644
--- a/source/blender/blenvm/intern/bvm_eval.cc
+++ b/source/blender/blenvm/intern/bvm_eval.cc
@@ -29,6 +29,8 @@
  *  \ingroup bvm
  */
 
+#include <cassert>
+
 #include "bvm_eval.h"
 #include "bvm_expression.h"
 
@@ -42,9 +44,103 @@ EvalContext::~EvalContext()
 {
 }
 
+inline static float stack_load_float(float *stack, StackIndex offset)
+{
+	return *(float *)(&stack[offset]);
+}
+
+inline static float3 stack_load_float3(float *stack, StackIndex offset)
+{
+	return *(float3 *)(&stack[offset]);
+}
+
+inline static void stack_store_float(float *stack, StackIndex offset, float f)
+{
+	*(float *)(&stack[offset]) = f;
+}
+
+inline static void stack_store_float3(float *stack, StackIndex offset, float3 f)
+{
+	*(float3 *)(&stack[offset]) = f;
+}
+
+static void eval_op_value_float(float *stack, float value, StackIndex offset)
+{
+	stack_store_float(stack, offset, value);
+}
+
+static void eval_op_value_float3(float *stack, float3 value, StackIndex offset)
+{
+	stack_store_float3(stack, offset, value);
+}
+
+static void eval_op_assign_float(float *stack, StackIndex offset_to, StackIndex offset_from)
+{
+	float f = stack_load_float(stack, offset_from);
+	stack_store_float(stack, offset_to, f);
+}
+
+static void eval_op_assign_float3(float *stack, StackIndex offset_to, StackIndex offset_from)
+{
+	float3 f = stack_load_float3(stack, offset_from);
+	stack_store_float3(stack, offset_to, f);
+}
+
+void EvalContext::eval_instructions(const Expression &expr, float *stack) const
+{
+	int instr = 0;
+	
+	while (true) {
+		OpCode op = expr.read_opcode(&instr);
+		
+		switch(op) {
+			case OP_NOOP:
+				break;
+			case OP_VALUE_FLOAT: {
+				float value = expr.read_float(&instr);
+				StackIndex offset = expr.read_stack_index(&instr);
+				eval_op_value_float(stack, value, offset);
+				break;
+			}
+			case OP_VALUE_FLOAT3: {
+				float3 value = expr.read_float3(&instr);
+				StackIndex offset = expr.read_stack_index(&instr);
+				eval_op_value_float3(stack, value, offset);
+				break;
+			}
+			case OP_ASSIGN_FLOAT: {
+				int offset_to = instr++;
+				int offset_from = instr++;
+				eval_op_assign_float(stack, offset_to, offset_from);
+				break;
+			}
+			case OP_ASSIGN_FLOAT3: {
+				int offset_to = instr++;
+				int offset_from = instr++;
+				eval_op_assign_float3(stack, offset_to, offset_from);
+				break;
+			}
+			case OP_END:
+				return;
+			default:
+				assert(!"Unknown opcode");
+				return;
+		}
+	}
+}
+
 void EvalContext::eval_expression(const Expression &expr, void **results) const
 {
+	float stack[BVM_STACK_SIZE];
+	
+	eval_instructions(expr, stack);
 	
+	for (int i = 0; i < expr.return_values_size(); ++i) {
+		const ReturnValue &rval = expr.return_value(i);
+		float *value = &stack[rval.stack_offset];
+		
+		rval.typedesc.copy_value(results[i], (void *)value);
+	}
 }
 
 } /* namespace bvm */
diff --git a/source/blender/blenvm/intern/bvm_eval.h b/source/blender/blenvm/intern/bvm_eval.h
index f4dd17c..fe4d874 100644
--- a/source/blender/blenvm/intern/bvm_eval.h
+++ b/source/blender/blenvm/intern/bvm_eval.h
@@ -32,6 +32,8 @@
  *  \ingroup bvm
  */
 
+#include <vector>
+
 #include "bvm_type_desc.h"
 
 #include "bvm_util_map.h"
@@ -41,6 +43,8 @@ namespace bvm {
 
 struct Expression;
 
+#define BVM_STACK_SIZE 255
+
 #if 0
 struct EvalResult {
 	typedef unordered_map<string, Value> ValueMap;
@@ -66,6 +70,9 @@ struct EvalContext {
 	~EvalContext();
 	
 	void eval_expression(const Expression &expr, void **results) const;
+	
+protected:
+	void eval_instructions(const Expression &expr, float *stack) const;
 };
 
 } /* namespace bvm */
diff --git a/source/blender/blenvm/intern/bvm_expression.cc b/source/blender/blenvm/intern/bvm_expression.cc
index af8983f..4612422 100644
--- a/source/blender/blenvm/intern/bvm_expression.cc
+++ b/source/blender/blenvm/intern/bvm_expression.cc
@@ -43,9 +43,15 @@ Expression::~Expression()
 {
 }
 
-void Expression::add_return_value(const TypeDesc &typedesc, const string &name)
+void Expression::add_instruction(Instruction v)
+{
+	instructions.push_back(v);
+}
+
+ReturnValue &Expression::add_return_value(const TypeDesc &typedesc, const string &name)
 {
 	return_values.push_back(ReturnValue(typedesc, name));
+	return return_values.back();
 }
 
 size_t Expression::return_values_size() const
@@ -53,12 +59,12 @@ size_t Expression::return_values_size() const
 	return return_values.size();
 }
 
-const Expression::ReturnValue &Expression::return_value(size_t index) const
+const ReturnValue &Expression::return_value(size_t index) const
 {
 	return return_values[index];
 }
 
-const Expression::ReturnValue &Expression::return_value(const string &name) const
+const ReturnValue &Expression::return_value(const string &name) const
 {
 	for (ReturnValueList::const_iterator it = return_values.begin(); it != return_values.end(); ++it)
 		if ((*it).name == name)
diff --git a/source/blender/blenvm/intern/bvm_expression.h b/source/blender/blenvm/intern/bvm_expression.h
index 9b92a17..c240627 100644
--- a/source/blender/blenvm/intern/bvm_expression.h
+++ b/source/blender/blenvm/intern/bvm_expression.h
@@ -35,38 +35,80 @@
 #include <vector>
 #include <stdint.h>
 
+#include "bvm_opcode.h"
 #include "bvm_type_desc.h"
 #include "bvm_util_string.h"
 
 namespace bvm {
 
-typedef int32_t Instruction;
-typedef std::vector<Instruction> InstructionList;
+typedef uint32_t Instruction;
+typedef Instructio

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list