16ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include "gles_conformance_tests.h" 26ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include "GTFMain.h" 36ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 46ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include <stdio.h> 56ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include <stdlib.h> 66ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include <vector> 76ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include <sstream> 86ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang#include <stdarg.h> 96ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 106ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langstatic ConformanceConfig kCurrentConfig = { 64, 64, EGL_DEFAULT_DISPLAY }; 116ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 126ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langvoid SetCurrentConfig(const ConformanceConfig& config) 136ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang{ 146ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang kCurrentConfig = config; 156ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang} 166ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 176ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langconst ConformanceConfig& GetCurrentConfig() 186ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang{ 196ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang return kCurrentConfig; 206ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang} 216ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 226ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langstatic std::vector<char> FormatArg(const char* fmt, ...) 236ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang{ 246ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang va_list vararg; 256ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang va_start(vararg, fmt); 266ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang int len = vsnprintf(NULL, 0, fmt, vararg); 276ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang va_end(vararg); 286ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 296ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> buf(len + 1); 306ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 316ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang va_start(vararg, fmt); 326ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang vsnprintf(buf.data(), buf.size(), fmt, vararg); 336ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang va_end(vararg); 346ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 356ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang return buf; 366ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang} 376ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 386ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langstatic std::string GetExecutableDirectory() 396ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang{ 406ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> executableFileBuf(MAX_PATH); 416ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang DWORD executablePathLen = GetModuleFileNameA(NULL, executableFileBuf.data(), executableFileBuf.size()); 426ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang if (executablePathLen == 0) 436ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang { 446ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang return false; 456ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang } 466ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 476ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::string executableLocation = executableFileBuf.data(); 486ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang size_t lastPathSepLoc = executableLocation.find_last_of("\\/"); 496ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang if (lastPathSepLoc != std::string::npos) 506ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang { 516ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang executableLocation = executableLocation.substr(0, lastPathSepLoc); 526ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang } 536ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang else 546ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang { 556ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang executableLocation = ""; 566ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang } 576ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 586ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang return executableLocation; 596ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang} 606ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 616ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Langvoid RunConformanceTest(const std::string &testPath, const ConformanceConfig& config) 626ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang{ 636ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char*> args; 646ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 656ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang // Empty first argument for the program name 666ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang args.push_back(""); 676ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 686ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> widthArg = FormatArg("-width=%u", config.width); 696ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang args.push_back(widthArg.data()); 706ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 716ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> heightArg = FormatArg("-height=%u", config.height); 726ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang args.push_back(heightArg.data()); 736ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 746ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> displayArg = FormatArg("-d=%u", config.displayType); 756ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang args.push_back(displayArg.data()); 766ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 776ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::vector<char> runArg = FormatArg("-run=%s/conformance_tests/%s", GetExecutableDirectory().c_str(), testPath.c_str()); 786ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang args.push_back(runArg.data()); 796ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 806ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang // Redirect cout 816ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::streambuf* oldCoutStreamBuf = std::cout.rdbuf(); 826ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::ostringstream strCout; 836ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::cout.rdbuf(strCout.rdbuf()); 846ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 856ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang if (GTFMain(args.size(), args.data()) != 0) 866ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang { 876ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang FAIL() << "GTFMain failed."; 886ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang } 896ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 906ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang // Restore old cout 916ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::cout.rdbuf(oldCoutStreamBuf); 926ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::string log = strCout.str(); 936ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 946ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang // Look for failures 956ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang size_t offset = 0; 966ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang std::string offsetSearchString = "failure = "; 976ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang while ((offset = log.find("failure = ", offset)) != std::string::npos) 986ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang { 996ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang offset += offsetSearchString.length(); 1006ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang 1016ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang size_t failureCount = atoll(log.c_str() + offset); 1026ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang EXPECT_EQ(0, failureCount) << log; 1036ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang } 1046ba49d9460a0071f1e95ba09a428addb9e3931b0Geoff Lang} 105