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 #include "vktTestCaseUtil.hpp"
25 #include "tcuResource.hpp"
26
27
28 namespace vkt
29 {
30 namespace cts_amber
31 {
32
33 class AmberIndexFileParser
34 {
35 std::string m_str;
36 size_t m_idx;
37 size_t m_len;
38 static const int m_fieldLen = 256;
39 char m_scratch[m_fieldLen];
40 char m_filenameField[m_fieldLen];
41 char m_testnameField[m_fieldLen];
42 char m_descField[m_fieldLen];
43
isWhitespace(char c)44 bool isWhitespace (char c)
45 {
46 if (c == ' ' ||
47 c == '\t' ||
48 c == '\r' ||
49 c == '\n')
50 {
51 return true;
52 }
53 return false;
54 }
55
skipWhitespace(void)56 void skipWhitespace (void)
57 {
58 while (m_idx < m_len && isWhitespace(m_str[m_idx]))
59 m_idx++;
60 }
61
skipCommentLine(void)62 bool skipCommentLine (void)
63 {
64 skipWhitespace();
65 if (m_str[m_idx] == '#')
66 {
67 while (m_idx < m_len && m_str[m_idx] != '\n')
68 m_idx++;
69 return true;
70 }
71 return false;
72 }
73
accept(char c)74 void accept (char c)
75 {
76 if (m_str[m_idx] == c)
77 m_idx++;
78 }
79
expect(char c)80 void expect (char c)
81 {
82 if (m_idx >= m_len || m_str[m_idx] != c)
83 TCU_THROW(ResourceError, "Error parsing amber index file");
84
85 m_idx++;
86 }
87
captureString(char * field)88 void captureString (char* field)
89 {
90 int i = 0;
91
92 while (m_idx < m_len && i < m_fieldLen && m_str[m_idx] != '"')
93 {
94 field[i] = m_str[m_idx];
95 i++;
96 m_idx++;
97 }
98
99 field[i] = 0;
100 m_idx++;
101 }
102
103
104 public:
AmberIndexFileParser(tcu::TestContext & testCtx,const char * filename,const char * category)105 AmberIndexFileParser (tcu::TestContext& testCtx, const char* filename, const char* category)
106 {
107 std::string indexFilename("vulkan/amber/");
108 indexFilename.append(category);
109 indexFilename.append("/");
110 indexFilename.append(filename);
111
112 m_str = ShaderSourceProvider::getSource(testCtx.getArchive(), indexFilename.c_str());
113 m_len = m_str.length();
114 m_idx = 0;
115 }
116
~AmberIndexFileParser(void)117 ~AmberIndexFileParser (void) { }
118
parse(const char * category,tcu::TestContext & testCtx)119 AmberTestCase* parse (const char* category, tcu::TestContext& testCtx)
120 {
121 // Format:
122 // {"filename","test name","description"[,requirement[,requirement[,requirement..]]]}[,]
123 // Things inside [] are optional. Whitespace is allowed everywhere.
124 //
125 // Comments are allowed starting with "#" character.
126 //
127 // For example, test without requirements might be:
128 // {"testname.amber","test name","test description"},
129
130 while (skipCommentLine());
131
132 if (m_idx < m_len)
133 {
134 skipWhitespace();
135 expect('{');
136 skipWhitespace();
137 expect('"');
138 captureString(m_filenameField);
139 skipWhitespace();
140 expect(',');
141 skipWhitespace();
142 expect('"');
143 captureString(m_testnameField);
144 skipWhitespace();
145 expect(',');
146 skipWhitespace();
147 expect('"');
148 captureString(m_descField);
149 skipWhitespace();
150
151 std::string testFilename("vulkan/amber/");
152 testFilename.append(category);
153 testFilename.append("/");
154 testFilename.append(m_filenameField);
155 AmberTestCase *testCase = new AmberTestCase(testCtx, m_testnameField, m_descField, testFilename);
156
157 while (m_idx < m_len && m_str[m_idx] == ',')
158 {
159 accept(',');
160 skipWhitespace();
161 expect('"');
162 captureString(m_scratch);
163 skipWhitespace();
164 testCase->addRequirement(m_scratch);
165 }
166
167 expect('}');
168 skipWhitespace();
169 accept(',');
170 skipWhitespace();
171 return testCase;
172 }
173 return 0;
174 }
175 };
176
createAmberTestsFromIndexFile(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,const std::string filename,const char * category)177 void createAmberTestsFromIndexFile (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, const std::string filename, const char* category)
178 {
179 AmberTestCase* testCase = 0;
180 AmberIndexFileParser parser(testCtx, filename.c_str(), category);
181
182 do
183 {
184 testCase = parser.parse(category, testCtx);
185 if (testCase)
186 {
187 group->addChild(testCase);
188 }
189 } while (testCase);
190 }
191
createAmberTestCase(tcu::TestContext & testCtx,const char * name,const char * description,const char * category,const std::string & filename,const std::vector<std::string> requirements,const std::vector<vk::VkImageCreateInfo> imageRequirements,const std::vector<BufferRequirement> bufferRequirements)192 AmberTestCase* createAmberTestCase (tcu::TestContext& testCtx,
193 const char* name,
194 const char* description,
195 const char* category,
196 const std::string& filename,
197 const std::vector<std::string> requirements,
198 const std::vector<vk::VkImageCreateInfo> imageRequirements,
199 const std::vector<BufferRequirement> bufferRequirements)
200
201 {
202 // shader_test files are saved in <path>/external/vulkancts/data/vulkan/amber/<categoryname>/
203 std::string readFilename("vulkan/amber/");
204 readFilename.append(category);
205 readFilename.append("/");
206 readFilename.append(filename);
207
208 AmberTestCase *testCase = new AmberTestCase(testCtx, name, description, readFilename);
209
210 for (auto req : requirements)
211 testCase->addRequirement(req);
212
213 for (auto req : imageRequirements)
214 testCase->addImageRequirement(req);
215
216 for (auto req : bufferRequirements)
217 testCase->addBufferRequirement(req);
218
219 return testCase;
220 }
221
222 } // cts_amber
223 } // vkt
224