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:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-04-02 18:37:57 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-04-20 15:29:51 +0300
commitcd44449578faa87c22776a0e8ecb792e18ed9a1b (patch)
tree8efe0a9d0e38365efc6078c0b1d77190286b617e /intern
parentb07c630676978498895f9e6d6c8cc00ad8215812 (diff)
Cycles: Synchronize images after building mesh BVH
This way memory overhead caused by the BVH building is not so visible and peak memory usage will be reduced. Implementing this idea is not so straightforward actually, because we need to synchronize images used for true displacement before meshes. Detecting whether image is used for true displacement is not so striaghtforward, so for now all all displacement types will synchronize images used for them. Such change brings memory usage from 4.1G to 4.0G with the 01_01_01_D scene from gooseberry. With 01_01_01_G scene it's 7.6G vs. 6.8G (before and after the patch). Reviewers: campbellbarton, juicyfruit, brecht Subscribers: eyecandy Differential Revision: https://developer.blender.org/D1217
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/render/graph.h1
-rw-r--r--intern/cycles/render/image.cpp27
-rw-r--r--intern/cycles/render/image.h1
-rw-r--r--intern/cycles/render/mesh.cpp66
-rw-r--r--intern/cycles/render/mesh.h1
-rw-r--r--intern/cycles/render/nodes.cpp4
-rw-r--r--intern/cycles/render/nodes.h21
-rw-r--r--intern/cycles/render/scene.cpp10
8 files changed, 120 insertions, 11 deletions
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index b39b3dae324..301938aa158 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -81,6 +81,7 @@ enum ShaderNodeSpecialType {
SHADER_SPECIAL_TYPE_GEOMETRY,
SHADER_SPECIAL_TYPE_SCRIPT,
SHADER_SPECIAL_TYPE_BACKGROUND,
+ SHADER_SPECIAL_TYPE_IMAGE_SLOT,
};
/* Enum
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 6e63b433709..f0608965d09 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -791,6 +791,33 @@ void ImageManager::device_update(Device *device, DeviceScene *dscene, Progress&
need_update = false;
}
+void ImageManager::device_update_slot(Device *device,
+ DeviceScene *dscene,
+ int slot,
+ Progress *progress)
+{
+ Image *image;
+ if(slot >= tex_image_byte_start) {
+ int byte_slot = slot - tex_image_byte_start;
+ assert(images[byte_slot] != NULL);
+ image = images[byte_slot];
+ }
+ else {
+ assert(float_images[slot] != NULL);
+ image = float_images[slot];
+ }
+ if(image->users == 0) {
+ device_free_image(device, dscene, slot);
+ }
+ else if(image->need_load) {
+ if(!osl_texture_system || float_images[slot]->builtin_data)
+ device_load_image(device,
+ dscene,
+ slot,
+ progress);
+ }
+}
+
void ImageManager::device_pack_images(Device *device,
DeviceScene *dscene,
Progress& /*progess*/)
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 1045b4532e4..70cc4935daa 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -63,6 +63,7 @@ public:
bool is_float_image(const string& filename, void *builtin_data, bool& is_linear);
void device_update(Device *device, DeviceScene *dscene, Progress& progress);
+ void device_update_slot(Device *device, DeviceScene *dscene, int slot, Progress *progress);
void device_free(Device *device, DeviceScene *dscene);
void device_free_builtin(Device *device, DeviceScene *dscene);
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 74ea3c94593..b6f3cb3502b 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -20,9 +20,11 @@
#include "camera.h"
#include "curves.h"
#include "device.h"
+#include "graph.h"
#include "shader.h"
#include "light.h"
#include "mesh.h"
+#include "nodes.h"
#include "object.h"
#include "scene.h"
@@ -1148,6 +1150,55 @@ void MeshManager::device_update_flags(Device * /*device*/,
need_flags_update = false;
}
+void MeshManager::device_update_displacement_images(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress& progress)
+{
+ progress.set_status("Updating Displacement Images");
+ TaskPool pool;
+ ImageManager *image_manager = scene->image_manager;
+ set<int> bump_images;
+ foreach(Mesh *mesh, scene->meshes) {
+ if(mesh->need_update) {
+ foreach(uint shader_index, mesh->used_shaders) {
+ Shader *shader = scene->shaders[shader_index];
+ if(shader->graph_bump == NULL) {
+ continue;
+ }
+ foreach(ShaderNode* node, shader->graph_bump->nodes) {
+ if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
+ continue;
+ }
+ if(device->info.pack_images) {
+ /* If device requires packed images we need to update all
+ * images now, even if they're not used for displacement.
+ */
+ image_manager->device_update(device,
+ dscene,
+ progress);
+ return;
+ }
+ ImageSlotNode *image_node = static_cast<ImageSlotNode*>(node);
+ int slot = image_node->slot;
+ if(slot != -1) {
+ bump_images.insert(slot);
+ }
+ }
+ }
+ }
+ }
+ foreach(int slot, bump_images) {
+ pool.push(function_bind(&ImageManager::device_update_slot,
+ image_manager,
+ device,
+ dscene,
+ slot,
+ &progress));
+ }
+ pool.wait_work();
+}
+
void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
VLOG(1) << "Total " << scene->meshes.size() << " meshes.";
@@ -1170,6 +1221,21 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
}
}
+ /* Update images needed for true displacement. */
+ bool need_displacement_images = false;
+ foreach(Mesh *mesh, scene->meshes) {
+ if(mesh->need_update &&
+ mesh->displacement_method != Mesh::DISPLACE_BUMP)
+ {
+ need_displacement_images = true;
+ break;
+ }
+ }
+ if(need_displacement_images) {
+ VLOG(1) << "Updating images used for true displacement.";
+ device_update_displacement_images(device, dscene, scene, progress);
+ }
+
/* device update */
device_free(device, dscene);
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 6eaafea8729..76c186a3feb 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -167,6 +167,7 @@ public:
void device_update_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_bvh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update_displacement_images(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 40bb82c6330..747bafcc904 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -186,7 +186,7 @@ ShaderEnum ImageTextureNode::color_space_enum = color_space_init();
ShaderEnum ImageTextureNode::projection_enum = image_projection_init();
ImageTextureNode::ImageTextureNode()
-: TextureNode("image_texture")
+: ImageSlotTextureNode("image_texture")
{
image_manager = NULL;
slot = -1;
@@ -380,7 +380,7 @@ ShaderEnum EnvironmentTextureNode::color_space_enum = color_space_init();
ShaderEnum EnvironmentTextureNode::projection_enum = env_projection_init();
EnvironmentTextureNode::EnvironmentTextureNode()
-: TextureNode("environment_texture")
+: ImageSlotTextureNode("environment_texture")
{
image_manager = NULL;
slot = -1;
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 0ec0fce512f..ee984773dcf 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -55,13 +55,28 @@ public:
/* Nodes */
+/* Any node which uses image manager's slot should be a subclass of this one. */
+class ImageSlotNode : public ShaderNode {
+public:
+ ImageSlotNode(const char *name_) : ShaderNode(name_) {
+ special_type = SHADER_SPECIAL_TYPE_IMAGE_SLOT;
+ }
+ int slot;
+};
+
class TextureNode : public ShaderNode {
public:
TextureNode(const char *name_) : ShaderNode(name_) {}
TextureMapping tex_mapping;
};
-class ImageTextureNode : public TextureNode {
+class ImageSlotTextureNode : public ImageSlotNode {
+public:
+ ImageSlotTextureNode(const char *name_) : ImageSlotNode(name_) {}
+ TextureMapping tex_mapping;
+};
+
+class ImageTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(ImageTextureNode)
~ImageTextureNode();
@@ -69,7 +84,6 @@ public:
void attributes(Shader *shader, AttributeRequestSet *attributes);
ImageManager *image_manager;
- int slot;
int is_float;
bool is_linear;
bool use_alpha;
@@ -85,7 +99,7 @@ public:
static ShaderEnum projection_enum;
};
-class EnvironmentTextureNode : public TextureNode {
+class EnvironmentTextureNode : public ImageSlotTextureNode {
public:
SHADER_NODE_NO_CLONE_CLASS(EnvironmentTextureNode)
~EnvironmentTextureNode();
@@ -93,7 +107,6 @@ public:
void attributes(Shader *shader, AttributeRequestSet *attributes);
ImageManager *image_manager;
- int slot;
int is_float;
bool is_linear;
bool use_alpha;
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 524574f096d..71741c0dfd1 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -160,11 +160,6 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel() || device->have_error()) return;
- progress.set_status("Updating Images");
- image_manager->device_update(device, &dscene, progress);
-
- if(progress.get_cancel() || device->have_error()) return;
-
progress.set_status("Updating Background");
background->device_update(device, &dscene, this);
@@ -195,6 +190,11 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel() || device->have_error()) return;
+ progress.set_status("Updating Images");
+ image_manager->device_update(device, &dscene, progress);
+
+ if(progress.get_cancel() || device->have_error()) return;
+
progress.set_status("Updating Camera Volume");
camera->device_update_volume(device, &dscene, this);