| 189 | } |
| 190 | |
| 191 | ref<const ProgramKernels> ProgramVersion::getKernels(Device* pDevice, ProgramVars const* pVars) const |
| 192 | { |
| 193 | // We need are going to look up or create specialized kernels |
| 194 | // based on how parameters are bound in `pVars`. |
| 195 | // |
| 196 | // To do this we need to identify those parameters that are relevant |
| 197 | // to specialization, and what argument type/value is bound to |
| 198 | // those parameters. |
| 199 | // |
| 200 | std::string specializationKey; |
| 201 | |
| 202 | ParameterBlock::SpecializationArgs specializationArgs; |
| 203 | if (pVars) |
| 204 | { |
| 205 | pVars->collectSpecializationArgs(specializationArgs); |
| 206 | } |
| 207 | |
| 208 | bool first = true; |
| 209 | for (auto specializationArg : specializationArgs) |
| 210 | { |
| 211 | if (!first) |
| 212 | specializationKey += ","; |
| 213 | specializationKey += std::string(specializationArg.type->getName()); |
| 214 | first = false; |
| 215 | } |
| 216 | |
| 217 | auto foundKernels = mpKernels.find(specializationKey); |
| 218 | if (foundKernels != mpKernels.end()) |
| 219 | { |
| 220 | return foundKernels->second; |
| 221 | } |
| 222 | |
| 223 | FALCOR_ASSERT(mpProgram); |
| 224 | |
| 225 | // Loop so that user can trigger recompilation on error |
| 226 | for (;;) |
| 227 | { |
| 228 | std::string log; |
| 229 | auto pKernels = pDevice->getProgramManager()->createProgramKernels(*mpProgram, *this, *pVars, log); |
| 230 | if (pKernels) |
| 231 | { |
| 232 | // Success |
| 233 | |
| 234 | if (!log.empty()) |
| 235 | { |
| 236 | logWarning("Warnings in program:\n{}\n{}", getName(), log); |
| 237 | } |
| 238 | |
| 239 | mpKernels[specializationKey] = pKernels; |
| 240 | return pKernels; |
| 241 | } |
| 242 | else |
| 243 | { |
| 244 | // Failure |
| 245 | std::string msg = fmt::format("Failed to link program:\n{}\n\n{}", getName(), log); |
| 246 | bool showMessageBox = is_set(getErrorDiagnosticFlags(), ErrorDiagnosticFlags::ShowMessageBoxOnError); |
| 247 | if (showMessageBox && reportErrorAndAllowRetry(msg)) |
| 248 | continue; |