forked from bartvdbraak/blender
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.
This commit is contained in:
parent
18ae259cc4
commit
7fd4c440ec
@ -556,6 +556,7 @@ MeshManager::MeshManager()
|
|||||||
{
|
{
|
||||||
bvh = NULL;
|
bvh = NULL;
|
||||||
need_update = true;
|
need_update = true;
|
||||||
|
need_flags_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshManager::~MeshManager()
|
MeshManager::~MeshManager()
|
||||||
@ -1034,20 +1035,33 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
|
|||||||
dscene->data.bvh.use_qbvh = scene->params.use_qbvh;
|
dscene->data.bvh.use_qbvh = scene->params.use_qbvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
|
||||||
{
|
{
|
||||||
if(!need_update)
|
if(!need_update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* update normals and flags */
|
/* update normals */
|
||||||
foreach(Mesh *mesh, scene->meshes) {
|
foreach(Mesh *mesh, scene->meshes) {
|
||||||
mesh->has_volume = false;
|
|
||||||
foreach(uint shader, mesh->used_shaders) {
|
foreach(uint shader, mesh->used_shaders) {
|
||||||
if(scene->shaders[shader]->need_update_attributes)
|
if(scene->shaders[shader]->need_update_attributes)
|
||||||
mesh->need_update = true;
|
mesh->need_update = true;
|
||||||
if(scene->shaders[shader]->has_volume) {
|
|
||||||
mesh->has_volume = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mesh->need_update) {
|
if(mesh->need_update) {
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
vector<uint> shader;
|
vector<uint> shader;
|
||||||
vector<bool> smooth;
|
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<float4> curve_keys; /* co + radius */
|
||||||
vector<Curve> curves;
|
vector<Curve> curves;
|
||||||
@ -145,6 +145,7 @@ public:
|
|||||||
BVH *bvh;
|
BVH *bvh;
|
||||||
|
|
||||||
bool need_update;
|
bool need_update;
|
||||||
|
bool need_flags_update;
|
||||||
|
|
||||||
MeshManager();
|
MeshManager();
|
||||||
~MeshManager();
|
~MeshManager();
|
||||||
@ -160,6 +161,7 @@ public:
|
|||||||
void device_update_mesh(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
|
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_attributes(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
|
||||||
void device_update_bvh(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 device_free(Device *device, DeviceScene *dscene);
|
||||||
|
|
||||||
void tag_update(Scene *scene);
|
void tag_update(Scene *scene);
|
||||||
|
@ -221,6 +221,7 @@ vector<float> Object::motion_times()
|
|||||||
ObjectManager::ObjectManager()
|
ObjectManager::ObjectManager()
|
||||||
{
|
{
|
||||||
need_update = true;
|
need_update = true;
|
||||||
|
need_flags_update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectManager::~ObjectManager()
|
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,
|
void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
|
||||||
Scene *scene, Progress& progress)
|
Scene *scene, Progress& progress)
|
||||||
{
|
{
|
||||||
if(!need_update)
|
if(!need_update && !need_flags_update)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
need_update = false;
|
need_update = false;
|
||||||
|
need_flags_update = false;
|
||||||
|
|
||||||
if(scene->objects.size() == 0)
|
if(scene->objects.size() == 0)
|
||||||
return;
|
return;
|
||||||
@ -427,6 +429,9 @@ void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
|
|||||||
if(object->mesh->has_volume) {
|
if(object->mesh->has_volume) {
|
||||||
object_flag[object_index] |= SD_OBJECT_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) {
|
foreach(Object *volume_object, volume_objects) {
|
||||||
if(object == volume_object) {
|
if(object == volume_object) {
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
class ObjectManager {
|
class ObjectManager {
|
||||||
public:
|
public:
|
||||||
bool need_update;
|
bool need_update;
|
||||||
|
bool need_flags_update;
|
||||||
|
|
||||||
ObjectManager();
|
ObjectManager();
|
||||||
~ObjectManager();
|
~ObjectManager();
|
||||||
|
@ -170,8 +170,8 @@ void Scene::device_update(Device *device_, Progress& progress)
|
|||||||
|
|
||||||
if(progress.get_cancel() || device->have_error()) return;
|
if(progress.get_cancel() || device->have_error()) return;
|
||||||
|
|
||||||
progress.set_status("Updating Meshes");
|
progress.set_status("Updating Meshes Flags");
|
||||||
mesh_manager->device_update(device, &dscene, this, progress);
|
mesh_manager->device_update_flags(device, &dscene, this, progress);
|
||||||
|
|
||||||
if(progress.get_cancel() || device->have_error()) return;
|
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;
|
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");
|
progress.set_status("Updating Hair Systems");
|
||||||
curve_system_manager->device_update(device, &dscene, this, progress);
|
curve_system_manager->device_update(device, &dscene, this, progress);
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "light.h"
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "nodes.h"
|
#include "nodes.h"
|
||||||
|
#include "object.h"
|
||||||
#include "osl.h"
|
#include "osl.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "shader.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
|
* e.g. surface attributes when there is only a volume shader. this could
|
||||||
* be more fine grained but it's better than nothing */
|
* be more fine grained but it's better than nothing */
|
||||||
OutputNode *output = graph->output();
|
OutputNode *output = graph->output();
|
||||||
|
bool prev_has_volume = has_volume;
|
||||||
has_surface = has_surface || output->input("Surface")->link;
|
has_surface = has_surface || output->input("Surface")->link;
|
||||||
has_volume = has_volume || output->input("Volume")->link;
|
has_volume = has_volume || output->input("Volume")->link;
|
||||||
has_displacement = has_displacement || output->input("Displacement")->link;
|
has_displacement = has_displacement || output->input("Displacement")->link;
|
||||||
@ -215,6 +217,11 @@ void Shader::tag_update(Scene *scene)
|
|||||||
need_update_attributes = true;
|
need_update_attributes = true;
|
||||||
scene->mesh_manager->need_update = 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)
|
void Shader::tag_used(Scene *scene)
|
||||||
|
Loading…
Reference in New Issue
Block a user