Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2016-06-02 18:30:33 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-06-02 18:30:33 +0300
commit570bbf680a58b6159792e22d6a1206e4a505bae4 (patch)
tree120cc39738fbc2ab83cb095b351e900aa3187e80 /source
parent8fda725b1873af2ca91e3e1999e82c02b9ff1863 (diff)
Support for image sampling in the LLVM backend.
This reintroduces the "globals" concept for mapping ID datablocks with a consistent permanent identifier key.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_texture.h6
-rw-r--r--source/blender/blenkernel/intern/texture.c45
-rw-r--r--source/blender/blenvm/BVM_api.h11
-rw-r--r--source/blender/blenvm/CMakeLists.txt4
-rw-r--r--source/blender/blenvm/bvm/CMakeLists.txt1
-rw-r--r--source/blender/blenvm/bvm/bvm_eval.cc64
-rw-r--r--source/blender/blenvm/bvm/bvm_eval.h40
-rw-r--r--source/blender/blenvm/compile/node_graph.cc6
-rw-r--r--source/blender/blenvm/compile/node_graph.h6
-rw-r--r--source/blender/blenvm/intern/bvm_api.cc33
-rw-r--r--source/blender/blenvm/llvm/CMakeLists.txt1
-rw-r--r--source/blender/blenvm/llvm/llvm_compiler.cc86
-rw-r--r--source/blender/blenvm/llvm/llvm_compiler.h4
-rw-r--r--source/blender/blenvm/llvm/llvm_compiler_dual.cc17
-rw-r--r--source/blender/blenvm/modules/mod_image.h94
-rw-r--r--source/blender/blenvm/modules/modules.h1
-rw-r--r--source/blender/blenvm/util/util_eval_globals.cc114
-rw-r--r--source/blender/blenvm/util/util_eval_globals.h80
-rw-r--r--source/blender/blenvm/util/util_opcode.h1
-rw-r--r--source/blender/modifiers/CMakeLists.txt1
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c17
-rw-r--r--source/blender/render/intern/source/render_texture.c6
22 files changed, 444 insertions, 194 deletions
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index e4c9a6dbcf7..904c130616f 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -39,6 +39,7 @@ extern "C" {
struct bNode;
struct Brush;
+struct BVMEvalGlobals;
struct ColorBand;
struct EnvMap;
struct EvaluationContext;
@@ -136,8 +137,9 @@ bool BKE_texture_is_image_user(const struct Tex *tex);
void BKE_texture_get_value(
const struct Scene *scene, struct Tex *texture,
- float *tex_co, struct TexResult *texres, bool use_color_management);
-void BKE_texture_get_value_deriv(
+ const float *tex_co, struct TexResult *texres, bool use_color_management);
+void BKE_texture_get_value_ex(
+ struct BVMEvalGlobals *globals,
const struct Scene *scene, struct Tex *texture,
const float *tex_co, const float *tex_dx, const float *tex_dy,
struct TexResult *texres, struct TexResult *texres_dx, struct TexResult *texres_dy,
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 8e24dd117c9..b6ce24de682 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -1660,45 +1660,36 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture)
void BKE_texture_get_value(
const Scene *scene, Tex *texture,
- float *tex_co, TexResult *texres, bool use_color_management)
+ const float *tex_co, TexResult *texres,
+ bool use_color_management)
{
- int result_type;
- bool do_color_manage = false;
-
- if (scene && use_color_management) {
- do_color_manage = BKE_scene_check_color_management_enabled(scene);
- }
-
- /* no node textures for now */
- result_type = multitex_ext_safe(texture, tex_co, texres, NULL, do_color_manage, false);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, since this is in the context of modifiers don't use perceptual color conversion.
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (result_type & TEX_RGB) {
- texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb);
- }
- else {
- copy_v3_fl(&texres->tr, texres->tin);
- }
+ BKE_texture_get_value_ex(NULL, scene, texture,
+ tex_co, NULL, NULL,
+ texres, NULL, NULL,
+ use_color_management);
}
-void BKE_texture_get_value_deriv(
+void BKE_texture_get_value_ex(
+ struct BVMEvalGlobals *globals,
const Scene *scene, Tex *texture,
const float *tex_co, const float *tex_dx, const float *tex_dy,
TexResult *texres, TexResult *texres_dx, TexResult *texres_dy,
- bool UNUSED(use_color_management))
+ bool use_color_management)
{
int result_type;
+ bool do_color_manage = false;
+
+ if (scene && use_color_management) {
+ do_color_manage = BKE_scene_check_color_management_enabled(scene);
+ }
- /* no node textures for now */
if (texture->use_nodes && texture->nodetree) {
struct BVMFunction *fn = BVM_gen_texture_function_llvm(texture->nodetree, true);
if (fn) {
struct BVMEvalContext *context = BVM_context_create();
- BVM_eval_texture_llvm(context, fn,
+ BVM_eval_texture_llvm(globals,
+ context, fn,
texres, texres_dx, texres_dy,
tex_co, tex_dx, tex_dy,
0, 0, scene->r.cfra, false);
@@ -1708,6 +1699,10 @@ void BKE_texture_get_value_deriv(
BVM_function_llvm_release(fn);
}
}
+ else {
+ struct ImagePool *image_pool = (globals ? BVM_globals_image_pool(globals) : NULL);
+ result_type = multitex_ext_safe(texture, (float*)tex_co, texres, image_pool, do_color_manage, false);
+ }
/* if the texture gave an RGB value, we assume it didn't give a valid
* intensity, since this is in the context of modifiers don't use perceptual color conversion.
diff --git a/source/blender/blenvm/BVM_api.h b/source/blender/blenvm/BVM_api.h
index 45f3af31ea6..467e147de42 100644
--- a/source/blender/blenvm/BVM_api.h
+++ b/source/blender/blenvm/BVM_api.h
@@ -91,6 +91,7 @@ BVMBufferType BVM_typedesc_buffer_type(struct BVMTypeDesc *typedesc);
/* ------------------------------------------------------------------------- */
+struct bNodeTree;
struct DepsNodeHandle;
void BVM_nodetree_compile_dependencies(struct bNodeTree *ntree, struct DepsNodeHandle *handle);
@@ -102,10 +103,12 @@ struct BVMEvalGlobals;
struct BVMEvalContext;
struct bNodeTree;
+struct ImagePool;
struct BVMEvalGlobals *BVM_globals_create(void);
void BVM_globals_free(struct BVMEvalGlobals *globals);
+struct ImagePool *BVM_globals_image_pool(struct BVMEvalGlobals *globals);
void BVM_globals_add_object(struct BVMEvalGlobals *globals, int key, struct Object *ob);
void BVM_globals_add_nodetree_relations(struct BVMEvalGlobals *globals, struct bNodeTree *ntree);
@@ -139,7 +142,7 @@ struct BVMFunction *BVM_gen_forcefield_function_bvm(struct bNodeTree *btree, boo
void BVM_debug_forcefield_nodes(struct bNodeTree *btree, FILE *debug_file, const char *label, BVMDebugMode mode);
void BVM_eval_forcefield_bvm(struct BVMEvalGlobals *globals, struct BVMEvalContext *context, struct BVMFunction *fn,
- struct Object *effob, const struct EffectedPoint *point, float force[3], float impulse[3]);
+ struct Object *effob, const struct EffectedPoint *point, float force[3], float impulse[3]);
/* ------------------------------------------------------------------------- */
@@ -151,11 +154,13 @@ struct BVMFunction *BVM_gen_texture_function_llvm(struct bNodeTree *btree, bool
void BVM_debug_texture_nodes(struct bNodeTree *btree, FILE *debug_file, const char *label, BVMDebugMode mode);
-void BVM_eval_texture_bvm(struct BVMEvalContext *context, struct BVMFunction *fn,
+void BVM_eval_texture_bvm(struct BVMEvalGlobals *globals, struct BVMEvalContext *context,
+ struct BVMFunction *fn,
struct TexResult *target,
float coord[3], float dxt[3], float dyt[3], int osatex,
short which_output, int cfra, int preview);
-void BVM_eval_texture_llvm(struct BVMEvalContext *context, struct BVMFunction *fn,
+void BVM_eval_texture_llvm(struct BVMEvalGlobals *globals, struct BVMEvalContext *context,
+ struct BVMFunction *fn,
struct TexResult *value,
struct TexResult *value_dx,
struct TexResult *value_dy,
diff --git a/source/blender/blenvm/CMakeLists.txt b/source/blender/blenvm/CMakeLists.txt
index 9b264a516a7..af06863533c 100644
--- a/source/blender/blenvm/CMakeLists.txt
+++ b/source/blender/blenvm/CMakeLists.txt
@@ -33,6 +33,7 @@ set(INC
../blenkernel
../blenlib
../depsgraph
+ ../imbuf
../makesdna
../makesrna
../render/extern/include
@@ -54,12 +55,15 @@ set(SRC
modules/mod_defines.h
modules/mod_base.h
modules/mod_color.h
+ modules/mod_image.h
modules/mod_math.h
modules/mod_texture.h
util/util_opcode.h
util/util_data_ptr.h
util/util_debug.h
+ util/util_eval_globals.cc
+ util/util_eval_globals.h
util/util_hash.h
util/util_map.h
util/util_math.h
diff --git a/source/blender/blenvm/bvm/CMakeLists.txt b/source/blender/blenvm/bvm/CMakeLists.txt
index 14601ef9384..ac668dd8de3 100644
--- a/source/blender/blenvm/bvm/CMakeLists.txt
+++ b/source/blender/blenvm/bvm/CMakeLists.txt
@@ -26,6 +26,7 @@
set(INC
.
..
+ ../intern
../modules
../util
../../blenkernel
diff --git a/source/blender/blenvm/bvm/bvm_eval.cc b/source/blender/blenvm/bvm/bvm_eval.cc
index 79da5cb3b85..fd053c7db19 100644
--- a/source/blender/blenvm/bvm/bvm_eval.cc
+++ b/source/blender/blenvm/bvm/bvm_eval.cc
@@ -59,70 +59,6 @@ extern "C" {
namespace blenvm {
-EvalGlobals::EvalGlobals()
-{
- m_image_pool = BKE_image_pool_new();
-}
-
-EvalGlobals::~EvalGlobals()
-{
- BKE_image_pool_free(m_image_pool);
-}
-
-int EvalGlobals::get_id_key(ID *id)
-{
- int hash = BLI_ghashutil_strhash(id->name);
- if (id->lib) {
- hash = hash_combine(hash, BLI_ghashutil_strhash(id->lib->name));
- }
- return hash;
-}
-
-void EvalGlobals::add_object(int key, Object *ob)
-{
- m_objects[key] = ob;
-}
-
-PointerRNA EvalGlobals::lookup_object(int key) const
-{
- ObjectMap::const_iterator it = m_objects.find(key);
- if (it != m_objects.end()) {
- PointerRNA ptr;
- RNA_id_pointer_create((ID *)it->second, &ptr);
- return ptr;
- }
- else {
- return PointerRNA_NULL;
- }
-}
-
-void EvalGlobals::add_image(int key, Image *ima)
-{
- m_images[key] = ima;
-}
-
-ImBuf *EvalGlobals::lookup_imbuf(int key, ImageUser *iuser) const
-{
- ImageMap::const_iterator ima_it = m_images.find(key);
- Image *ima = (ima_it != m_images.end()) ? ima_it->second : NULL;
- if (!ima)
- return NULL;
-
- /* local changes to the original ImageUser */
-// if (!BKE_image_is_multilayer(ima))
-// iuser->multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
-
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, iuser, m_image_pool);
- if (!ibuf || (!ibuf->rect && !ibuf->rect_float)) {
- BKE_image_pool_release_ibuf(ima, ibuf, m_image_pool);
- return NULL;
- }
-
- return ibuf;
-}
-
-/* ------------------------------------------------------------------------- */
-
int EvalStack::stack_size(size_t datasize)
{
return int_div_ceil(datasize, sizeof(EvalStack));
diff --git a/source/blender/blenvm/bvm/bvm_eval.h b/source/blender/blenvm/bvm/bvm_eval.h
index 68dd80f4c85..c4d4c06ac06 100644
--- a/source/blender/blenvm/bvm/bvm_eval.h
+++ b/source/blender/blenvm/bvm/bvm_eval.h
@@ -32,24 +32,9 @@
* \ingroup bvm
*/
-#include <set>
-#include <vector>
-
#include "MEM_guardedalloc.h"
-extern "C" {
-#include "RNA_access.h"
-}
-
-#include "util_map.h"
-#include "util_string.h"
-
-struct ID;
-struct Image;
-struct ImagePool;
-struct ImageUser;
-struct ImBuf;
-struct Object;
+#include "util_eval_globals.h"
namespace blenvm {
@@ -57,29 +42,6 @@ struct InstructionList;
#define BVM_STACK_SIZE 4095
-struct EvalGlobals {
- typedef unordered_map<int, Object *> ObjectMap;
- typedef unordered_map<int, Image *> ImageMap;
-
- EvalGlobals();
- ~EvalGlobals();
-
- static int get_id_key(ID *id);
-
- void add_object(int key, Object *ob);
- PointerRNA lookup_object(int key) const;
-
- void add_image(int key, Image *ima);
- ImBuf *lookup_imbuf(int key, ImageUser *iuser) const;
-
-private:
- ObjectMap m_objects;
- ImageMap m_images;
- ImagePool *m_image_pool;
-
- MEM_CXX_CLASS_ALLOC_FUNCS("BVM:EvalGlobals")
-};
-
struct EvalStack {
static int stack_size(size_t datasize);
diff --git a/source/blender/blenvm/compile/node_graph.cc b/source/blender/blenvm/compile/node_graph.cc
index ef0f057be98..17d5aa31cf2 100644
--- a/source/blender/blenvm/compile/node_graph.cc
+++ b/source/blender/blenvm/compile/node_graph.cc
@@ -74,9 +74,10 @@ NodeOutput::~NodeOutput()
/* ------------------------------------------------------------------------- */
-NodeType::NodeType(const string &name, eNodeTypeKind kind) :
+NodeType::NodeType(const string &name, eNodeTypeKind kind, bool use_globals) :
m_name(name),
- m_kind(kind)
+ m_kind(kind),
+ m_use_globals(use_globals)
{
}
@@ -1773,6 +1774,7 @@ static void register_opcode_node_types()
nt->add_output("duplis", "DUPLIS");
nt = NodeGraph::add_node_type("IMAGE_SAMPLE");
+ nt->set_use_globals(true);
nt->add_input("image", "INT", 0);
nt->add_input("uv", "FLOAT3", float3(0.0f, 0.0f, 0.0f));
nt->add_output("color", "FLOAT4");
diff --git a/source/blender/blenvm/compile/node_graph.h b/source/blender/blenvm/compile/node_graph.h
index 57b182bbcb5..47228138993 100644
--- a/source/blender/blenvm/compile/node_graph.h
+++ b/source/blender/blenvm/compile/node_graph.h
@@ -98,11 +98,14 @@ struct NodeType {
typedef std::vector<NodeInput> InputList;
typedef std::vector<NodeOutput> OutputList;
- NodeType(const string &name, eNodeTypeKind kind = NODE_TYPE_FUNCTION);
+ NodeType(const string &name, eNodeTypeKind kind = NODE_TYPE_FUNCTION, bool use_globals = false);
~NodeType();
const string &name() const { return m_name; }
eNodeTypeKind kind() const { return m_kind; }
+ bool use_globals() const { return m_use_globals; }
+
+ void set_use_globals(bool use_globals) { m_use_globals = use_globals; }
int num_inputs() const { return m_inputs.size(); }
int num_outputs() const { return m_outputs.size(); }
@@ -139,6 +142,7 @@ private:
InputList m_inputs;
OutputList m_outputs;
eNodeTypeKind m_kind;
+ bool m_use_globals;
MEM_CXX_CLASS_ALLOC_FUNCS("BVM:NodeType")
};
diff --git a/source/blender/blenvm/intern/bvm_api.cc b/source/blender/blenvm/intern/bvm_api.cc
index ee047e2291f..3a0a46590fa 100644
--- a/source/blender/blenvm/intern/bvm_api.cc
+++ b/source/blender/blenvm/intern/bvm_api.cc
@@ -77,6 +77,13 @@ extern "C" {
namespace blenvm {
static mesh_ptr __empty_mesh__;
static duplis_ptr __empty_duplilist__ = duplis_ptr(new DupliList());
+
+static blenvm::EvalGlobals *eval_globals_default()
+{
+ static blenvm::EvalGlobals default_globals;
+ return &default_globals;
+}
+
}
void BVM_init(void)
@@ -292,6 +299,9 @@ struct BVMEvalGlobals *BVM_globals_create(void)
void BVM_globals_free(struct BVMEvalGlobals *globals)
{ delete _GLOBALS(globals); }
+struct ImagePool *BVM_globals_image_pool(struct BVMEvalGlobals *globals)
+{ return _GLOBALS(globals)->image_pool(); }
+
void BVM_globals_add_object(struct BVMEvalGlobals *globals, int key, struct Object *ob)
{ _GLOBALS(globals)->add_object(key, ob); }
@@ -556,7 +566,8 @@ void BVM_eval_forcefield_bvm(struct BVMEvalGlobals *globals, struct BVMEvalConte
namespace blenvm {
-typedef void (*TexNodesFunc)(Dual2<float4> *r_color, Dual2<float3> *r_normal,
+typedef void (*TexNodesFunc)(const struct EvalGlobals *globals,
+ Dual2<float4> *r_color, Dual2<float3> *r_normal,
const Dual2<float3> *co, int cfra, int osatex);
static void set_texresult(TexResult *result, const float4 &color, const float3 &normal)
@@ -672,37 +683,41 @@ void BVM_debug_texture_nodes(bNodeTree *btree, FILE *debug_file, const char *lab
debug_node_graph(graph, debug_file, label, mode);
}
-void BVM_eval_texture_bvm(struct BVMEvalContext *ctx, struct BVMFunction *fn,
+void BVM_eval_texture_bvm(struct BVMEvalGlobals *_globals, struct BVMEvalContext *ctx, struct BVMFunction *fn,
struct TexResult *target,
float coord[3], float dxt[3], float dyt[3], int osatex,
short UNUSED(which_output), int cfra, int UNUSED(preview))
{
using namespace blenvm;
- EvalGlobals globals;
+ EvalGlobals *globals = _GLOBALS(_globals);
+ if (globals == NULL)
+ globals = eval_globals_default();
float4 color;
float3 normal;
const void *args[] = { coord, dxt, dyt, &cfra, &osatex };
void *results[] = { &color.x, &normal.x };
- _FUNC_BVM(fn)->eval(_CTX(ctx), &globals, args, results);
+ _FUNC_BVM(fn)->eval(_CTX(ctx), globals, args, results);
set_texresult(target, color, normal);
}
-void BVM_eval_texture_llvm(struct BVMEvalContext *UNUSED(ctx), struct BVMFunction *fn,
+void BVM_eval_texture_llvm(struct BVMEvalGlobals *_globals, struct BVMEvalContext *UNUSED(ctx), struct BVMFunction *fn,
struct TexResult *value, struct TexResult *value_dx, struct TexResult *value_dy,
const float coord[3], const float dxt[3], const float dyt[3], int osatex,
short UNUSED(which_output), int cfra, int UNUSED(preview))
{
using namespace blenvm;
- EvalGlobals globals;
+ EvalGlobals *globals = _GLOBALS(_globals);
+ if (globals == NULL)
+ globals = eval_globals_default();
+
Dual2<float4> r_color;
Dual2<float3> r_normal;
- UNUSED_VARS(globals);
#ifdef WITH_LLVM
TexNodesFunc fp = (TexNodesFunc)_FUNC_LLVM(fn)->ptr();
@@ -717,9 +732,9 @@ void BVM_eval_texture_llvm(struct BVMEvalContext *UNUSED(ctx), struct BVMFunctio
else
coord_v.set_dy(float3(0.0f, 1.0f, 0.0f));
- fp(&r_color, &r_normal, &coord_v, cfra, osatex);
+ fp(globals, &r_color, &r_normal, &coord_v, cfra, osatex);
#else
- UNUSED_VARS(fn, coord, dxt, dyt, cfra, osatex);
+ UNUSED_VARS(fn, globals, coord, dxt, dyt, cfra, osatex);
r_color = Dual2<float4>(float4(0.0f, 0.0f, 0.0f, 0.0f));
r_normal = Dual2<float3>(float3(0.0f, 0.0f, 1.0f));
#endif
diff --git a/source/blender/blenvm/llvm/CMakeLists.txt b/source/blender/blenvm/llvm/CMakeLists.txt
index 442702235d8..2c184427833 100644
--- a/source/blender/blenvm/llvm/CMakeLists.txt
+++ b/source/blender/blenvm/llvm/CMakeLists.txt
@@ -32,6 +32,7 @@ set(INC
../util
../../blenkernel
../../blenlib
+ ../../imbuf
../../makesdna
../../makesrna
../../../../intern/guardedalloc
diff --git a/source/blender/blenvm/llvm/llvm_compiler.cc b/source/blender/blenvm/llvm/llvm_compiler.cc
index 432cb43d2c7..6bbc4fe311a 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.cc
+++ b/source/blender/blenvm/llvm/llvm_compiler.cc
@@ -49,7 +49,8 @@
namespace blenvm {
LLVMCompilerBase::LLVMCompilerBase() :
- m_module(NULL)
+ m_module(NULL),
+ m_globals_ptr(NULL)
{
}
@@ -115,28 +116,28 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_expression(const NodeG
using namespace llvm;
node_graph_begin();
+ /* cache function arguments */
+ int num_inputs = graph.inputs.size();
+ int num_outputs = graph.outputs.size();
+ std::vector<Argument*> input_args(num_inputs), output_args(num_outputs);
+ {
+ Function::ArgumentListType::iterator arg_it = func->arg_begin();
+ m_globals_ptr = arg_it++; /* globals, passed to functions which need it */
+ for (int i = 0; i < num_outputs; ++i)
+ output_args[i] = arg_it++;
+ for (int i = 0; i < num_inputs; ++i)
+ input_args[i] = arg_it++;
+ }
IRBuilder<> builder(context());
BasicBlock *block = BasicBlock::Create(context(), "entry", func);
builder.SetInsertPoint(block);
- int num_inputs = graph.inputs.size();
- int num_outputs = graph.outputs.size();
-
- {
- Function::ArgumentListType::iterator it = func->arg_begin();
- for (int i = 0; i < num_outputs; ++i) {
- /* skip output arguments */
- ++it;
- }
- for (int i = 0; i < num_inputs; ++i) {
- const NodeGraph::Input &input = graph.inputs[i];
- Argument *arg = it++;
-
- if (input.key)
- map_argument(block, input.key, arg);
- }
+ for (int i = 0; i < num_inputs; ++i) {
+ const NodeGraph::Input &input = graph.inputs[i];
+ if (input.key)
+ map_argument(block, input.key, input_args[i]);
}
OrderedNodeSet nodes;
@@ -149,19 +150,15 @@ llvm::BasicBlock *LLVMCompilerBase::codegen_function_body_expression(const NodeG
codegen_node(block, &node);
}
- {
- Function::ArgumentListType::iterator it = func->arg_begin();
- for (int i = 0; i < num_outputs; ++i) {
- const NodeGraph::Output &output = graph.outputs[i];
- Argument *arg = it++;
-
- store_return_value(block, output.key, arg);
- }
+ for (int i = 0; i < num_outputs; ++i) {
+ const NodeGraph::Output &output = graph.outputs[i];
+ store_return_value(block, output.key, output_args[i]);
}
builder.CreateRetVoid();
node_graph_end();
+ m_globals_ptr = NULL;
return block;
}
@@ -182,8 +179,8 @@ llvm::Function *LLVMCompilerBase::codegen_node_function(const string &name, cons
output_types.push_back(FunctionParameter(type, output.name));
}
- Function *func = declare_function(module(), name, input_types, output_types);
- BLI_assert(func->getArgumentList().size() == graph.inputs.size() + graph.outputs.size() &&
+ Function *func = declare_function(module(), name, input_types, output_types, true);
+ BLI_assert(func->getArgumentList().size() == 1 + graph.inputs.size() + graph.outputs.size() &&
"Error: Function has wrong number of arguments for node tree\n");
codegen_function_body_expression(graph, func);
@@ -278,6 +275,10 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
/* function call arguments */
std::vector<Value *> args;
+ if (node->type->use_globals()) {
+ args.push_back(m_globals_ptr);
+ }
+
for (int i = 0; i < node->num_outputs(); ++i) {
ConstOutputKey output = node->output(i);
@@ -313,11 +314,18 @@ void LLVMCompilerBase::expand_function_node(llvm::BasicBlock *block, const NodeI
llvm::Function *LLVMCompilerBase::declare_function(llvm::Module *mod, const string &name,
const FunctionParameterList &input_types,
- const FunctionParameterList &output_types)
+ const FunctionParameterList &output_types,
+ bool use_globals)
{
using namespace llvm;
std::vector<llvm::Type*> arg_types;
+
+ if (use_globals) {
+ Type *t_globals = llvm::TypeBuilder<void*, false>::get(context());
+ arg_types.push_back(t_globals);
+ }
+
for (int i = 0; i < output_types.size(); ++i) {
Type *type = output_types[i].type;
/* use a pointer to store output values */
@@ -332,11 +340,14 @@ llvm::Function *LLVMCompilerBase::declare_function(llvm::Module *mod, const stri
Function *func = Function::Create(functype, Function::ExternalLinkage, name, mod);
Function::arg_iterator it = func->arg_begin();
- for (size_t i = 0; i < output_types.size(); ++i, ++it) {
- it->setName(output_types[i].name);
+ if (use_globals) {
+ (it++)->setName("globals");
+ }
+ for (size_t i = 0; i < output_types.size(); ++i) {
+ (it++)->setName(output_types[i].name);
}
- for (size_t i = 0; i < input_types.size(); ++i, ++it) {
- it->setName(input_types[i].name);
+ for (size_t i = 0; i < input_types.size(); ++i) {
+ (it++)->setName(input_types[i].name);
}
return func;
@@ -356,7 +367,7 @@ llvm::Function *LLVMCompilerBase::declare_node_function(llvm::Module *mod, const
append_output_types(output_types, output);
}
- return declare_function(mod, nodetype->name(), input_types, output_types);
+ return declare_function(mod, nodetype->name(), input_types, output_types, nodetype->use_globals());
}
/* ------------------------------------------------------------------------- */
@@ -374,15 +385,6 @@ FunctionLLVM *LLVMCompilerBase::compile_function(const string &name, const NodeG
BLI_assert(opt_level >= 0 && opt_level <= 3 && "Invalid optimization level (must be between 0 and 3)");
optimize_function(func, opt_level);
-#if 0
- printf("=== NODE FUNCTION ===\n");
- fflush(stdout);
-// func->dump();
- module()->dump();
- printf("=====================\n");
- fflush(stdout);
-#endif
-
verifyFunction(*func, &outs());
verifyModule(*module(), &outs());
diff --git a/source/blender/blenvm/llvm/llvm_compiler.h b/source/blender/blenvm/llvm/llvm_compiler.h
index ba01a2b6d76..f48f7813c9c 100644
--- a/source/blender/blenvm/llvm/llvm_compiler.h
+++ b/source/blender/blenvm/llvm/llvm_compiler.h
@@ -121,13 +121,15 @@ protected:
llvm::Function *declare_function(llvm::Module *mod, const string &name,
const FunctionParameterList &input_types,
- const FunctionParameterList &output_types);
+ const FunctionParameterList &output_types,
+ bool use_globals);
llvm::Function *declare_node_function(llvm::Module *mod, const NodeType *nodetype);
virtual void define_nodes_module() = 0;
virtual llvm::Module *get_nodes_module() const = 0;
private:
llvm::Module *m_module;
+ llvm::Value *m_globals_ptr;
};
struct LLVMTextureCompiler : public LLVMCompilerBase {
diff --git a/source/blender/blenvm/llvm/llvm_compiler_dual.cc b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
index 97eacec0863..f01cf7197af 100644
--- a/source/blender/blenvm/llvm/llvm_compiler_dual.cc
+++ b/source/blender/blenvm/llvm/llvm_compiler_dual.cc
@@ -400,7 +400,7 @@ llvm::Function *LLVMTextureCompiler::declare_elementary_node_function(
return NULL;
}
- return declare_function(mod, name, input_types, output_types);
+ return declare_function(mod, name, input_types, output_types, nodetype->use_globals());
}
void LLVMTextureCompiler::define_elementary_functions(llvm::Module *mod, OpCode op, const NodeType *nodetype)
@@ -445,6 +445,14 @@ void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod,
std::vector<Value*> call_args_value, call_args_dx, call_args_dy;
Function::arg_iterator arg_it = func->arg_begin();
+
+ if (nodetype->use_globals()) {
+ Value *globals = arg_it++;
+ call_args_value.push_back(globals);
+ call_args_dx.push_back(globals);
+ call_args_dy.push_back(globals);
+ }
+
/* output arguments */
for (int i = 0; i < nodetype->num_outputs(); ++i) {
const NodeOutput *output = nodetype->find_output(i);
@@ -507,13 +515,14 @@ void LLVMTextureCompiler::define_dual_function_wrapper(llvm::Module *mod,
}
else {
/* zero the derivatives */
- for (int i = 0; i < nodetype->num_outputs(); ++i, ++arg_it) {
+ for (int i = 0; i < nodetype->num_outputs(); ++i) {
const NodeOutput *output = nodetype->find_output(i);
const TypeSpec *typespec = output->typedesc.get_typespec();
if (bvm_type_has_dual_value(typespec)) {
- bvm_llvm_set_zero(context(), block, call_args_dx[i], typespec);
- bvm_llvm_set_zero(context(), block, call_args_dy[i], typespec);
+ int arg_i = nodetype->use_globals() ? i + 1 : i;
+ bvm_llvm_set_zero(context(), block, call_args_dx[arg_i], typespec);
+ bvm_llvm_set_zero(context(), block, call_args_dy[arg_i], typespec);
}
}
}
diff --git a/source/blender/blenvm/modules/mod_image.h b/source/blender/blenvm/modules/mod_image.h
new file mode 100644
index 00000000000..f5197880950
--- /dev/null
+++ b/source/blender/blenvm/modules/mod_image.h
@@ -0,0 +1,94 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __MOD_IMAGE_H__
+#define __MOD_IMAGE_H__
+
+extern "C" {
+#include "BLI_math_color.h"
+
+#include "DNA_image_types.h"
+
+#include "BKE_image.h"
+#include "BKE_scene.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
+}
+
+#include "mod_defines.h"
+
+#include "util_eval_globals.h"
+#include "util_math.h"
+
+BVM_MOD_NAMESPACE_BEGIN
+
+/* nearest sampling mode */
+inline static void imbuf_sample_nearest(ImBuf *ibuf, const float3 &uv, float4 &color)
+{
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+
+ int x1 = (int)uv.x;
+ int y1 = (int)uv.y;
+
+ /* sample area entirely outside image? */
+ if (x1 < 0 || x1 > ibuf->x - 1 || y1 < 0 || y1 > ibuf->y - 1) {
+ color.x = color.y = color.z = color.w = 0.0f;
+ return;
+ }
+
+ if (ibuf->rect_float) {
+ const float *data = ibuf->rect_float + ((size_t)ibuf->x * y1 + x1) * 4;
+ copy_v4_v4(color.data(), data);
+ }
+ else {
+ const unsigned char *data = (unsigned char *)ibuf->rect + ((size_t)ibuf->x * y1 + x1) * 4;
+ rgba_uchar_to_float(color.data(), data);
+ }
+}
+
+bvm_extern void V__IMAGE_SAMPLE(const EvalGlobals *globals,
+ float4 &r_color,
+ int image, const float3 &uv)
+{
+ r_color = float4(0.0f, 0.0f, 0.0f, 0.0f);
+
+ /* TODO just a dummy ImageUser for now */
+ ImageUser iuser = {0};
+ iuser.ok = true;
+
+ ImBuf *ibuf = globals->lookup_imbuf(image, &iuser);
+ if (ibuf) {
+ imbuf_sample_nearest(ibuf, uv, r_color);
+ }
+}
+BVM_DECL_FUNCTION_VALUE(IMAGE_SAMPLE)
+
+BVM_MOD_NAMESPACE_END
+
+#endif /* __MOD_IMAGE_H__ */
diff --git a/source/blender/blenvm/modules/modules.h b/source/blender/blenvm/modules/modules.h
index b2ab355855c..f8d6edbaf1b 100644
--- a/source/blender/blenvm/modules/modules.h
+++ b/source/blender/blenvm/modules/modules.h
@@ -30,6 +30,7 @@
#include "mod_base.h"
#include "mod_color.h"
+#include "mod_image.h"
#include "mod_math.h"
#include "mod_texture.h"
diff --git a/source/blender/blenvm/util/util_eval_globals.cc b/source/blender/blenvm/util/util_eval_globals.cc
new file mode 100644
index 00000000000..5b33ba95107
--- /dev/null
+++ b/source/blender/blenvm/util/util_eval_globals.cc
@@ -0,0 +1,114 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file util_eval_globals.cc
+ * \ingroup bvm
+ */
+
+#include <cassert>
+
+extern "C" {
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+
+#include "BKE_image.h"
+
+#include "IMB_imbuf_types.h"
+}
+
+#include "util_eval_globals.h"
+
+#include "util_hash.h"
+
+namespace blenvm {
+
+EvalGlobals::EvalGlobals()
+{
+ m_image_pool = BKE_image_pool_new();
+}
+
+EvalGlobals::~EvalGlobals()
+{
+ BKE_image_pool_free(m_image_pool);
+}
+
+int EvalGlobals::get_id_key(ID *id)
+{
+ int hash = BLI_ghashutil_strhash(id->name);
+ if (id->lib) {
+ hash = hash_combine(hash, BLI_ghashutil_strhash(id->lib->name));
+ }
+ return hash;
+}
+
+void EvalGlobals::add_object(int key, Object *ob)
+{
+ m_objects[key] = ob;
+}
+
+PointerRNA EvalGlobals::lookup_object(int key) const
+{
+ ObjectMap::const_iterator it = m_objects.find(key);
+ if (it != m_objects.end()) {
+ PointerRNA ptr;
+ RNA_id_pointer_create((ID *)it->second, &ptr);
+ return ptr;
+ }
+ else {
+ return PointerRNA_NULL;
+ }
+}
+
+void EvalGlobals::add_image(int key, Image *ima)
+{
+ m_images[key] = ima;
+}
+
+ImBuf *EvalGlobals::lookup_imbuf(int key, ImageUser *iuser) const
+{
+ ImageMap::const_iterator ima_it = m_images.find(key);
+ Image *ima = (ima_it != m_images.end()) ? ima_it->second : NULL;
+ if (!ima)
+ return NULL;
+
+ /* local changes to the original ImageUser */
+// if (!BKE_image_is_multilayer(ima))
+// iuser->multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
+
+ ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, iuser, m_image_pool);
+ if (!ibuf || (!ibuf->rect && !ibuf->rect_float)) {
+ BKE_image_pool_release_ibuf(ima, ibuf, m_image_pool);
+ return NULL;
+ }
+
+ return ibuf;
+}
+
+} /* namespace blenvm */
diff --git a/source/blender/blenvm/util/util_eval_globals.h b/source/blender/blenvm/util/util_eval_globals.h
new file mode 100644
index 00000000000..9d0a0e520a7
--- /dev/null
+++ b/source/blender/blenvm/util/util_eval_globals.h
@@ -0,0 +1,80 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __UTIL_EVAL_GLOBALS_H__
+#define __UTIL_EVAL_GLOBALS_H__
+
+/** \file util_eval_globals.h
+ * \ingroup bvm
+ */
+
+#include "MEM_guardedalloc.h"
+
+extern "C" {
+#include "RNA_access.h"
+}
+
+#include "util_map.h"
+#include "util_string.h"
+
+struct ID;
+struct Image;
+struct ImagePool;
+struct ImageUser;
+struct ImBuf;
+struct Object;
+
+namespace blenvm {
+
+struct EvalGlobals {
+ typedef unordered_map<int, Object *> ObjectMap;
+ typedef unordered_map<int, Image *> ImageMap;
+
+ EvalGlobals();
+ ~EvalGlobals();
+
+ static int get_id_key(ID *id);
+
+ ImagePool *image_pool() const { return m_image_pool; }
+
+ void add_object(int key, Object *ob);
+ PointerRNA lookup_object(int key) const;
+
+ void add_image(int key, Image *ima);
+ ImBuf *lookup_imbuf(int key, ImageUser *iuser) const;
+
+private:
+ ObjectMap m_objects;
+ ImageMap m_images;
+ ImagePool *m_image_pool;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("BVM:EvalGlobals")
+};
+
+} /* namespace blenvm */
+
+#endif /* __UTIL_EVAL_GLOBALS_H__ */
diff --git a/source/blender/blenvm/util/util_opcode.h b/source/blender/blenvm/util/util_opcode.h
index 41742328a24..210f67cf963 100644
--- a/source/blender/blenvm/util/util_opcode.h
+++ b/source/blender/blenvm/util/util_opcode.h
@@ -208,6 +208,7 @@ namespace blenvm {
#define BVM_DEFINE_OPCODES \
BVM_DEFINE_OPCODES_BASE \
BVM_DEFINE_OPCODES_COLOR \
+ BVM_DEFINE_OPCODES_IMAGE \
BVM_DEFINE_OPCODES_MATH \
BVM_DEFINE_OPCODES_TEXTURE \
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 0de7676e8f8..5c17ab46a78 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../blenkernel
../blenlib
../blenfont
+ ../blenvm
../depsgraph
../makesdna
../makesrna
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 24400b731cb..fbf9b060b52 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -47,6 +47,8 @@
#include "BKE_texture.h"
#include "BKE_deform.h"
+#include "BVM_api.h"
+
#include "depsgraph_private.h"
#include "MEM_guardedalloc.h"
@@ -209,6 +211,7 @@ static void displaceModifier_do(
float weight = 1.0f; /* init value unused but some compilers may complain */
const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */
float (*vert_clnors)[3] = NULL;
+ struct BVMEvalGlobals *globals = NULL;
if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return;
if (dmd->strength == 0.0f) return;
@@ -222,6 +225,10 @@ static void displaceModifier_do(
get_texture_coords((MappingInfoModifierData *)dmd, ob, dm, vertexCos, tex_co, numVerts);
modifier_init_texture(dmd->modifier.scene, dmd->texture);
+
+ globals = BVM_globals_create();
+ if (dmd->texture->use_nodes && dmd->texture->nodetree != NULL)
+ BVM_globals_add_nodetree_relations(globals, dmd->texture->nodetree);
}
else {
tex_co = NULL;
@@ -259,7 +266,11 @@ static void displaceModifier_do(
if (dmd->texture) {
texres.nor = NULL;
- BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false);
+ BKE_texture_get_value_ex(globals,
+ dmd->modifier.scene, dmd->texture,
+ tex_co[i], NULL, NULL,
+ &texres, NULL, NULL,
+ false);
delta = texres.tin - dmd->midlevel;
}
else {
@@ -304,6 +315,10 @@ static void displaceModifier_do(
if (vert_clnors) {
MEM_freeN(vert_clnors);
}
+
+ if (globals) {
+ BVM_globals_free(globals);
+ }
}
static void deformVerts(ModifierData *md, Object *ob,
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index b4c5fea1c68..21e5d4e6cf3 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1126,7 +1126,11 @@ static int multitex(Tex *tex,
if (fn) {
struct BVMEvalContext *context = BVM_context_create();
- BVM_eval_texture_llvm(context, fn, texres, NULL, NULL, texvec, dxt, dyt, osatex, which_output,
+ BVM_eval_texture_llvm(NULL,
+ context, fn,
+ texres, NULL, NULL,
+ texvec, dxt, dyt,
+ osatex, which_output,
R.r.cfra, texnode_preview);
retval = TEX_INT | TEX_RGB | TEX_NOR;