| 79 | } |
| 80 | |
| 81 | void RenderGraphCompiler::validateGraph() const |
| 82 | { |
| 83 | std::string err; |
| 84 | |
| 85 | for (const auto& p : mExecutionList) |
| 86 | { |
| 87 | // Make sure all the inputs are satisfied |
| 88 | for (uint32_t i = 0; i < p.reflector.getFieldCount(); i++) |
| 89 | { |
| 90 | const auto& f = *p.reflector.getField(i); |
| 91 | if (!is_set(f.getVisibility(), RenderPassReflection::Field::Visibility::Input)) |
| 92 | continue; |
| 93 | if (is_set(f.getFlags(), RenderPassReflection::Field::Flags::Optional)) |
| 94 | continue; |
| 95 | |
| 96 | const DirectedGraph::Node* pGraphNode = mGraph.mpGraph->getNode(p.index); |
| 97 | const std::string& name = f.getName(); |
| 98 | bool found = false; |
| 99 | for (uint32_t e = 0; e < pGraphNode->getIncomingEdgeCount(); e++) |
| 100 | { |
| 101 | const auto& edgeData = mGraph.mEdgeData.at(pGraphNode->getIncomingEdge(e)); |
| 102 | found = (edgeData.dstField == name); |
| 103 | if (found) |
| 104 | break; |
| 105 | } |
| 106 | std::string resName = p.name + '.' + name; |
| 107 | bool hasExternal = mDependencies.externalResources.find(resName) != mDependencies.externalResources.end(); |
| 108 | if (hasExternal && found) |
| 109 | err += "Input field '" + resName + "' has an incoming edge and an external resource bound. This is illegal"; |
| 110 | if (!hasExternal && !found) |
| 111 | err += "Input field '" + resName + "' is required but not satisfied\n"; |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | if (mGraph.getOutputCount() == 0) |
| 116 | err += "Graph must have at least one output.\n"; |
| 117 | |
| 118 | if (err.size()) |
| 119 | FALCOR_THROW(err); |
| 120 | } |
| 121 | |
| 122 | void RenderGraphCompiler::resolveExecutionOrder() |
| 123 | { |
no test coverage detected