Cycles: Wrap SVM compiler state variables into a single struct
This way it's easier to pass stuff around and also much easier to add more state variables. So far should be no functional changes for artists.
This commit is contained in:
@@ -411,8 +411,11 @@ void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet& done)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes, ShaderNodeSet& done)
|
void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes,
|
||||||
|
CompilerState *state)
|
||||||
{
|
{
|
||||||
|
ShaderNodeSet& done = state->nodes_done;
|
||||||
|
|
||||||
bool nodes_done;
|
bool nodes_done;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -438,14 +441,15 @@ void SVMCompiler::generate_svm_nodes(const ShaderNodeSet& nodes, ShaderNodeSet&
|
|||||||
} while(!nodes_done);
|
} while(!nodes_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::generate_closure_node(ShaderNode *node, ShaderNodeSet& done)
|
void SVMCompiler::generate_closure_node(ShaderNode *node,
|
||||||
|
CompilerState *state)
|
||||||
{
|
{
|
||||||
/* execute dependencies for closure */
|
/* execute dependencies for closure */
|
||||||
foreach(ShaderInput *in, node->inputs) {
|
foreach(ShaderInput *in, node->inputs) {
|
||||||
if(!node_skip_input(node, in) && in->link) {
|
if(!node_skip_input(node, in) && in->link) {
|
||||||
ShaderNodeSet dependencies;
|
ShaderNodeSet dependencies;
|
||||||
find_dependencies(dependencies, done, in);
|
find_dependencies(dependencies, state->nodes_done, in);
|
||||||
generate_svm_nodes(dependencies, done);
|
generate_svm_nodes(dependencies, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +465,7 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, ShaderNodeSet& done)
|
|||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
|
||||||
/* compile closure itself */
|
/* compile closure itself */
|
||||||
generate_node(node, done);
|
generate_node(node, state->nodes_done);
|
||||||
|
|
||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
|
||||||
@@ -480,32 +484,32 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, ShaderNodeSet& done)
|
|||||||
|
|
||||||
void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
|
void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
|
||||||
ShaderNode *node,
|
ShaderNode *node,
|
||||||
ShaderNodeSet& done,
|
CompilerState *state,
|
||||||
ShaderNodeSet& closure_done,
|
|
||||||
const ShaderNodeSet& shared)
|
const ShaderNodeSet& shared)
|
||||||
{
|
{
|
||||||
if(shared.find(node) != shared.end()) {
|
if(shared.find(node) != shared.end()) {
|
||||||
generate_multi_closure(root_node, node, done, closure_done);
|
generate_multi_closure(root_node, node, state);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
foreach(ShaderInput *in, node->inputs) {
|
foreach(ShaderInput *in, node->inputs) {
|
||||||
if(in->type == SHADER_SOCKET_CLOSURE && in->link)
|
if(in->type == SHADER_SOCKET_CLOSURE && in->link)
|
||||||
generated_shared_closure_nodes(root_node, in->link->parent,
|
generated_shared_closure_nodes(root_node,
|
||||||
done, closure_done, shared);
|
in->link->parent,
|
||||||
|
state,
|
||||||
|
shared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
||||||
ShaderNode *node,
|
ShaderNode *node,
|
||||||
ShaderNodeSet& done,
|
CompilerState *state)
|
||||||
ShaderNodeSet& closure_done)
|
|
||||||
{
|
{
|
||||||
/* only generate once */
|
/* only generate once */
|
||||||
if(closure_done.find(node) != closure_done.end())
|
if(state->closure_done.find(node) != state->closure_done.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
closure_done.insert(node);
|
state->closure_done.insert(node);
|
||||||
|
|
||||||
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
|
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
|
||||||
/* weighting is already taken care of in ShaderGraph::transform_multi_closure */
|
/* weighting is already taken care of in ShaderGraph::transform_multi_closure */
|
||||||
@@ -520,8 +524,8 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
if(facin && facin->link) {
|
if(facin && facin->link) {
|
||||||
/* mix closure: generate instructions to compute mix weight */
|
/* mix closure: generate instructions to compute mix weight */
|
||||||
ShaderNodeSet dependencies;
|
ShaderNodeSet dependencies;
|
||||||
find_dependencies(dependencies, done, facin);
|
find_dependencies(dependencies, state->nodes_done, facin);
|
||||||
generate_svm_nodes(dependencies, done);
|
generate_svm_nodes(dependencies, state);
|
||||||
|
|
||||||
stack_assign(facin);
|
stack_assign(facin);
|
||||||
|
|
||||||
@@ -530,8 +534,8 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
* ensure that they only skip dependencies that are unique to them */
|
* ensure that they only skip dependencies that are unique to them */
|
||||||
ShaderNodeSet cl1deps, cl2deps, shareddeps;
|
ShaderNodeSet cl1deps, cl2deps, shareddeps;
|
||||||
|
|
||||||
find_dependencies(cl1deps, done, cl1in);
|
find_dependencies(cl1deps, state->nodes_done, cl1in);
|
||||||
find_dependencies(cl2deps, done, cl2in);
|
find_dependencies(cl2deps, state->nodes_done, cl2in);
|
||||||
|
|
||||||
ShaderNodeIDComparator node_id_comp;
|
ShaderNodeIDComparator node_id_comp;
|
||||||
set_intersection(cl1deps.begin(), cl1deps.end(),
|
set_intersection(cl1deps.begin(), cl1deps.end(),
|
||||||
@@ -546,7 +550,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
if(root_node != node) {
|
if(root_node != node) {
|
||||||
foreach(ShaderInput *in, root_node->inputs) {
|
foreach(ShaderInput *in, root_node->inputs) {
|
||||||
ShaderNodeSet rootdeps;
|
ShaderNodeSet rootdeps;
|
||||||
find_dependencies(rootdeps, done, in, node);
|
find_dependencies(rootdeps, state->nodes_done, in, node);
|
||||||
set_intersection(rootdeps.begin(), rootdeps.end(),
|
set_intersection(rootdeps.begin(), rootdeps.end(),
|
||||||
cl1deps.begin(), cl1deps.end(),
|
cl1deps.begin(), cl1deps.end(),
|
||||||
std::inserter(shareddeps, shareddeps.begin()),
|
std::inserter(shareddeps, shareddeps.begin()),
|
||||||
@@ -560,15 +564,19 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
|
|
||||||
if(!shareddeps.empty()) {
|
if(!shareddeps.empty()) {
|
||||||
if(cl1in->link) {
|
if(cl1in->link) {
|
||||||
generated_shared_closure_nodes(root_node, cl1in->link->parent,
|
generated_shared_closure_nodes(root_node,
|
||||||
done, closure_done, shareddeps);
|
cl1in->link->parent,
|
||||||
|
state,
|
||||||
|
shareddeps);
|
||||||
}
|
}
|
||||||
if(cl2in->link) {
|
if(cl2in->link) {
|
||||||
generated_shared_closure_nodes(root_node, cl2in->link->parent,
|
generated_shared_closure_nodes(root_node,
|
||||||
done, closure_done, shareddeps);
|
cl2in->link->parent,
|
||||||
|
state,
|
||||||
|
shareddeps);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_svm_nodes(shareddeps, done);
|
generate_svm_nodes(shareddeps, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate instructions for input closure 1 */
|
/* generate instructions for input closure 1 */
|
||||||
@@ -577,7 +585,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
svm_nodes.push_back(make_int4(NODE_JUMP_IF_ONE, 0, facin->stack_offset, 0));
|
svm_nodes.push_back(make_int4(NODE_JUMP_IF_ONE, 0, facin->stack_offset, 0));
|
||||||
int node_jump_skip_index = svm_nodes.size() - 1;
|
int node_jump_skip_index = svm_nodes.size() - 1;
|
||||||
|
|
||||||
generate_multi_closure(root_node, cl1in->link->parent, done, closure_done);
|
generate_multi_closure(root_node, cl1in->link->parent, state);
|
||||||
|
|
||||||
/* fill in jump instruction location to be after closure */
|
/* fill in jump instruction location to be after closure */
|
||||||
svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
|
svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
|
||||||
@@ -589,7 +597,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
svm_nodes.push_back(make_int4(NODE_JUMP_IF_ZERO, 0, facin->stack_offset, 0));
|
svm_nodes.push_back(make_int4(NODE_JUMP_IF_ZERO, 0, facin->stack_offset, 0));
|
||||||
int node_jump_skip_index = svm_nodes.size() - 1;
|
int node_jump_skip_index = svm_nodes.size() - 1;
|
||||||
|
|
||||||
generate_multi_closure(root_node, cl2in->link->parent, done, closure_done);
|
generate_multi_closure(root_node, cl2in->link->parent, state);
|
||||||
|
|
||||||
/* fill in jump instruction location to be after closure */
|
/* fill in jump instruction location to be after closure */
|
||||||
svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
|
svm_nodes[node_jump_skip_index].y = svm_nodes.size() - node_jump_skip_index - 1;
|
||||||
@@ -603,16 +611,16 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
|||||||
* to skip closures here because was already optimized due to
|
* to skip closures here because was already optimized due to
|
||||||
* fixed weight or add closure that always needs both */
|
* fixed weight or add closure that always needs both */
|
||||||
if(cl1in->link)
|
if(cl1in->link)
|
||||||
generate_multi_closure(root_node, cl1in->link->parent, done, closure_done);
|
generate_multi_closure(root_node, cl1in->link->parent, state);
|
||||||
if(cl2in->link)
|
if(cl2in->link)
|
||||||
generate_multi_closure(root_node, cl2in->link->parent, done, closure_done);
|
generate_multi_closure(root_node, cl2in->link->parent, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
generate_closure_node(node, done);
|
generate_closure_node(node, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
done.insert(node);
|
state->nodes_done.insert(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -689,9 +697,10 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(generate) {
|
if(generate) {
|
||||||
ShaderNodeSet done, closure_done;
|
CompilerState state;
|
||||||
generate_multi_closure(clin->link->parent, clin->link->parent,
|
generate_multi_closure(clin->link->parent,
|
||||||
done, closure_done);
|
clin->link->parent,
|
||||||
|
&state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -152,6 +152,15 @@ protected:
|
|||||||
ShaderNodeSet done;
|
ShaderNodeSet done;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Global state of the compiler accessible from the compilation routines. */
|
||||||
|
struct CompilerState {
|
||||||
|
/* Set of nodes which were already compiled. */
|
||||||
|
ShaderNodeSet nodes_done;
|
||||||
|
|
||||||
|
/* Set of closures which were already compiled. */
|
||||||
|
ShaderNodeSet closure_done;
|
||||||
|
};
|
||||||
|
|
||||||
void stack_backup(StackBackup& backup, ShaderNodeSet& done);
|
void stack_backup(StackBackup& backup, ShaderNodeSet& done);
|
||||||
void stack_restore(StackBackup& backup, ShaderNodeSet& done);
|
void stack_restore(StackBackup& backup, ShaderNodeSet& done);
|
||||||
|
|
||||||
@@ -167,18 +176,18 @@ protected:
|
|||||||
ShaderInput *input,
|
ShaderInput *input,
|
||||||
ShaderNode *skip_node = NULL);
|
ShaderNode *skip_node = NULL);
|
||||||
void generate_node(ShaderNode *node, ShaderNodeSet& done);
|
void generate_node(ShaderNode *node, ShaderNodeSet& done);
|
||||||
void generate_closure_node(ShaderNode *node, ShaderNodeSet& done);
|
void generate_closure_node(ShaderNode *node, CompilerState *state);
|
||||||
void generated_shared_closure_nodes(ShaderNode *root_node, ShaderNode *node,
|
void generated_shared_closure_nodes(ShaderNode *root_node,
|
||||||
ShaderNodeSet& done,
|
ShaderNode *node,
|
||||||
ShaderNodeSet& closure_done,
|
CompilerState *state,
|
||||||
const ShaderNodeSet& shared);
|
const ShaderNodeSet& shared);
|
||||||
void generate_svm_nodes(const ShaderNodeSet& nodes, ShaderNodeSet& done);
|
void generate_svm_nodes(const ShaderNodeSet& nodes,
|
||||||
|
CompilerState *state);
|
||||||
|
|
||||||
/* multi closure */
|
/* multi closure */
|
||||||
void generate_multi_closure(ShaderNode *root_node,
|
void generate_multi_closure(ShaderNode *root_node,
|
||||||
ShaderNode *node,
|
ShaderNode *node,
|
||||||
ShaderNodeSet& done,
|
CompilerState *state);
|
||||||
ShaderNodeSet& closure_done);
|
|
||||||
|
|
||||||
/* compile */
|
/* compile */
|
||||||
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
|
void compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
|
||||||
|
Reference in New Issue
Block a user