xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/amber/vktAmberTestCaseUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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