13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Test Executor 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------ 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Extract shader programs from log. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestLogParser.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xeTestResultParser.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deFilePath.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string> 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdio> 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <cstdlib> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <fstream> 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iostream> 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdexcept> 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map; 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct CommandLine 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommandLine (void) 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string filename; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string dstPath; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getShaderTypeSuffix (const xe::ri::Shader::ShaderType shaderType) 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (shaderType) 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_VERTEX: return "vert"; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_FRAGMENT: return "frag"; 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_GEOMETRY: return "geom"; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_TESS_CONTROL: return "tesc"; 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_TESS_EVALUATION: return "tese"; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case xe::ri::Shader::SHADERTYPE_COMPUTE: return "comp"; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw xe::Error("Invalid shader type"); 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeShaderProgram (const CommandLine& cmdLine, const std::string& casePath, const xe::ri::ShaderProgram& shaderProgram, int programNdx) 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string basePath = string(de::FilePath::join(cmdLine.dstPath, casePath).getPath()) + "." + de::toString(programNdx); 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < shaderProgram.shaders.getNumItems(); shaderNdx++) 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::ri::Shader& shader = dynamic_cast<const xe::ri::Shader&>(shaderProgram.shaders.getItem(shaderNdx)); 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string shaderPath = basePath + "." + getShaderTypeSuffix(shader.shaderType); 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::FilePath(shaderPath).exists()) 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw xe::Error("File '" + shaderPath + "' exists already"); 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ofstream out(shaderPath.c_str(), std::ifstream::binary|std::ifstream::out); 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!out.good()) 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw xe::Error("Failed to open '" + shaderPath + "'"); 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry out.write(shader.source.source.c_str(), shader.source.source.size()); 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct StackEntry 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::ri::List* list; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curNdx; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry explicit StackEntry (const xe::ri::List* list_) : list(list_), curNdx(0) {} 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void extractShaderPrograms (const CommandLine& cmdLine, const std::string& casePath, const xe::TestCaseResult& result) 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<StackEntry> itemListStack; 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int programNdx = 0; 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry itemListStack.push_back(StackEntry(&result.resultItems)); 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (!itemListStack.empty()) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StackEntry& curEntry = itemListStack.back(); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curEntry.curNdx < curEntry.list->getNumItems()) 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const xe::ri::Item& curItem = curEntry.list->getItem(curEntry.curNdx); 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curEntry.curNdx += 1; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curItem.getType() == xe::ri::TYPE_SHADERPROGRAM) 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeShaderProgram(cmdLine, casePath, static_cast<const xe::ri::ShaderProgram&>(curItem), programNdx); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry programNdx += 1; 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curItem.getType() == xe::ri::TYPE_SECTION) 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry itemListStack.push_back(StackEntry(&static_cast<const xe::ri::Section&>(curItem).items)); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry itemListStack.pop_back(); 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx == 0) 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::cout << "WARNING: no shader programs found in '" << casePath << "'\n"; 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderProgramExtractHandler : public xe::TestLogHandler 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderProgramExtractHandler (const CommandLine& cmdLine) 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_cmdLine(cmdLine) 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void setSessionInfo (const xe::SessionInfo&) 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ignored. 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResultPtr startTestCaseResult (const char* casePath) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath)); 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultUpdated (const xe::TestCaseResultPtr&) 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ignored. 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void testCaseResultComplete (const xe::TestCaseResultPtr& caseData) 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (caseData->getDataSize() > 0) 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestCaseResult fullResult; 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestResultParser::ParseResult parseResult; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testResultParser.init(&fullResult); 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parseResult = m_testResultParser.parse(caseData->getData(), caseData->getDataSize()); 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(parseResult); 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry extractShaderPrograms(m_cmdLine, caseData->getTestCasePath(), fullResult); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CommandLine& m_cmdLine; 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestResultParser m_testResultParser; 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void extractShaderProgramsFromLogFile (const CommandLine& cmdLine) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ifstream in (cmdLine.filename.c_str(), std::ifstream::binary|std::ifstream::in); 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderProgramExtractHandler resultHandler (cmdLine); 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry xe::TestLogParser parser (&resultHandler); 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8 buf [1024]; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRead = 0; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!in.good()) 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw std::runtime_error(string("Failed to open '") + cmdLine.filename + "'"); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry in.read((char*)&buf[0], DE_LENGTH_OF_ARRAY(buf)); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numRead = (int)in.gcount(); 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numRead <= 0) 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parser.parse(&buf[0], numRead); 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry in.close(); 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void printHelp (const char* binName) 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("%s: [filename] [dst path (optional)]\n", binName); 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int argNdx = 1; argNdx < argc; argNdx++) 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* arg = argv[argNdx]; 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!deStringBeginsWith(arg, "--")) 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmdLine.filename.empty()) 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine.filename = arg; 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (cmdLine.dstPath.empty()) 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmdLine.dstPath = arg; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmdLine.filename.empty()) 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint main (int argc, const char* const* argv) 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommandLine cmdLine; 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!parseCommandLine(cmdLine, argc, argv)) 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printHelp(argv[0]); 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry extractShaderProgramsFromLogFile(cmdLine); 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const std::exception& e) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry printf("FATAL ERROR: %s\n", e.what()); 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 251