| … | … | @@ -162,7 +162,21 @@ String GpuCompiler::compile_batch( |
| 162 | 162 | // GraphExecutor refills it on every dispatch. See GlslEmitContext. |
| 163 | 163 | ctx.push_constants = true; |
| 164 | 164 | ctx.graph = p_graph; |
| 165 | | ctx.emitted_nodes = p_node_indices; |
| 165 | // ⛔ EMITTED, NOT MERELY LISTED, AND ONLY IF ALREADY WRITTEN. |
| 166 | // |
| 167 | // This was set to the whole batch up front, so param() would resolve a |
| 168 | // socket to `nX_sY` for a producer that had not emitted yet -- or had |
| 169 | // emitted NOTHING, because compile_glsl returned empty and the loop below |
| 170 | // skips it. The consumer then referenced a local that does not exist: |
| 171 | // |
| 172 | // ERROR: 0:46: 'n30_s0' : undeclared identifier |
| 173 | // ProcNodes: GPU pipeline creation failed for SetPosition |
| 174 | // |
| 175 | // The list is built as the loop goes, so a node can only name a producer |
| 176 | // that has ALREADY put its declaration in the body above it. Execution |
| 177 | // order is topological, so a real producer is always there first; anything |
| 178 | // missing falls back to the push constant, which is what it did before. |
| 179 | ctx.emitted_nodes.clear(); |
| 166 | 180 | |
| 167 | 181 | String main_body; |
| 168 | 182 | String preludes; |
| … | … | @@ -196,6 +210,7 @@ String GpuCompiler::compile_batch( |
| 196 | 210 | |
| 197 | 211 | main_body += " // Node " + itos(graph_idx) + ": " + node->get_node_title() + "\n"; |
| 198 | 212 | main_body += " " + glsl + "\n"; |
| 213 | ctx.emitted_nodes.push_back(graph_idx); |
| 199 | 214 | } |
| 200 | 215 | |
| 201 | 216 | String shader = get_shader_template(); |