From 138362a3c928af5a23a6069fff541341ece7b025 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Mon, 1 Aug 2016 18:53:20 +0300 Subject: Cycles: add unit tests for supported constant folding rules. Code coverage of different combinations of secondary conditions is obviously not complete because there are so many of them, but all main rules should be there. The reason for CORRECT vs INVALID is that both words have the same number of characters so calls line up, but look quite different. Reviewers: #cycles, sergey Reviewed By: #cycles, sergey Subscribers: dingto, sergey, brecht Differential Revision: https://developer.blender.org/D2130 --- intern/cycles/render/constant_fold.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'intern/cycles/render') diff --git a/intern/cycles/render/constant_fold.cpp b/intern/cycles/render/constant_fold.cpp index 073bafce98d..200a4c497cd 100644 --- a/intern/cycles/render/constant_fold.cpp +++ b/intern/cycles/render/constant_fold.cpp @@ -40,7 +40,8 @@ bool ConstantFolder::all_inputs_constant() const void ConstantFolder::make_constant(float value) const { - VLOG(1) << "Replacing " << node->name << " with constant " << value << "."; + VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant (" << value << ")."; + foreach(ShaderInput *sock, output->links) { sock->set(value); } @@ -50,6 +51,8 @@ void ConstantFolder::make_constant(float value) const void ConstantFolder::make_constant(float3 value) const { + VLOG(1) << "Folding " << node->name << "::" << output->name() << " to constant " << value << "."; + foreach(ShaderInput *sock, output->links) { sock->set(value); } @@ -90,6 +93,8 @@ void ConstantFolder::bypass(ShaderOutput *new_output) const { assert(new_output); + VLOG(1) << "Folding " << node->name << "::" << output->name() << " to socket " << new_output->parent->name << "::" << new_output->name() << "."; + /* Remove all outgoing links from socket and connect them to new_output instead. * The graph->relink method affects node inputs, so it's not safe to use in constant * folding if the node has multiple outputs and will thus be folded multiple times. */ @@ -105,6 +110,9 @@ void ConstantFolder::bypass(ShaderOutput *new_output) const void ConstantFolder::discard() const { assert(output->type() == SocketType::CLOSURE); + + VLOG(1) << "Discarding closure " << node->name << "."; + graph->disconnect(output); } -- cgit v1.2.3 From e54320c4883ec8276e64991e5b1604f557d4e354 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 2 Aug 2016 12:22:43 +0300 Subject: Cycles: add folding for redundant A to B to A conversions. As a result of other folding simplifications it may happen that two type conversion nodes end up directly connected. In some cases it may be possible to then remove both. A realistic case might be an optimized out Mix RGB node used to blend vectors. It seems it's safe to optimize when B is a float3 type (color, vector), and A is float3 or float. Reviewers: #cycles, sergey Reviewed By: #cycles, sergey Subscribers: sergey Differential Revision: https://developer.blender.org/D2134 --- intern/cycles/render/nodes.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'intern/cycles/render') diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 9009d71da2f..4f54b86fe4a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1689,6 +1689,19 @@ void ConvertNode::constant_fold(const ConstantFolder& folder) } } } + else { + ShaderInput *in = inputs[0]; + ShaderNode *prev = in->link->parent; + + /* no-op conversion of A to B to A */ + if(prev->type == node_types[to][from]) { + ShaderInput *prev_in = prev->inputs[0]; + + if(SocketType::is_float3(from) && (to == SocketType::FLOAT || SocketType::is_float3(to)) && prev_in->link) { + folder.bypass(prev_in->link); + } + } + } } void ConvertNode::compile(SVMCompiler& compiler) -- cgit v1.2.3 From f2d5295abf7a5285cd851de45c8beff276e84d3a Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 2 Aug 2016 19:26:57 +0300 Subject: Cycles: log how many nodes were deduplicated for use in tests. To make the number more meaningful, also skip deduplicating obviously unused nodes with no outgoing links. --- intern/cycles/render/graph.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'intern/cycles/render') diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 3eeb7ffc2bc..6e795ef896a 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -24,6 +24,7 @@ #include "util_debug.h" #include "util_foreach.h" #include "util_queue.h" +#include "util_logging.h" CCL_NAMESPACE_BEGIN @@ -543,6 +544,7 @@ void ShaderGraph::deduplicate_nodes() ShaderNodeSet scheduled, done; map candidates; queue traverse_queue; + int num_deduplicated = 0; /* Schedule nodes which doesn't have any dependencies. */ foreach(ShaderNode *node, nodes) { @@ -557,8 +559,10 @@ void ShaderGraph::deduplicate_nodes() traverse_queue.pop(); done.insert(node); /* Schedule the nodes which were depending on the current node. */ + bool has_output_links = false; foreach(ShaderOutput *output, node->outputs) { foreach(ShaderInput *input, output->links) { + has_output_links = true; if(scheduled.find(input->parent) != scheduled.end()) { /* Node might not be optimized yet but scheduled already * by other dependencies. No need to re-schedule it. @@ -572,6 +576,10 @@ void ShaderGraph::deduplicate_nodes() } } } + /* Only need to care about nodes that are actually used */ + if(!has_output_links) { + continue; + } /* Try to merge this node with another one. */ ShaderNode *merge_with = NULL; foreach(ShaderNode *other_node, candidates[node->type->name]) { @@ -585,11 +593,16 @@ void ShaderGraph::deduplicate_nodes() for(int i = 0; i < node->outputs.size(); ++i) { relink(node, node->outputs[i], merge_with->outputs[i]); } + num_deduplicated++; } else { candidates[node->type->name].insert(node); } } + + if(num_deduplicated > 0) { + VLOG(1) << "Deduplicated " << num_deduplicated << " nodes."; + } } void ShaderGraph::break_cycles(ShaderNode *node, vector& visited, vector& on_stack) -- cgit v1.2.3 From 285e082a772f99fc09e52bcc8e8dd95f66431a60 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 3 Aug 2016 12:38:25 +0200 Subject: Fix T49010: Portals don't work in recent Blender versions --- intern/cycles/render/light.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'intern/cycles/render') diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index ae6042cef34..4cd77f8c6e1 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -238,14 +238,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen /* count */ size_t num_lights = 0; + size_t num_portals = 0; size_t num_background_lights = 0; size_t num_triangles = 0; bool background_mis = false; foreach(Light *light, scene->lights) { - if(light->is_enabled) + if(light->is_enabled) { num_lights++; + } + if(light->is_portal) { + num_portals++; + } } foreach(Object *object, scene->objects) { @@ -435,9 +440,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen device->tex_alloc("__light_distribution", dscene->light_distribution); /* Portals */ - if(num_background_lights > 0 && light_index != num_lights) { + if(num_portals > 0) { kintegrator->portal_offset = light_index; - kintegrator->num_portals = num_lights - light_index; + kintegrator->num_portals = num_portals; kintegrator->portal_pdf = background_mis? 0.5f: 1.0f; } else { @@ -601,10 +606,10 @@ void LightManager::device_update_points(Device *device, Scene *scene) { int num_scene_lights = scene->lights.size(); - int num_lights = 0; + int num_lights = 0; foreach(Light *light, scene->lights) { - if(light->is_enabled) { + if(light->is_enabled || light->is_portal) { num_lights++; } } -- cgit v1.2.3