[Bf-blender-cvs] [c9ca7b8] blender-v2.73-release: Fix T43311: using displacement shader crashes blender

Sergey Sharybin noreply at git.blender.org
Tue Jan 20 10:23:42 CET 2015


Commit: c9ca7b816ef2a1daab2aba508a266d079ef21417
Author: Sergey Sharybin
Date:   Mon Jan 19 19:08:58 2015 +0500
Branches: blender-v2.73-release
https://developer.blender.org/rBc9ca7b816ef2a1daab2aba508a266d079ef21417

Fix T43311: using displacement shader crashes blender

Issue was caused by wrong order of scene device update, which could
lead to missing object flags in shader kernel.

This patch solves a bit more than that making sure objects flags are
always properly updated, so adding/removing volume BSDF will properly
reflect on viewport where camera might become being in volume and so.

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

M	intern/cycles/render/mesh.cpp
M	intern/cycles/render/mesh.h
M	intern/cycles/render/object.cpp
M	intern/cycles/render/object.h
M	intern/cycles/render/scene.cpp
M	intern/cycles/render/shader.cpp

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

diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 6137f7d..7f9bb85 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -555,6 +555,7 @@ MeshManager::MeshManager()
 {
 	bvh = NULL;
 	need_update = true;
+	need_flags_update = true;
 }
 
 MeshManager::~MeshManager()
@@ -1029,20 +1030,33 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
 	dscene->data.bvh.root = pack.root_index;
 }
 
+void MeshManager::device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+	if(!need_update && !need_flags_update) {
+		return;
+	}
+	/* update flags */
+	foreach(Mesh *mesh, scene->meshes) {
+		mesh->has_volume = false;
+		foreach(uint shader, mesh->used_shaders) {
+			if(scene->shaders[shader]->has_volume) {
+				mesh->has_volume = true;
+			}
+		}
+	}
+	need_flags_update = false;
+}
+
 void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
 {
 	if(!need_update)
 		return;
 
-	/* update normals and flags */
+	/* update normals */
 	foreach(Mesh *mesh, scene->meshes) {
-		mesh->has_volume = false;
 		foreach(uint shader, mesh->used_shaders) {
 			if(scene->shaders[shader]->need_update_attributes)
 				mesh->need_update = true;
-			if(scene->shaders[shader]->has_volume) {
-				mesh->has_volume = true;
-			}
 		}
 
 		if(mesh->need_update) {
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index 7e34b76..fdd3d3c 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -79,7 +79,7 @@ public:
 	vector<uint> shader;
 	vector<bool> smooth;
 
-	bool has_volume;  /* Set in the device_update(). */
+	bool has_volume;  /* Set in the device_update_flags(). */
 
 	vector<float4> curve_keys; /* co + radius */
 	vector<Curve> curves;
@@ -145,6 +145,7 @@ public:
 	BVH *bvh;
 
 	bool need_update;
+	bool need_flags_update;
 
 	MeshManager();
 	~MeshManager();
@@ -160,6 +161,7 @@ public:
 	void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
 	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_free(Device *device, DeviceScene *dscene);
 
 	void tag_update(Scene *scene);
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 3b2a3ae..3f57135 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -221,6 +221,7 @@ vector<float> Object::motion_times()
 ObjectManager::ObjectManager()
 {
 	need_update = true;
+	need_flags_update = true;
 }
 
 ObjectManager::~ObjectManager()
@@ -404,10 +405,11 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
 void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
                                         Scene *scene, Progress& progress)
 {
-	if(!need_update)
+	if(!need_update && !need_flags_update)
 		return;
 
 	need_update = false;
+	need_flags_update = false;
 
 	if(scene->objects.size() == 0)
 		return;
@@ -427,6 +429,9 @@ void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
 		if(object->mesh->has_volume) {
 			object_flag[object_index] |= SD_OBJECT_HAS_VOLUME;
 		}
+		else {
+			object_flag[object_index] &= ~SD_OBJECT_HAS_VOLUME;
+		}
 
 		foreach(Object *volume_object, volume_objects) {
 			if(object == volume_object) {
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 2c69b83..ce07484 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -70,6 +70,7 @@ public:
 class ObjectManager {
 public:
 	bool need_update;
+	bool need_flags_update;
 
 	ObjectManager();
 	~ObjectManager();
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index ccb03ea..7da7ca0 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -170,8 +170,8 @@ void Scene::device_update(Device *device_, Progress& progress)
 
 	if(progress.get_cancel() || device->have_error()) return;
 
-	progress.set_status("Updating Meshes");
-	mesh_manager->device_update(device, &dscene, this, progress);
+	progress.set_status("Updating Meshes Flags");
+	mesh_manager->device_update_flags(device, &dscene, this, progress);
 
 	if(progress.get_cancel() || device->have_error()) return;
 
@@ -180,6 +180,11 @@ void Scene::device_update(Device *device_, Progress& progress)
 
 	if(progress.get_cancel() || device->have_error()) return;
 
+	progress.set_status("Updating Meshes");
+	mesh_manager->device_update(device, &dscene, this, progress);
+
+	if(progress.get_cancel() || device->have_error()) return;
+
 	progress.set_status("Updating Hair Systems");
 	curve_system_manager->device_update(device, &dscene, this, progress);
 
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 5c30d19..9fa6be0 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -21,6 +21,7 @@
 #include "light.h"
 #include "mesh.h"
 #include "nodes.h"
+#include "object.h"
 #include "osl.h"
 #include "scene.h"
 #include "shader.h"
@@ -194,6 +195,7 @@ void Shader::tag_update(Scene *scene)
 	 * e.g. surface attributes when there is only a volume shader. this could
 	 * be more fine grained but it's better than nothing */
 	OutputNode *output = graph->output();
+	bool prev_has_volume = has_volume;
 	has_surface = has_surface || output->input("Surface")->link;
 	has_volume = has_volume || output->input("Volume")->link;
 	has_displacement = has_displacement || output->input("Displacement")->link;
@@ -215,6 +217,11 @@ void Shader::tag_update(Scene *scene)
 		need_update_attributes = true;
 		scene->mesh_manager->need_update = true;
 	}
+
+	if(has_volume != prev_has_volume) {
+		scene->mesh_manager->need_flags_update = true;
+		scene->object_manager->need_flags_update = true;
+	}
 }
 
 void Shader::tag_used(Scene *scene)




More information about the Bf-blender-cvs mailing list