forked from bartvdbraak/blender
37933cb048
This commit adds some easy to use way to check whether the graph was properly optimized. The idea is based on using mock glog sync which keeps track on all messages and expects specific log message to appear in the logging. This means each optimization step should report that it optimized something (specifying what exactly was optimized) and what was used for optimization. There's also some ease-ish way to define shader networks which we might want to make a bit more global and available for all tests in the future. For now only RGBToBW node is covered as an example, really hope to get help from active guys in the community to finish covering all existing optimization cases. Ready to fix any possible issues with builder when needed tho :)
125 lines
2.8 KiB
C++
125 lines
2.8 KiB
C++
/*
|
|
* Copyright 2011-2013 Blender Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "constant_fold.h"
|
|
#include "graph.h"
|
|
|
|
#include "util_foreach.h"
|
|
#include "util_logging.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
ConstantFolder::ConstantFolder(ShaderGraph *graph, ShaderNode *node, ShaderOutput *output)
|
|
: graph(graph), node(node), output(output)
|
|
{
|
|
}
|
|
|
|
bool ConstantFolder::all_inputs_constant() const
|
|
{
|
|
foreach(ShaderInput *input, node->inputs) {
|
|
if(input->link) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ConstantFolder::make_constant(float value) const
|
|
{
|
|
VLOG(1) << "Replacing " << node->name << " with constant " << value << ".";
|
|
foreach(ShaderInput *sock, output->links) {
|
|
sock->set(value);
|
|
}
|
|
|
|
graph->disconnect(output);
|
|
}
|
|
|
|
void ConstantFolder::make_constant(float3 value) const
|
|
{
|
|
foreach(ShaderInput *sock, output->links) {
|
|
sock->set(value);
|
|
}
|
|
|
|
graph->disconnect(output);
|
|
}
|
|
|
|
void ConstantFolder::make_constant_clamp(float value, bool clamp) const
|
|
{
|
|
make_constant(clamp ? saturate(value) : value);
|
|
}
|
|
|
|
void ConstantFolder::make_constant_clamp(float3 value, bool clamp) const
|
|
{
|
|
if (clamp) {
|
|
value.x = saturate(value.x);
|
|
value.y = saturate(value.y);
|
|
value.z = saturate(value.z);
|
|
}
|
|
|
|
make_constant(value);
|
|
}
|
|
|
|
void ConstantFolder::bypass(ShaderOutput *new_output) const
|
|
{
|
|
assert(new_output);
|
|
|
|
/* 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. */
|
|
vector<ShaderInput*> outputs = output->links;
|
|
|
|
graph->disconnect(output);
|
|
|
|
foreach(ShaderInput *sock, outputs) {
|
|
graph->connect(new_output, sock);
|
|
}
|
|
}
|
|
|
|
void ConstantFolder::discard() const
|
|
{
|
|
assert(output->type() == SocketType::CLOSURE);
|
|
graph->disconnect(output);
|
|
}
|
|
|
|
void ConstantFolder::bypass_or_discard(ShaderInput *input) const
|
|
{
|
|
assert(input->type() == SocketType::CLOSURE);
|
|
|
|
if (input->link) {
|
|
bypass(input->link);
|
|
}
|
|
else {
|
|
discard();
|
|
}
|
|
}
|
|
|
|
bool ConstantFolder::try_bypass_or_make_constant(ShaderInput *input, float3 input_value, bool clamp) const
|
|
{
|
|
if(!input->link) {
|
|
make_constant_clamp(input_value, clamp);
|
|
return true;
|
|
}
|
|
else if(!clamp) {
|
|
bypass(input->link);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
CCL_NAMESPACE_END
|