diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-30 15:51:17 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-30 15:51:17 +0400 |
commit | 0c3d3e5562770586eaa95d6087d190240de5b8f2 (patch) | |
tree | cf72e859a15a12d2bbf5c6129dc7d5f91f384e6e | |
parent | e09a1bc7cff068484ec43bb3383d4981e998c0cf (diff) |
Cycles: optimization to not compile shaders and load images that are not
used by any mesh/lamp/world.
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 33 | ||||
-rw-r--r-- | intern/cycles/render/shader.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 57 |
5 files changed, 76 insertions, 29 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 0ce1a7dcf28..188996cc34d 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -43,6 +43,7 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default for(size_t i = 0; i < scene->shaders.size(); i++) { if(scene->shaders[i] == shader) { used_shaders.push_back(i); + scene->shaders[i]->tag_used(scene); break; } } diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 638bfa8634e..4856a8d4e0c 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -99,6 +99,9 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene device_free(device, dscene); + /* determine which shaders are in use */ + device_update_shaders_used(scene); + /* create shaders */ OSLGlobals *og = (OSLGlobals*)device->osl_memory(); @@ -530,7 +533,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) shader->has_displacement = false; /* generate surface shader */ - if(graph && output->input("Surface")->link) { + if(shader->used && graph && output->input("Surface")->link) { compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); og->surface_state.push_back(ss->state()); @@ -552,7 +555,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) } /* generate volume shader */ - if(graph && output->input("Volume")->link) { + if(shader->used && graph && output->input("Volume")->link) { compile_type(shader, shader->graph, SHADER_TYPE_VOLUME); shader->has_volume = true; @@ -566,7 +569,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) } /* generate displacement shader */ - if(graph && output->input("Displacement")->link) { + if(shader->used && graph && output->input("Displacement")->link) { compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT); shader->has_displacement = true; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index fae1d6bd81c..17f7fbd43d6 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -49,6 +49,8 @@ Shader::Shader() has_volume = false; has_displacement = false; + used = false; + need_update = true; need_update_attributes = true; } @@ -98,6 +100,16 @@ void Shader::tag_update(Scene *scene) } } +void Shader::tag_used(Scene *scene) +{ + /* if an unused shader suddenly gets used somewhere, it needs to be + * recompiled because it was skipped for compilation before */ + if(!used) { + need_update = true; + scene->shader_manager->need_update = true; + } +} + /* Shader Manager */ ShaderManager::ShaderManager() @@ -161,6 +173,27 @@ int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth) return id; } +void ShaderManager::device_update_shaders_used(Scene *scene) +{ + /* figure out which shaders are in use, so SVM/OSL can skip compiling them + * for speed and avoid loading image textures into memory */ + foreach(Shader *shader, scene->shaders) + shader->used = false; + + scene->shaders[scene->default_surface]->used = true; + scene->shaders[scene->default_light]->used = true; + scene->shaders[scene->default_background]->used = true; + scene->shaders[scene->default_holdout]->used = true; + scene->shaders[scene->default_empty]->used = true; + + foreach(Mesh *mesh, scene->meshes) + foreach(uint shader, mesh->used_shaders) + scene->shaders[shader]->used = true; + + foreach(Light *light, scene->lights) + scene->shaders[light->shader]->used = true; +} + void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { device_free_common(device, dscene); diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 02788008060..90ae67eecff 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -75,11 +75,15 @@ public: /* requested mesh attributes */ AttributeRequestSet attributes; + /* determined before compiling */ + bool used; + Shader(); ~Shader(); void set_graph(ShaderGraph *graph); void tag_update(Scene *scene); + void tag_used(Scene *scene); }; /* Shader Manager virtual base class @@ -98,6 +102,7 @@ public: virtual void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) = 0; virtual void device_free(Device *device, DeviceScene *dscene) = 0; + void device_update_shaders_used(Scene *scene); void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_free_common(Device *device, DeviceScene *dscene); diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index c41d503b217..dc249984499 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -48,6 +48,9 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene /* test if we need to update */ device_free(device, dscene); + /* determine which shaders are in use */ + device_update_shaders_used(scene); + /* svm_nodes */ vector<int4> svm_nodes; size_t i; @@ -609,36 +612,38 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty output->stack_offset = SVM_STACK_INVALID; } - if(clin->link) { - bool generate = false; - if(type == SHADER_TYPE_SURFACE) { - /* generate surface shader */ - generate = true; - shader->has_surface = true; - } - else if(type == SHADER_TYPE_VOLUME) { - /* generate volume shader */ - generate = true; - shader->has_volume = true; - } - else if(type == SHADER_TYPE_DISPLACEMENT) { - /* generate displacement shader */ - generate = true; - shader->has_displacement = true; - } + if(shader->used) { + if(clin->link) { + bool generate = false; + if(type == SHADER_TYPE_SURFACE) { + /* generate surface shader */ + generate = true; + shader->has_surface = true; + } + else if(type == SHADER_TYPE_VOLUME) { + /* generate volume shader */ + generate = true; + shader->has_volume = true; + } + else if(type == SHADER_TYPE_DISPLACEMENT) { + /* generate displacement shader */ + generate = true; + shader->has_displacement = true; + } - if(generate) { - set<ShaderNode*> done; + if(generate) { + set<ShaderNode*> done; - if(use_multi_closure) - generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID); - else - generate_closure(clin->link->parent, done); + if(use_multi_closure) + generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID); + else + generate_closure(clin->link->parent, done); + } } - } - /* compile output node */ - node->compile(*this); + /* compile output node */ + node->compile(*this); + } add_node(NODE_END, 0, 0, 0); } |