| 173 | } |
| 174 | |
| 175 | bool RenderGraphCompiler::insertAutoPasses() |
| 176 | { |
| 177 | bool addedPasses = false; |
| 178 | for (size_t i = 0; i < mExecutionList.size(); i++) |
| 179 | { |
| 180 | const RenderPassReflection& passReflection = mExecutionList[i].reflector; |
| 181 | |
| 182 | // Check for opportunities to automatically resolve MSAA |
| 183 | // - Only take explicitly specified MS output |
| 184 | for (uint32_t f = 0; f < passReflection.getFieldCount(); f++) |
| 185 | { |
| 186 | // Iterate over output fields |
| 187 | auto& srcField = *passReflection.getField(f); |
| 188 | if (is_set(srcField.getVisibility(), RenderPassReflection::Field::Visibility::Output) == false) |
| 189 | continue; |
| 190 | |
| 191 | const std::string& srcPassName = mExecutionList[i].name; |
| 192 | // Gather src field name, and every input it is connected to |
| 193 | std::string srcFieldName = srcPassName + '.' + srcField.getName(); |
| 194 | std::vector<std::string> dstFieldNames; |
| 195 | |
| 196 | const DirectedGraph::Node* pNode = mGraph.mpGraph->getNode(mExecutionList[i].index); |
| 197 | for (uint32_t e = 0; e < pNode->getOutgoingEdgeCount(); e++) |
| 198 | { |
| 199 | uint32_t edgeIndex = pNode->getOutgoingEdge(e); |
| 200 | const auto& edgeData = mGraph.mEdgeData.at(edgeIndex); |
| 201 | |
| 202 | // For every output field, iterate over all edges extending from that field |
| 203 | if (srcField.getName() == edgeData.srcField) |
| 204 | { |
| 205 | const auto& pEdge = mGraph.mpGraph->getEdge(edgeIndex); |
| 206 | const std::string& dstPassName = mGraph.mNodeData.at(pEdge->getDestNode()).name; |
| 207 | |
| 208 | // If edge is connected to something that isn't executed, ignore |
| 209 | auto getPassReflection = [&](uint32_t index) -> std::optional<RenderPassReflection> |
| 210 | { |
| 211 | for (const auto& e : mExecutionList) |
| 212 | if (e.index == index) |
| 213 | return e.reflector; |
| 214 | return std::nullopt; |
| 215 | }; |
| 216 | |
| 217 | const auto& dstReflection = getPassReflection(pEdge->getDestNode()); |
| 218 | if (!dstReflection) |
| 219 | continue; |
| 220 | const auto& dstField = *dstReflection->getField(edgeData.dstField); |
| 221 | |
| 222 | FALCOR_ASSERT(srcField.isValid() && dstField.isValid()); |
| 223 | if (canAutoResolve(srcField, dstField)) |
| 224 | { |
| 225 | std::string dstFieldName = dstPassName + '.' + dstField.getName(); |
| 226 | dstFieldNames.push_back(dstFieldName); |
| 227 | } |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | // If there are connections to add MSAA Resolve |
| 232 | if (dstFieldNames.size() > 0) |
no test coverage detected