[Bf-blender-cvs] [90c18b4] cycles_memory_experiments: Cycles: Synchronize images after building mesh BVH

Sergey Sharybin noreply at git.blender.org
Fri Apr 10 20:33:19 CEST 2015


Commit: 90c18b422de5169354e7360acb239f939af48ff8
Author: Sergey Sharybin
Date:   Thu Apr 2 20:37:57 2015 +0500
Branches: cycles_memory_experiments
https://developer.blender.org/rB90c18b422de5169354e7360acb239f939af48ff8

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

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

M	intern/cycles/render/image.cpp
M	intern/cycles/render/image.h
M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/scene.cpp

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

diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 6e63b43..0dd8041 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(!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 1045b45..70cc493 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 74ea3c9..c21a9ac 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,50 @@ 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;
+	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) {
+					foreach(ShaderNode* node, shader->graph_bump->nodes) {
+						int slot = -1;
+						if(node->name == "image_texture") {
+							slot = ((ImageTextureNode *)node)->slot;
+						}
+						if(slot != -1) {
+							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;
+							}
+							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 +1216,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 6eaafea..76c186a 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/scene.cpp b/intern/cycles/render/scene.cpp
index 524574f..71741c0 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);




More information about the Bf-blender-cvs mailing list