Add index file for amber tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / amber / vktAmberTestCaseUtil.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Google LLC
6  * Copyright (c) 2019 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*--------------------------------------------------------------------*/
21
22 #include "vktAmberTestCase.hpp"
23 #include "vktTestGroupUtil.hpp"
24
25 namespace vkt
26 {
27 namespace cts_amber
28 {
29
30 class AmberIndexFileParser
31 {
32         char*                           m_buf;
33         size_t                          m_idx;
34         size_t                          m_len;
35         static const int        m_fieldLen = 256;
36         char                            m_scratch[m_fieldLen];
37         char                            m_filenameField[m_fieldLen];
38         char                            m_testnameField[m_fieldLen];
39         char                            m_descField[m_fieldLen];
40
41         bool isWhitespace (char c)
42         {
43                 if (c == ' '  ||
44                         c == '\t' ||
45                         c == '\r' ||
46                         c == '\n')
47                 {
48                         return true;
49                 }
50                 return false;
51         }
52
53         void skipWhitespace (void)
54         {
55                 while (m_idx < m_len && isWhitespace(m_buf[m_idx]))
56                         m_idx++;
57         }
58
59         void accept (char c)
60         {
61                 if (m_buf[m_idx] == c)
62                         m_idx++;
63         }
64
65         void expect (char c)
66         {
67                 if (m_buf[m_idx] != c || m_idx >= m_len)
68                         TCU_THROW(ResourceError, "Error parsing amber index file");
69
70                 m_idx++;
71         }
72
73         void captureString (char* field)
74         {
75                 int i = 0;
76
77                 while (m_idx < m_len && i < m_fieldLen && m_buf[m_idx] != '"')
78                 {
79                         field[i] = m_buf[m_idx];
80                         i++;
81                         m_idx++;
82                 }
83
84                 field[i] = 0;
85                 m_idx++;
86         }
87
88         char* loadFile (const char* filename, size_t& len)
89         {
90                 FILE* f = fopen(filename, "rb");
91
92                 if (f == 0)
93                 {
94                         std::string error("Unable to open index file ");
95                         error.append(filename);
96                         TCU_THROW(ResourceError, error.c_str());
97                 }
98
99                 fseek(f, 0, SEEK_END);
100                 len = ftell(f);
101                 fseek(f, 0, SEEK_SET);
102                 char* buf = new char[len + 1];
103
104                 if (fread(buf, 1, len, f) != len)
105                 {
106                         delete[] buf;
107                         fclose(f);
108                         std::string error("File i/o error reading index file ");
109                         error.append(filename);
110                         TCU_THROW(ResourceError, error.c_str());
111                 }
112
113                 buf[len] = 0;
114                 fclose(f);
115                 return buf;
116         }
117
118 public:
119         AmberIndexFileParser (const char* filename, const char* category)
120         {
121                 std::string     indexFilename("vulkan/amber/");
122                 indexFilename.append(category);
123                 indexFilename.append("/");
124                 indexFilename.append(filename);
125
126                 m_buf = loadFile(indexFilename.c_str(), m_len);
127                 m_idx = 0;
128         }
129
130         ~AmberIndexFileParser (void)
131         {
132                 delete[] m_buf;
133         }
134
135         AmberTestCase* parse (const char* category, tcu::TestContext& testCtx)
136         {
137                 // Format:
138                 // {"filename","test name","description"[,requirement[,requirement[,requirement..]]]}[,]
139                 // Things inside [] are optional. Whitespace is allowed everywhere.
140                 //
141                 // For example, test without requirements might be:
142                 // {"testname.amber","test name","test description"},
143
144                 if (m_idx < m_len)
145                 {
146                         skipWhitespace();
147                         expect('{');
148                         skipWhitespace();
149                         expect('"');
150                         captureString(m_filenameField);
151                         skipWhitespace();
152                         expect(',');
153                         skipWhitespace();
154                         expect('"');
155                         captureString(m_testnameField);
156                         skipWhitespace();
157                         expect(',');
158                         skipWhitespace();
159                         expect('"');
160                         captureString(m_descField);
161                         skipWhitespace();
162
163                         std::string testFilename("vulkan/amber/");
164                         testFilename.append(category);
165                         testFilename.append("/");
166                         testFilename.append(m_filenameField);
167                         AmberTestCase *testCase = new AmberTestCase(testCtx, m_testnameField, m_descField, testFilename);
168
169                         while (m_idx < m_len && m_buf[m_idx] == ',')
170                         {
171                                 accept(',');
172                                 skipWhitespace();
173                                 expect('"');
174                                 captureString(m_scratch);
175                                 skipWhitespace();
176                                 testCase->addRequirement(m_scratch);
177                         }
178
179                         expect('}');
180                         skipWhitespace();
181                         accept(',');
182                         skipWhitespace();
183                         return testCase;
184                 }
185                 return 0;
186         }
187 };
188
189 void createAmberTestsFromIndexFile (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string filename, const char* category)
190 {
191         AmberTestCase*                  testCase = 0;
192         AmberIndexFileParser    parser(filename.c_str(), category);
193
194         do
195         {
196                 testCase = parser.parse(category, testCtx);
197                 if (testCase)
198                 {
199                         group->addChild(testCase);
200                 }
201         } while (testCase);
202 }
203
204 AmberTestCase* createAmberTestCase (tcu::TestContext&                           testCtx,
205                                                                         const char*                                             name,
206                                                                         const char*                                             description,
207                                                                         const char*                                             category,
208                                                                         const std::string&                              filename,
209                                                                         const std::vector<std::string>  requirements)
210 {
211         // shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
212         std::string readFilename("vulkan/amber/");
213         readFilename.append(category);
214         readFilename.append("/");
215         readFilename.append(filename);
216
217         AmberTestCase *testCase = new AmberTestCase(testCtx, name, description, readFilename);
218
219         for (auto req : requirements)
220                 testCase->addRequirement(req);
221
222         return testCase;
223 }
224
225 } // cts_amber
226 } // vkt