xref: /aosp_15_r20/external/deqp/executor/tools/xeExtractShaderPrograms.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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