1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Test Executor
3*35238bceSAndroid Build Coastguard Worker * ------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Extract shader programs from log.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "xeTestLogParser.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "xeTestResultParser.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "deFilePath.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deString.h"
29*35238bceSAndroid Build Coastguard Worker
30*35238bceSAndroid Build Coastguard Worker #include <vector>
31*35238bceSAndroid Build Coastguard Worker #include <string>
32*35238bceSAndroid Build Coastguard Worker #include <cstdio>
33*35238bceSAndroid Build Coastguard Worker #include <cstdlib>
34*35238bceSAndroid Build Coastguard Worker #include <fstream>
35*35238bceSAndroid Build Coastguard Worker #include <iostream>
36*35238bceSAndroid Build Coastguard Worker #include <stdexcept>
37*35238bceSAndroid Build Coastguard Worker
38*35238bceSAndroid Build Coastguard Worker using std::map;
39*35238bceSAndroid Build Coastguard Worker using std::set;
40*35238bceSAndroid Build Coastguard Worker using std::string;
41*35238bceSAndroid Build Coastguard Worker using std::vector;
42*35238bceSAndroid Build Coastguard Worker
43*35238bceSAndroid Build Coastguard Worker struct CommandLine
44*35238bceSAndroid Build Coastguard Worker {
CommandLineCommandLine45*35238bceSAndroid Build Coastguard Worker CommandLine(void)
46*35238bceSAndroid Build Coastguard Worker {
47*35238bceSAndroid Build Coastguard Worker }
48*35238bceSAndroid Build Coastguard Worker
49*35238bceSAndroid Build Coastguard Worker string filename;
50*35238bceSAndroid Build Coastguard Worker string dstPath;
51*35238bceSAndroid Build Coastguard Worker };
52*35238bceSAndroid Build Coastguard Worker
getShaderTypeSuffix(const xe::ri::Shader::ShaderType shaderType)53*35238bceSAndroid Build Coastguard Worker static const char *getShaderTypeSuffix(const xe::ri::Shader::ShaderType shaderType)
54*35238bceSAndroid Build Coastguard Worker {
55*35238bceSAndroid Build Coastguard Worker switch (shaderType)
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_VERTEX:
58*35238bceSAndroid Build Coastguard Worker return "vert";
59*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_FRAGMENT:
60*35238bceSAndroid Build Coastguard Worker return "frag";
61*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_GEOMETRY:
62*35238bceSAndroid Build Coastguard Worker return "geom";
63*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_TESS_CONTROL:
64*35238bceSAndroid Build Coastguard Worker return "tesc";
65*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_TESS_EVALUATION:
66*35238bceSAndroid Build Coastguard Worker return "tese";
67*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_COMPUTE:
68*35238bceSAndroid Build Coastguard Worker return "comp";
69*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_RAYGEN:
70*35238bceSAndroid Build Coastguard Worker return "rgen";
71*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_ANY_HIT:
72*35238bceSAndroid Build Coastguard Worker return "ahit";
73*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_CLOSEST_HIT:
74*35238bceSAndroid Build Coastguard Worker return "chit";
75*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_MISS:
76*35238bceSAndroid Build Coastguard Worker return "miss";
77*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_INTERSECTION:
78*35238bceSAndroid Build Coastguard Worker return "sect";
79*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_CALLABLE:
80*35238bceSAndroid Build Coastguard Worker return "call";
81*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_TASK:
82*35238bceSAndroid Build Coastguard Worker return "task";
83*35238bceSAndroid Build Coastguard Worker case xe::ri::Shader::SHADERTYPE_MESH:
84*35238bceSAndroid Build Coastguard Worker return "mesh";
85*35238bceSAndroid Build Coastguard Worker
86*35238bceSAndroid Build Coastguard Worker default:
87*35238bceSAndroid Build Coastguard Worker throw xe::Error("Invalid shader type");
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker
writeShaderProgram(const CommandLine & cmdLine,const std::string & casePath,const xe::ri::ShaderProgram & shaderProgram,int programNdx)91*35238bceSAndroid Build Coastguard Worker static void writeShaderProgram(const CommandLine &cmdLine, const std::string &casePath,
92*35238bceSAndroid Build Coastguard Worker const xe::ri::ShaderProgram &shaderProgram, int programNdx)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker const string basePath =
95*35238bceSAndroid Build Coastguard Worker string(de::FilePath::join(cmdLine.dstPath, casePath).getPath()) + "." + de::toString(programNdx);
96*35238bceSAndroid Build Coastguard Worker
97*35238bceSAndroid Build Coastguard Worker for (int shaderNdx = 0; shaderNdx < shaderProgram.shaders.getNumItems(); shaderNdx++)
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker const xe::ri::Shader &shader = dynamic_cast<const xe::ri::Shader &>(shaderProgram.shaders.getItem(shaderNdx));
100*35238bceSAndroid Build Coastguard Worker const string shaderPath = basePath + "." + getShaderTypeSuffix(shader.shaderType);
101*35238bceSAndroid Build Coastguard Worker
102*35238bceSAndroid Build Coastguard Worker if (de::FilePath(shaderPath).exists())
103*35238bceSAndroid Build Coastguard Worker throw xe::Error("File '" + shaderPath + "' exists already");
104*35238bceSAndroid Build Coastguard Worker
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker std::ofstream out(shaderPath.c_str(), std::ifstream::binary | std::ifstream::out);
107*35238bceSAndroid Build Coastguard Worker
108*35238bceSAndroid Build Coastguard Worker if (!out.good())
109*35238bceSAndroid Build Coastguard Worker throw xe::Error("Failed to open '" + shaderPath + "'");
110*35238bceSAndroid Build Coastguard Worker
111*35238bceSAndroid Build Coastguard Worker out.write(shader.source.source.c_str(), shader.source.source.size());
112*35238bceSAndroid Build Coastguard Worker }
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker }
115*35238bceSAndroid Build Coastguard Worker
116*35238bceSAndroid Build Coastguard Worker struct StackEntry
117*35238bceSAndroid Build Coastguard Worker {
118*35238bceSAndroid Build Coastguard Worker const xe::ri::List *list;
119*35238bceSAndroid Build Coastguard Worker int curNdx;
120*35238bceSAndroid Build Coastguard Worker
StackEntryStackEntry121*35238bceSAndroid Build Coastguard Worker explicit StackEntry(const xe::ri::List *list_) : list(list_), curNdx(0)
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker }
124*35238bceSAndroid Build Coastguard Worker };
125*35238bceSAndroid Build Coastguard Worker
extractShaderPrograms(const CommandLine & cmdLine,const std::string & casePath,const xe::TestCaseResult & result)126*35238bceSAndroid Build Coastguard Worker static void extractShaderPrograms(const CommandLine &cmdLine, const std::string &casePath,
127*35238bceSAndroid Build Coastguard Worker const xe::TestCaseResult &result)
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker vector<StackEntry> itemListStack;
130*35238bceSAndroid Build Coastguard Worker int programNdx = 0;
131*35238bceSAndroid Build Coastguard Worker
132*35238bceSAndroid Build Coastguard Worker itemListStack.push_back(StackEntry(&result.resultItems));
133*35238bceSAndroid Build Coastguard Worker
134*35238bceSAndroid Build Coastguard Worker while (!itemListStack.empty())
135*35238bceSAndroid Build Coastguard Worker {
136*35238bceSAndroid Build Coastguard Worker StackEntry &curEntry = itemListStack.back();
137*35238bceSAndroid Build Coastguard Worker
138*35238bceSAndroid Build Coastguard Worker if (curEntry.curNdx < curEntry.list->getNumItems())
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker const xe::ri::Item &curItem = curEntry.list->getItem(curEntry.curNdx);
141*35238bceSAndroid Build Coastguard Worker curEntry.curNdx += 1;
142*35238bceSAndroid Build Coastguard Worker
143*35238bceSAndroid Build Coastguard Worker if (curItem.getType() == xe::ri::TYPE_SHADERPROGRAM)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker writeShaderProgram(cmdLine, casePath, static_cast<const xe::ri::ShaderProgram &>(curItem), programNdx);
146*35238bceSAndroid Build Coastguard Worker programNdx += 1;
147*35238bceSAndroid Build Coastguard Worker }
148*35238bceSAndroid Build Coastguard Worker else if (curItem.getType() == xe::ri::TYPE_SECTION)
149*35238bceSAndroid Build Coastguard Worker itemListStack.push_back(StackEntry(&static_cast<const xe::ri::Section &>(curItem).items));
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker else
152*35238bceSAndroid Build Coastguard Worker itemListStack.pop_back();
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker
155*35238bceSAndroid Build Coastguard Worker if (programNdx == 0)
156*35238bceSAndroid Build Coastguard Worker std::cout << "WARNING: no shader programs found in '" << casePath << "'\n";
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker
159*35238bceSAndroid Build Coastguard Worker class ShaderProgramExtractHandler : public xe::TestLogHandler
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker public:
ShaderProgramExtractHandler(const CommandLine & cmdLine)162*35238bceSAndroid Build Coastguard Worker ShaderProgramExtractHandler(const CommandLine &cmdLine) : m_cmdLine(cmdLine)
163*35238bceSAndroid Build Coastguard Worker {
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker
setSessionInfo(const xe::SessionInfo &)166*35238bceSAndroid Build Coastguard Worker void setSessionInfo(const xe::SessionInfo &)
167*35238bceSAndroid Build Coastguard Worker {
168*35238bceSAndroid Build Coastguard Worker // Ignored.
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker
startTestCaseResult(const char * casePath)171*35238bceSAndroid Build Coastguard Worker xe::TestCaseResultPtr startTestCaseResult(const char *casePath)
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker
testCaseResultUpdated(const xe::TestCaseResultPtr &)176*35238bceSAndroid Build Coastguard Worker void testCaseResultUpdated(const xe::TestCaseResultPtr &)
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker // Ignored.
179*35238bceSAndroid Build Coastguard Worker }
180*35238bceSAndroid Build Coastguard Worker
testCaseResultComplete(const xe::TestCaseResultPtr & caseData)181*35238bceSAndroid Build Coastguard Worker void testCaseResultComplete(const xe::TestCaseResultPtr &caseData)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker if (caseData->getDataSize() > 0)
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker xe::TestCaseResult fullResult;
186*35238bceSAndroid Build Coastguard Worker xe::TestResultParser::ParseResult parseResult;
187*35238bceSAndroid Build Coastguard Worker
188*35238bceSAndroid Build Coastguard Worker m_testResultParser.init(&fullResult);
189*35238bceSAndroid Build Coastguard Worker parseResult = m_testResultParser.parse(caseData->getData(), caseData->getDataSize());
190*35238bceSAndroid Build Coastguard Worker DE_UNREF(parseResult);
191*35238bceSAndroid Build Coastguard Worker
192*35238bceSAndroid Build Coastguard Worker extractShaderPrograms(m_cmdLine, caseData->getTestCasePath(), fullResult);
193*35238bceSAndroid Build Coastguard Worker }
194*35238bceSAndroid Build Coastguard Worker }
195*35238bceSAndroid Build Coastguard Worker
196*35238bceSAndroid Build Coastguard Worker private:
197*35238bceSAndroid Build Coastguard Worker const CommandLine &m_cmdLine;
198*35238bceSAndroid Build Coastguard Worker xe::TestResultParser m_testResultParser;
199*35238bceSAndroid Build Coastguard Worker };
200*35238bceSAndroid Build Coastguard Worker
extractShaderProgramsFromLogFile(const CommandLine & cmdLine)201*35238bceSAndroid Build Coastguard Worker static void extractShaderProgramsFromLogFile(const CommandLine &cmdLine)
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker std::ifstream in(cmdLine.filename.c_str(), std::ifstream::binary | std::ifstream::in);
204*35238bceSAndroid Build Coastguard Worker ShaderProgramExtractHandler resultHandler(cmdLine);
205*35238bceSAndroid Build Coastguard Worker xe::TestLogParser parser(&resultHandler);
206*35238bceSAndroid Build Coastguard Worker uint8_t buf[1024];
207*35238bceSAndroid Build Coastguard Worker int numRead = 0;
208*35238bceSAndroid Build Coastguard Worker
209*35238bceSAndroid Build Coastguard Worker if (!in.good())
210*35238bceSAndroid Build Coastguard Worker throw std::runtime_error(string("Failed to open '") + cmdLine.filename + "'");
211*35238bceSAndroid Build Coastguard Worker
212*35238bceSAndroid Build Coastguard Worker for (;;)
213*35238bceSAndroid Build Coastguard Worker {
214*35238bceSAndroid Build Coastguard Worker in.read((char *)&buf[0], DE_LENGTH_OF_ARRAY(buf));
215*35238bceSAndroid Build Coastguard Worker numRead = (int)in.gcount();
216*35238bceSAndroid Build Coastguard Worker
217*35238bceSAndroid Build Coastguard Worker if (numRead <= 0)
218*35238bceSAndroid Build Coastguard Worker break;
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker parser.parse(&buf[0], numRead);
221*35238bceSAndroid Build Coastguard Worker }
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker in.close();
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker
printHelp(const char * binName)226*35238bceSAndroid Build Coastguard Worker static void printHelp(const char *binName)
227*35238bceSAndroid Build Coastguard Worker {
228*35238bceSAndroid Build Coastguard Worker printf("%s: [filename] [dst path (optional)]\n", binName);
229*35238bceSAndroid Build Coastguard Worker }
230*35238bceSAndroid Build Coastguard Worker
parseCommandLine(CommandLine & cmdLine,int argc,const char * const * argv)231*35238bceSAndroid Build Coastguard Worker static bool parseCommandLine(CommandLine &cmdLine, int argc, const char *const *argv)
232*35238bceSAndroid Build Coastguard Worker {
233*35238bceSAndroid Build Coastguard Worker for (int argNdx = 1; argNdx < argc; argNdx++)
234*35238bceSAndroid Build Coastguard Worker {
235*35238bceSAndroid Build Coastguard Worker const char *arg = argv[argNdx];
236*35238bceSAndroid Build Coastguard Worker
237*35238bceSAndroid Build Coastguard Worker if (!deStringBeginsWith(arg, "--"))
238*35238bceSAndroid Build Coastguard Worker {
239*35238bceSAndroid Build Coastguard Worker if (cmdLine.filename.empty())
240*35238bceSAndroid Build Coastguard Worker cmdLine.filename = arg;
241*35238bceSAndroid Build Coastguard Worker else if (cmdLine.dstPath.empty())
242*35238bceSAndroid Build Coastguard Worker cmdLine.dstPath = arg;
243*35238bceSAndroid Build Coastguard Worker else
244*35238bceSAndroid Build Coastguard Worker return false;
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker else
247*35238bceSAndroid Build Coastguard Worker return false;
248*35238bceSAndroid Build Coastguard Worker }
249*35238bceSAndroid Build Coastguard Worker
250*35238bceSAndroid Build Coastguard Worker if (cmdLine.filename.empty())
251*35238bceSAndroid Build Coastguard Worker return false;
252*35238bceSAndroid Build Coastguard Worker
253*35238bceSAndroid Build Coastguard Worker return true;
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker
main(int argc,const char * const * argv)256*35238bceSAndroid Build Coastguard Worker int main(int argc, const char *const *argv)
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker try
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker CommandLine cmdLine;
261*35238bceSAndroid Build Coastguard Worker
262*35238bceSAndroid Build Coastguard Worker if (!parseCommandLine(cmdLine, argc, argv))
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker printHelp(argv[0]);
265*35238bceSAndroid Build Coastguard Worker return -1;
266*35238bceSAndroid Build Coastguard Worker }
267*35238bceSAndroid Build Coastguard Worker
268*35238bceSAndroid Build Coastguard Worker extractShaderProgramsFromLogFile(cmdLine);
269*35238bceSAndroid Build Coastguard Worker }
270*35238bceSAndroid Build Coastguard Worker catch (const std::exception &e)
271*35238bceSAndroid Build Coastguard Worker {
272*35238bceSAndroid Build Coastguard Worker printf("FATAL ERROR: %s\n", e.what());
273*35238bceSAndroid Build Coastguard Worker return -1;
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker
276*35238bceSAndroid Build Coastguard Worker return 0;
277*35238bceSAndroid Build Coastguard Worker }
278