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