@@ -19,6 +19,12 @@ ShaderNodeImplPtr CompoundNode::create()
1919 return std::make_shared<CompoundNode>();
2020}
2121
22+ void CompoundNode::addClassification (ShaderNode& node) const
23+ {
24+ // Add classification from the graph implementation.
25+ node.addClassification (_rootGraph->getClassification ());
26+ }
27+
2228void CompoundNode::initialize (const InterfaceElement& element, GenContext& context)
2329{
2430 ShaderNodeImpl::initialize (element, context);
@@ -54,7 +60,7 @@ void CompoundNode::createVariables(const ShaderNode&, GenContext& context, Shade
5460 }
5561}
5662
57- void CompoundNode::emitFunctionDefinition (const ShaderNode&, GenContext& context, ShaderStage& stage) const
63+ void CompoundNode::emitFunctionDefinition (const ShaderNode& node , GenContext& context, ShaderStage& stage) const
5864{
5965 DEFINE_SHADER_STAGE (stage, Stage::PIXEL )
6066 {
@@ -66,9 +72,14 @@ void CompoundNode::emitFunctionDefinition(const ShaderNode&, GenContext& context
6672
6773 // Begin function signature.
6874 shadergen.emitLineBegin (stage);
69- shadergen.emitString (" void " + _functionName + + " (" , stage);
75+ shadergen.emitString (" void " + _functionName + " (" , stage);
7076
71- string delim = " " ;
77+ if (context.getShaderGenerator ().nodeNeedsClosureData (node))
78+ {
79+ shadergen.emitString (HW ::CLOSURE_DATA_TYPE + " " + HW ::CLOSURE_DATA_ARG + " , " , stage);
80+ }
81+
82+ string delim;
7283
7384 // Add all inputs
7485 for (ShaderGraphInputSocket* inputSocket : _rootGraph->getInputSockets ())
@@ -90,7 +101,32 @@ void CompoundNode::emitFunctionDefinition(const ShaderNode&, GenContext& context
90101
91102 // Begin function body.
92103 shadergen.emitFunctionBodyBegin (*_rootGraph, context, stage);
93- shadergen.emitFunctionCalls (*_rootGraph, context, stage);
104+
105+ if (nodeOutputIsClosure (node))
106+ {
107+ // Emit all texturing nodes. These are inputs to the
108+ // closure nodes and need to be emitted first.
109+ shadergen.emitFunctionCalls (*_rootGraph, context, stage, ShaderNode::Classification::TEXTURE );
110+
111+ // Emit function calls for internal closures nodes connected to the graph sockets.
112+ // These will in turn emit function calls for any dependent closure nodes upstream.
113+ for (ShaderGraphOutputSocket* outputSocket : _rootGraph->getOutputSockets ())
114+ {
115+ if (outputSocket->getConnection ())
116+ {
117+ const ShaderNode* upstream = outputSocket->getConnection ()->getNode ();
118+ if (upstream->getParent () == _rootGraph.get () &&
119+ (upstream->hasClassification (ShaderNode::Classification::CLOSURE ) || upstream->hasClassification (ShaderNode::Classification::SHADER )))
120+ {
121+ shadergen.emitFunctionCall (*upstream, context, stage);
122+ }
123+ }
124+ }
125+ }
126+ else
127+ {
128+ shadergen.emitFunctionCalls (*_rootGraph, context, stage);
129+ }
94130
95131 // Emit final results
96132 for (ShaderGraphOutputSocket* outputSocket : _rootGraph->getOutputSockets ())
@@ -116,14 +152,26 @@ void CompoundNode::emitFunctionCall(const ShaderNode& node, GenContext& context,
116152
117153 DEFINE_SHADER_STAGE (stage, Stage::PIXEL )
118154 {
155+ if (nodeOutputIsClosure (node))
156+ {
157+ // Emit calls for any closure dependencies upstream from this nodedef
158+ shadergen.emitDependentFunctionCalls (node, context, stage, ShaderNode::Classification::CLOSURE );
159+ }
160+
119161 // Declare the output variables.
120162 emitOutputVariables (node, context, stage);
121163
122164 // Begin function call.
123165 shadergen.emitLineBegin (stage);
124166 shadergen.emitString (_functionName + " (" , stage);
125167
126- string delim = " " ;
168+ // Check if we have a closure context to modify the function call.
169+ if (context.getShaderGenerator ().nodeNeedsClosureData (node))
170+ {
171+ shadergen.emitString (HW ::CLOSURE_DATA_ARG + " , " , stage);
172+ }
173+
174+ string delim;
127175
128176 // Emit inputs.
129177 for (ShaderInput* input : node.getInputs ())
0 commit comments