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/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/blender_session.cpp10
-rw-r--r--intern/cycles/blender/blender_session.h2
-rw-r--r--intern/cycles/blender/blender_shader.cpp6
-rw-r--r--intern/cycles/blender/blender_sync.cpp3
-rw-r--r--intern/cycles/blender/blender_util.h19
-rw-r--r--intern/cycles/kernel/svm/svm.h2
-rw-r--r--intern/cycles/kernel/svm/svm_image.h53
-rw-r--r--intern/cycles/render/image.cpp2
-rw-r--r--intern/cycles/render/image.h2
-rw-r--r--intern/cycles/render/light.cpp3
-rw-r--r--intern/cycles/render/mesh.cpp47
-rw-r--r--intern/cycles/render/mesh.h3
-rw-r--r--intern/cycles/render/nodes.cpp288
-rw-r--r--intern/cycles/render/nodes.h18
-rw-r--r--intern/cycles/render/osl.cpp15
-rw-r--r--intern/cycles/render/osl.h8
-rw-r--r--intern/cycles/render/scene.h3
-rw-r--r--intern/cycles/render/svm.cpp18
-rw-r--r--intern/cycles/render/svm.h13
-rw-r--r--intern/cycles/test/render_graph_finalize_test.cpp3
20 files changed, 369 insertions, 149 deletions
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 53f2fdb91b9..78fb49db6c8 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -142,9 +142,9 @@ void BlenderSession::create_session()
scene->image_manager->builtin_image_info_cb = function_bind(
&BlenderSession::builtin_image_info, this, _1, _2, _3);
scene->image_manager->builtin_image_pixels_cb = function_bind(
- &BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5, _6);
+ &BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4, _5, _6, _7);
scene->image_manager->builtin_image_float_pixels_cb = function_bind(
- &BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5, _6);
+ &BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4, _5, _6, _7);
session->scene = scene;
@@ -1210,6 +1210,7 @@ void BlenderSession::builtin_image_info(const string &builtin_name,
bool BlenderSession::builtin_image_pixels(const string &builtin_name,
void *builtin_data,
+ int tile,
unsigned char *pixels,
const size_t pixels_size,
const bool associate_alpha,
@@ -1229,7 +1230,7 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name,
const int height = b_image.size()[1];
const int channels = b_image.channels();
- unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
+ unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame, tile);
const size_t num_pixels = ((size_t)width) * height;
if (image_pixels && num_pixels * channels == pixels_size) {
@@ -1276,6 +1277,7 @@ bool BlenderSession::builtin_image_pixels(const string &builtin_name,
bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
void *builtin_data,
+ int tile,
float *pixels,
const size_t pixels_size,
const bool,
@@ -1299,7 +1301,7 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
const int channels = b_image.channels();
float *image_pixels;
- image_pixels = image_get_float_pixels_for_frame(b_image, frame);
+ image_pixels = image_get_float_pixels_for_frame(b_image, frame, tile);
const size_t num_pixels = ((size_t)width) * height;
if (image_pixels && num_pixels * channels == pixels_size) {
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 7445fb53458..2f25ec740f9 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -157,12 +157,14 @@ class BlenderSession {
void builtin_image_info(const string &builtin_name, void *builtin_data, ImageMetaData &metadata);
bool builtin_image_pixels(const string &builtin_name,
void *builtin_data,
+ int tile,
unsigned char *pixels,
const size_t pixels_size,
const bool associate_alpha,
const bool free_cache);
bool builtin_image_float_pixels(const string &builtin_name,
void *builtin_data,
+ int tile,
float *pixels,
const size_t pixels_size,
const bool associate_alpha,
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index c3564eac940..6bbc73f72ec 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -665,6 +665,12 @@ static ShaderNode *add_node(Scene *scene,
image->animated = b_image_node.image_user().use_auto_refresh();
image->alpha_type = get_image_alpha_type(b_image);
+ image->tiles.clear();
+ BL::Image::tiles_iterator b_iter;
+ for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
+ image->tiles.push_back(b_iter->number());
+ }
+
/* TODO: restore */
/* TODO(sergey): Does not work properly when we change builtin type. */
#if 0
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index bb52c740bfb..332ee3575c0 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -729,6 +729,9 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
params.bvh_layout = RNA_boolean_get(&cscene, "use_bvh_embree") ? BVH_LAYOUT_EMBREE :
params.bvh_layout;
#endif
+
+ params.background = background;
+
return params;
}
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index cbe61e367fa..efed96ec9f5 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -34,8 +34,8 @@
extern "C" {
void BKE_image_user_frame_calc(void *ima, void *iuser, int cfra);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
-unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame);
-float *BKE_image_get_float_pixels_for_frame(void *image, int frame);
+unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame, int tile);
+float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile);
}
CCL_NAMESPACE_BEGIN
@@ -234,8 +234,15 @@ static inline int render_resolution_y(BL::RenderSettings &b_render)
static inline string image_user_file_path(BL::ImageUser &iuser, BL::Image &ima, int cfra)
{
char filepath[1024];
+ iuser.tile(0);
BKE_image_user_frame_calc(NULL, iuser.ptr.data, cfra);
BKE_image_user_file_path(iuser.ptr.data, ima.ptr.data, filepath);
+ if (ima.source() == BL::Image::source_TILED) {
+ char *udim_id = strstr(filepath, "1001");
+ if (udim_id != NULL) {
+ memcpy(udim_id, "%04d", 4);
+ }
+ }
return string(filepath);
}
@@ -245,14 +252,14 @@ static inline int image_user_frame_number(BL::ImageUser &iuser, int cfra)
return iuser.frame_current();
}
-static inline unsigned char *image_get_pixels_for_frame(BL::Image &image, int frame)
+static inline unsigned char *image_get_pixels_for_frame(BL::Image &image, int frame, int tile)
{
- return BKE_image_get_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_pixels_for_frame(image.ptr.data, frame, tile);
}
-static inline float *image_get_float_pixels_for_frame(BL::Image &image, int frame)
+static inline float *image_get_float_pixels_for_frame(BL::Image &image, int frame, int tile)
{
- return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame);
+ return BKE_image_get_float_pixels_for_frame(image.ptr.data, frame, tile);
}
static inline void render_add_metadata(BL::RenderResult &b_rr, string name, string value)
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index c4d7164a4d8..fd2833ee687 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -311,7 +311,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
# endif /* NODES_FEATURE(NODE_FEATURE_BUMP) */
# ifdef __TEXTURES__
case NODE_TEX_IMAGE:
- svm_node_tex_image(kg, sd, stack, node);
+ svm_node_tex_image(kg, sd, stack, node, &offset);
break;
case NODE_TEX_IMAGE_BOX:
svm_node_tex_image_box(kg, sd, stack, node);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 64abdd2d8b3..90f1a7845c7 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -20,6 +20,11 @@ CCL_NAMESPACE_BEGIN
ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint flags)
{
+ if (id == -1) {
+ return make_float4(
+ TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
+ }
+
float4 r = kernel_tex_image_interp(kg, id, x, y);
const float alpha = r.w;
@@ -45,9 +50,9 @@ ccl_device_inline float3 texco_remap_square(float3 co)
return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
}
-ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
+ccl_device void svm_node_tex_image(
+ KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
{
- uint id = node.y;
uint co_offset, out_offset, alpha_offset, flags;
svm_unpack_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &flags);
@@ -65,6 +70,50 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
else {
tex_co = make_float2(co.x, co.y);
}
+
+ /* TODO(lukas): Consider moving tile information out of the SVM node.
+ * TextureInfo seems a reasonable candidate. */
+ int id = -1;
+ int num_nodes = (int)node.y;
+ if (num_nodes > 0) {
+ /* Remember the offset of the node following the tile nodes. */
+ int next_offset = (*offset) + num_nodes;
+
+ /* Find the tile that the UV lies in. */
+ int tx = (int)tex_co.x;
+ int ty = (int)tex_co.y;
+
+ /* Check that we're within a legitimate tile. */
+ if (tx >= 0 && ty >= 0 && tx < 10) {
+ int tile = 1001 + 10 * ty + tx;
+
+ /* Find the index of the tile. */
+ for (int i = 0; i < num_nodes; i++) {
+ uint4 tile_node = read_node(kg, offset);
+ if (tile_node.x == tile) {
+ id = tile_node.y;
+ break;
+ }
+ if (tile_node.z == tile) {
+ id = tile_node.w;
+ break;
+ }
+ }
+
+ /* If we found the tile, offset the UVs to be relative to it. */
+ if (id != -1) {
+ tex_co.x -= tx;
+ tex_co.y -= ty;
+ }
+ }
+
+ /* Skip over the remaining nodes. */
+ *offset = next_offset;
+ }
+ else {
+ id = -num_nodes;
+ }
+
float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, flags);
if (stack_valid(out_offset))
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 03ecc9bce52..212a867f9cd 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -630,6 +630,7 @@ bool ImageManager::file_load_image(Image *img,
if (FileFormat == TypeDesc::FLOAT) {
builtin_image_float_pixels_cb(img->filename,
img->builtin_data,
+ 0, /* TODO(lukas): Support tiles here? */
(float *)&pixels[0],
num_pixels * components,
image_associate_alpha(img),
@@ -638,6 +639,7 @@ bool ImageManager::file_load_image(Image *img,
else if (FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
+ 0, /* TODO(lukas): Support tiles here? */
(uchar *)&pixels[0],
num_pixels * components,
image_associate_alpha(img),
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 459cd8c056c..bc04a667953 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -130,6 +130,7 @@ class ImageManager {
builtin_image_info_cb;
function<bool(const string &filename,
void *data,
+ int tile,
unsigned char *pixels,
const size_t pixels_size,
const bool associate_alpha,
@@ -137,6 +138,7 @@ class ImageManager {
builtin_image_pixels_cb;
function<bool(const string &filename,
void *data,
+ int tile,
float *pixels,
const size_t pixels_size,
const bool associate_alpha,
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index dc3f7c8f8ac..06304205dc9 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -575,7 +575,8 @@ void LightManager::device_update_background(Device *device,
if (node->type == EnvironmentTextureNode::node_type) {
EnvironmentTextureNode *env = (EnvironmentTextureNode *)node;
ImageMetaData metadata;
- if (env->image_manager && env->image_manager->get_image_metadata(env->slot, metadata)) {
+ if (env->image_manager && !env->slots.empty() &&
+ env->image_manager->get_image_metadata(env->slots[0], metadata)) {
res.x = max(res.x, metadata.width);
res.y = max(res.y, metadata.height);
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index cffe2bfa70a..2bf1040455f 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -637,6 +637,50 @@ void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth
subd_faces.push_back_reserved(face);
}
+static void get_uv_tiles_from_attribute(Attribute *attr, int num, unordered_set<int> &tiles)
+{
+ if (attr == NULL) {
+ return;
+ }
+
+ const float2 *uv = attr->data_float2();
+ for (int i = 0; i < num; i++, uv++) {
+ float u = uv->x, v = uv->y;
+ int x = (int)u, y = (int)v;
+
+ if (x < 0 || y < 0 || x >= 10) {
+ continue;
+ }
+
+ /* Be conservative in corners - precisely touching the right or upper edge of a tile
+ * should not load its right/upper neighbor as well. */
+ if (x > 0 && (u < x + 1e-6f)) {
+ x--;
+ }
+ if (y > 0 && (v < y + 1e-6f)) {
+ y--;
+ }
+
+ tiles.insert(1001 + 10 * y + x);
+ }
+}
+
+void Mesh::get_uv_tiles(ustring map, unordered_set<int> &tiles)
+{
+ if (map.empty()) {
+ get_uv_tiles_from_attribute(attributes.find(ATTR_STD_UV), num_triangles() * 3, tiles);
+ get_uv_tiles_from_attribute(
+ subd_attributes.find(ATTR_STD_UV), subd_face_corners.size() + num_ngons, tiles);
+ get_uv_tiles_from_attribute(curve_attributes.find(ATTR_STD_UV), num_curves(), tiles);
+ }
+ else {
+ get_uv_tiles_from_attribute(attributes.find(map), num_triangles() * 3, tiles);
+ get_uv_tiles_from_attribute(
+ subd_attributes.find(map), subd_face_corners.size() + num_ngons, tiles);
+ get_uv_tiles_from_attribute(curve_attributes.find(map), num_curves(), tiles);
+ }
+}
+
void Mesh::compute_bounds()
{
BoundBox bnds = BoundBox::empty;
@@ -2085,8 +2129,7 @@ void MeshManager::device_update_displacement_images(Device *device,
}
ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode *>(node);
- int slot = image_node->slot;
- if (slot != -1) {
+ foreach (int slot, image_node->slots) {
bump_images.insert(slot);
}
}
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 4a24a9c2656..c5be0ba60b9 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -28,6 +28,7 @@
#include "util/util_list.h"
#include "util/util_map.h"
#include "util/util_param.h"
+#include "util/util_set.h"
#include "util/util_transform.h"
#include "util/util_types.h"
#include "util/util_vector.h"
@@ -314,6 +315,8 @@ class Mesh : public Node {
void add_vertex_normals();
void add_undisplaced();
+ void get_uv_tiles(ustring map, unordered_set<int> &tiles);
+
void pack_shaders(Scene *scene, uint *shader);
void pack_normals(float4 *vnormal);
void pack_verts(const vector<uint> &tri_prim_index,
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 5e12d79bc6b..b8847f92153 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -19,6 +19,7 @@
#include "render/image.h"
#include "render/integrator.h"
#include "render/light.h"
+#include "render/mesh.h"
#include "render/nodes.h"
#include "render/scene.h"
#include "render/svm.h"
@@ -204,6 +205,27 @@ void TextureMapping::compile(OSLCompiler &compiler)
/* Image Texture */
+ImageSlotTextureNode::~ImageSlotTextureNode()
+{
+ if (image_manager) {
+ foreach (int slot, slots) {
+ if (slot != -1) {
+ image_manager->remove_image(slot);
+ }
+ }
+ }
+}
+
+void ImageSlotTextureNode::add_image_user() const
+{
+ /* Increase image user count for new node. */
+ foreach (int slot, slots) {
+ if (slot != -1) {
+ image_manager->add_image_user(slot);
+ }
+ }
+}
+
NODE_DEFINE(ImageTextureNode)
{
NodeType *type = NodeType::add("image_texture", create, NodeType::SHADER);
@@ -253,30 +275,71 @@ NODE_DEFINE(ImageTextureNode)
ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type)
{
- image_manager = NULL;
- slot = -1;
- is_float = -1;
+ is_float = false;
compress_as_srgb = false;
colorspace = u_colorspace_raw;
builtin_data = NULL;
animated = false;
+ tiles.push_back(1001);
}
-ImageTextureNode::~ImageTextureNode()
+ShaderNode *ImageTextureNode::clone() const
{
- if (image_manager) {
- image_manager->remove_image(
- filename.string(), builtin_data, interpolation, extension, alpha_type, colorspace);
- }
+ add_image_user();
+ return new ImageTextureNode(*this);
}
-ShaderNode *ImageTextureNode::clone() const
+void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph)
{
- /* Increase image user count for new node. */
- if (slot != -1) {
- image_manager->add_image_user(slot);
+ if (!scene->params.background) {
+ /* During interactive renders, all tiles are loaded.
+ * While we could support updating this when UVs change, that could lead
+ * to annoying interruptions when loading images while editing UVs. */
+ return;
}
- return new ImageTextureNode(*this);
+
+ /* Only check UVs for tile culling if there are multiple tiles. */
+ if (tiles.size() < 2) {
+ return;
+ }
+
+ ShaderInput *vector_in = input("Vector");
+ ustring attribute;
+ if (vector_in->link) {
+ ShaderNode *node = vector_in->link->parent;
+ if (node->type == UVMapNode::node_type) {
+ UVMapNode *uvmap = (UVMapNode *)node;
+ attribute = uvmap->attribute;
+ }
+ else if (node->type == TextureCoordinateNode::node_type) {
+ if (vector_in->link != node->output("UV")) {
+ return;
+ }
+ }
+ else {
+ return;
+ }
+ }
+
+ unordered_set<int> used_tiles;
+ /* TODO(lukas): This is quite inefficient. A fairly simple improvement would
+ * be to have a cache in each mesh that is indexed by attribute.
+ * Additionally, building a graph-to-meshes list once could help. */
+ foreach (Mesh *mesh, scene->meshes) {
+ foreach (Shader *shader, mesh->used_shaders) {
+ if (shader->graph == graph) {
+ mesh->get_uv_tiles(attribute, used_tiles);
+ }
+ }
+ }
+
+ ccl::vector<int> new_tiles;
+ foreach (int tile, tiles) {
+ if (used_tiles.count(tile)) {
+ new_tiles.push_back(tile);
+ }
+ }
+ tiles.swap(new_tiles);
}
void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes)
@@ -300,24 +363,61 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
ShaderOutput *color_out = output("Color");
ShaderOutput *alpha_out = output("Alpha");
- image_manager = compiler.image_manager;
- if (is_float == -1) {
- ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- extension,
- alpha_type,
- colorspace,
- metadata);
- is_float = metadata.is_float;
- compress_as_srgb = metadata.compress_as_srgb;
- known_colorspace = metadata.colorspace;
+ image_manager = compiler.scene->image_manager;
+ if (slots.empty()) {
+ cull_tiles(compiler.scene, compiler.current_graph);
}
+ if (slots.size() < tiles.size()) {
+ slots.clear();
+ slots.reserve(tiles.size());
+
+ bool have_metadata = false;
+ foreach (int tile, tiles) {
+ string tile_name = filename.string();
+ if (tiles.size() > 1) {
+ tile_name = string_printf(tile_name.c_str(), tile);
+ }
+
+ ImageMetaData metadata;
+ int slot = image_manager->add_image(tile_name,
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ extension,
+ alpha_type,
+ colorspace,
+ metadata);
+ slots.push_back(slot);
+
+ /* We assume that all tiles have the same metadata. */
+ if (!have_metadata) {
+ is_float = metadata.is_float;
+ compress_as_srgb = metadata.compress_as_srgb;
+ known_colorspace = metadata.colorspace;
+ have_metadata = true;
+ }
+ }
+ }
+
+ bool has_image = false;
+ foreach (int slot, slots) {
+ if (slot != -1) {
+ has_image = true;
+ break;
+ }
+ }
+
+ if (has_image) {
+ /* If there only is one image (a very common case), we encode it as a negative value. */
+ int num_nodes;
+ if (slots.size() == 1) {
+ num_nodes = -slots[0];
+ }
+ else {
+ num_nodes = divide_up(slots.size(), 2);
+ }
- if (slot != -1) {
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
uint flags = 0;
@@ -336,7 +436,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
if (projection != NODE_IMAGE_PROJ_BOX) {
compiler.add_node(NODE_TEX_IMAGE,
- slot,
+ num_nodes,
compiler.encode_uchar4(vector_offset,
compiler.stack_assign_if_linked(color_out),
compiler.stack_assign_if_linked(alpha_out),
@@ -345,7 +445,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
}
else {
compiler.add_node(NODE_TEX_IMAGE_BOX,
- slot,
+ num_nodes,
compiler.encode_uchar4(vector_offset,
compiler.stack_assign_if_linked(color_out),
compiler.stack_assign_if_linked(alpha_out),
@@ -353,6 +453,23 @@ void ImageTextureNode::compile(SVMCompiler &compiler)
__float_as_int(projection_blend));
}
+ if (num_nodes > 0) {
+ for (int i = 0; i < num_nodes; i++) {
+ int4 node;
+ node.x = tiles[2 * i];
+ node.y = slots[2 * i];
+ if (2 * i + 1 < slots.size()) {
+ node.z = tiles[2 * i + 1];
+ node.w = slots[2 * i + 1];
+ }
+ else {
+ node.z = -1;
+ node.w = -1;
+ }
+ compiler.add_node(node.x, node.y, node.z, node.w);
+ }
+ }
+
tex_mapping.compile_end(compiler, vector_in, vector_offset);
}
else {
@@ -375,34 +492,37 @@ void ImageTextureNode::compile(OSLCompiler &compiler)
tex_mapping.compile(compiler);
- image_manager = compiler.image_manager;
- if (is_float == -1) {
+ image_manager = compiler.scene->image_manager;
+ if (slots.size() == 0) {
ImageMetaData metadata;
if (builtin_data == NULL) {
image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata);
+ slots.push_back(-1);
}
else {
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- extension,
- alpha_type,
- colorspace,
- metadata);
+ /* TODO(lukas): OSL UDIMs */
+ int slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ extension,
+ alpha_type,
+ colorspace,
+ metadata);
+ slots.push_back(slot);
}
is_float = metadata.is_float;
compress_as_srgb = metadata.compress_as_srgb;
known_colorspace = metadata.colorspace;
}
- if (slot == -1) {
+ if (slots[0] == -1) {
compiler.parameter_texture(
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
}
else {
- compiler.parameter_texture("filename", slot);
+ compiler.parameter_texture("filename", slots[0]);
}
const bool unassociate_alpha = !(ColorSpaceManager::colorspace_is_data(colorspace) ||
@@ -462,29 +582,16 @@ NODE_DEFINE(EnvironmentTextureNode)
EnvironmentTextureNode::EnvironmentTextureNode() : ImageSlotTextureNode(node_type)
{
- image_manager = NULL;
- slot = -1;
- is_float = -1;
+ is_float = false;
compress_as_srgb = false;
colorspace = u_colorspace_raw;
builtin_data = NULL;
animated = false;
}
-EnvironmentTextureNode::~EnvironmentTextureNode()
-{
- if (image_manager) {
- image_manager->remove_image(
- filename.string(), builtin_data, interpolation, EXTENSION_REPEAT, alpha_type, colorspace);
- }
-}
-
ShaderNode *EnvironmentTextureNode::clone() const
{
- /* Increase image user count for new node. */
- if (slot != -1) {
- image_manager->add_image_user(slot);
- }
+ add_image_user();
return new EnvironmentTextureNode(*this);
}
@@ -507,24 +614,25 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
ShaderOutput *color_out = output("Color");
ShaderOutput *alpha_out = output("Alpha");
- image_manager = compiler.image_manager;
- if (slot == -1) {
+ image_manager = compiler.scene->image_manager;
+ if (slots.empty()) {
ImageMetaData metadata;
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- EXTENSION_REPEAT,
- alpha_type,
- colorspace,
- metadata);
+ int slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ EXTENSION_REPEAT,
+ alpha_type,
+ colorspace,
+ metadata);
+ slots.push_back(slot);
is_float = metadata.is_float;
compress_as_srgb = metadata.compress_as_srgb;
known_colorspace = metadata.colorspace;
}
- if (slot != -1) {
+ if (slots[0] != -1) {
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
uint flags = 0;
@@ -533,7 +641,7 @@ void EnvironmentTextureNode::compile(SVMCompiler &compiler)
}
compiler.add_node(NODE_TEX_ENVIRONMENT,
- slot,
+ slots[0],
compiler.encode_uchar4(vector_offset,
compiler.stack_assign_if_linked(color_out),
compiler.stack_assign_if_linked(alpha_out),
@@ -563,34 +671,36 @@ void EnvironmentTextureNode::compile(OSLCompiler &compiler)
/* See comments in ImageTextureNode::compile about support
* of builtin images.
*/
- image_manager = compiler.image_manager;
- if (is_float == -1) {
+ image_manager = compiler.scene->image_manager;
+ if (slots.empty()) {
ImageMetaData metadata;
if (builtin_data == NULL) {
image_manager->get_image_metadata(filename.string(), NULL, colorspace, metadata);
+ slots.push_back(-1);
}
else {
- slot = image_manager->add_image(filename.string(),
- builtin_data,
- animated,
- 0,
- interpolation,
- EXTENSION_REPEAT,
- alpha_type,
- colorspace,
- metadata);
+ int slot = image_manager->add_image(filename.string(),
+ builtin_data,
+ animated,
+ 0,
+ interpolation,
+ EXTENSION_REPEAT,
+ alpha_type,
+ colorspace,
+ metadata);
+ slots.push_back(slot);
}
is_float = metadata.is_float;
compress_as_srgb = metadata.compress_as_srgb;
known_colorspace = metadata.colorspace;
}
- if (slot == -1) {
+ if (slots[0] == -1) {
compiler.parameter_texture(
"filename", filename, compress_as_srgb ? u_colorspace_raw : known_colorspace);
}
else {
- compiler.parameter_texture("filename", slot);
+ compiler.parameter_texture("filename", slots[0]);
}
compiler.parameter(this, "projection");
@@ -1123,7 +1233,7 @@ void IESLightNode::get_slot()
void IESLightNode::compile(SVMCompiler &compiler)
{
- light_manager = compiler.light_manager;
+ light_manager = compiler.scene->light_manager;
get_slot();
ShaderInput *strength_in = input("Strength");
@@ -1145,7 +1255,7 @@ void IESLightNode::compile(SVMCompiler &compiler)
void IESLightNode::compile(OSLCompiler &compiler)
{
- light_manager = compiler.light_manager;
+ light_manager = compiler.scene->light_manager;
get_slot();
tex_mapping.compile(compiler);
@@ -1663,7 +1773,7 @@ void PointDensityTextureNode::compile(SVMCompiler &compiler)
const bool use_density = !density_out->links.empty();
const bool use_color = !color_out->links.empty();
- image_manager = compiler.image_manager;
+ image_manager = compiler.scene->image_manager;
if (use_density || use_color) {
add_image();
@@ -1704,7 +1814,7 @@ void PointDensityTextureNode::compile(OSLCompiler &compiler)
const bool use_density = !density_out->links.empty();
const bool use_color = !color_out->links.empty();
- image_manager = compiler.image_manager;
+ image_manager = compiler.scene->image_manager;
if (use_density || use_color) {
add_image();
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 54124cd2175..a8fe7644957 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -77,14 +77,17 @@ class ImageSlotTextureNode : public TextureNode {
explicit ImageSlotTextureNode(const NodeType *node_type) : TextureNode(node_type)
{
special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
+ image_manager = NULL;
}
- int slot;
+ ~ImageSlotTextureNode();
+ void add_image_user() const;
+ ImageManager *image_manager;
+ vector<int> slots;
};
class ImageTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
- ~ImageTextureNode();
ShaderNode *clone() const;
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
@@ -110,18 +113,20 @@ class ImageTextureNode : public ImageSlotTextureNode {
float projection_blend;
bool animated;
float3 vector;
+ ccl::vector<int> tiles;
/* Runtime. */
- ImageManager *image_manager;
- int is_float;
+ bool is_float;
bool compress_as_srgb;
ustring known_colorspace;
+
+ protected:
+ void cull_tiles(Scene *scene, ShaderGraph *graph);
};
class EnvironmentTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
- ~EnvironmentTextureNode();
ShaderNode *clone() const;
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
@@ -151,8 +156,7 @@ class EnvironmentTextureNode : public ImageSlotTextureNode {
float3 vector;
/* Runtime. */
- ImageManager *image_manager;
- int is_float;
+ bool is_float;
bool compress_as_srgb;
ustring known_colorspace;
};
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 889552f49cd..91f02e42071 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -118,9 +118,9 @@ void OSLShaderManager::device_update(Device *device,
* compile shaders alternating */
thread_scoped_lock lock(ss_mutex);
- OSLCompiler compiler(this, services, ss, scene->image_manager, scene->light_manager);
+ OSLCompiler compiler(this, services, ss, scene);
compiler.background = (shader == scene->default_background);
- compiler.compile(scene, og, shader);
+ compiler.compile(og, shader);
if (shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
@@ -566,13 +566,8 @@ OSLNode *OSLShaderManager::osl_node(const std::string &filepath,
OSLCompiler::OSLCompiler(OSLShaderManager *manager,
OSLRenderServices *services,
OSL::ShadingSystem *ss,
- ImageManager *image_manager,
- LightManager *light_manager)
- : image_manager(image_manager),
- light_manager(light_manager),
- manager(manager),
- services(services),
- ss(ss)
+ Scene *scene)
+ : scene(scene), manager(manager), services(services), ss(ss)
{
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
@@ -1114,7 +1109,7 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
return group;
}
-void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
+void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
{
if (shader->need_update) {
ShaderGraph *graph = shader->graph;
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 17bf98a3433..62cbfebf7eb 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -131,10 +131,9 @@ class OSLCompiler {
OSLCompiler(OSLShaderManager *manager,
OSLRenderServices *services,
OSL::ShadingSystem *shadingsys,
- ImageManager *image_manager,
- LightManager *light_manager);
+ Scene *scene);
#endif
- void compile(Scene *scene, OSLGlobals *og, Shader *shader);
+ void compile(OSLGlobals *og, Shader *shader);
void add(ShaderNode *node, const char *name, bool isfilepath = false);
@@ -165,8 +164,7 @@ class OSLCompiler {
}
bool background;
- ImageManager *image_manager;
- LightManager *light_manager;
+ Scene *scene;
private:
#ifdef WITH_OSL
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 45997bccf5d..f99510d2d42 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -170,6 +170,8 @@ class SceneParams {
bool persistent_data;
int texture_limit;
+ bool background;
+
SceneParams()
{
shadingsystem = SHADINGSYSTEM_SVM;
@@ -180,6 +182,7 @@ class SceneParams {
num_bvh_time_steps = 0;
persistent_data = false;
texture_limit = 0;
+ background = true;
}
bool modified(const SceneParams &params)
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 8466742ae38..f42a2ea818d 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -57,9 +57,9 @@ void SVMShaderManager::device_update_shader(Scene *scene,
svm_nodes->push_back_slow(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
SVMCompiler::Summary summary;
- SVMCompiler compiler(scene->shader_manager, scene->image_manager, scene->light_manager);
+ SVMCompiler compiler(scene);
compiler.background = (shader == scene->default_background);
- compiler.compile(scene, shader, *svm_nodes, 0, &summary);
+ compiler.compile(shader, *svm_nodes, 0, &summary);
VLOG(2) << "Compilation summary:\n"
<< "Shader name: " << shader->name << "\n"
@@ -169,13 +169,8 @@ void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s
/* Graph Compiler */
-SVMCompiler::SVMCompiler(ShaderManager *shader_manager_,
- ImageManager *image_manager_,
- LightManager *light_manager_)
+SVMCompiler::SVMCompiler(Scene *scene) : scene(scene)
{
- shader_manager = shader_manager_;
- image_manager = image_manager_;
- light_manager = light_manager_;
max_stack_use = 0;
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
@@ -408,12 +403,12 @@ void SVMCompiler::add_node(const float4 &f)
uint SVMCompiler::attribute(ustring name)
{
- return shader_manager->get_attribute_id(name);
+ return scene->shader_manager->get_attribute_id(name);
}
uint SVMCompiler::attribute(AttributeStandard std)
{
- return shader_manager->get_attribute_id(std);
+ return scene->shader_manager->get_attribute_id(std);
}
uint SVMCompiler::attribute_standard(ustring name)
@@ -838,8 +833,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
}
}
-void SVMCompiler::compile(
- Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary)
+void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Summary *summary)
{
/* copy graph for shader with bump mapping */
ShaderNode *output = shader->graph->output();
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index d1534567bea..61923fc40ac 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -93,11 +93,8 @@ class SVMCompiler {
string full_report() const;
};
- SVMCompiler(ShaderManager *shader_manager,
- ImageManager *image_manager,
- LightManager *light_manager);
- void compile(
- Scene *scene, Shader *shader, array<int4> &svm_nodes, int index, Summary *summary = NULL);
+ SVMCompiler(Scene *scene);
+ void compile(Shader *shader, array<int4> &svm_nodes, int index, Summary *summary = NULL);
int stack_assign(ShaderOutput *output);
int stack_assign(ShaderInput *input);
@@ -126,9 +123,8 @@ class SVMCompiler {
return current_type;
}
- ImageManager *image_manager;
- ShaderManager *shader_manager;
- LightManager *light_manager;
+ Scene *scene;
+ ShaderGraph *current_graph;
bool background;
protected:
@@ -221,7 +217,6 @@ class SVMCompiler {
array<int4> current_svm_nodes;
ShaderType current_type;
Shader *current_shader;
- ShaderGraph *current_graph;
Stack active_stack;
int max_stack_use;
uint mix_weight_offset;
diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp
index ca93f8b02d0..ace4f29913b 100644
--- a/intern/cycles/test/render_graph_finalize_test.cpp
+++ b/intern/cycles/test/render_graph_finalize_test.cpp
@@ -158,10 +158,11 @@ class RenderGraph : public testing::Test {
Device *device_cpu;
SceneParams scene_params;
Scene *scene;
+ Shader shader;
ShaderGraph graph;
ShaderGraphBuilder builder;
- RenderGraph() : testing::Test(), builder(&graph)
+ RenderGraph() : testing::Test(), graph(&shader), builder(&graph)
{
}