1 #ifndef _VKTTESTCASEUTIL_HPP
2 #define _VKTTESTCASEUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
6 *
7 * Copyright (c) 2015 Google Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief TestCase utilities
24 *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "tcuResource.hpp"
28 #include "vktTestCase.hpp"
29
30 namespace vkt
31 {
32
33 class ShaderSourceProvider
34 {
35 public:
getSource(tcu::Archive & archive,const char * path)36 static std::string getSource(tcu::Archive &archive, const char *path)
37 {
38 de::UniquePtr<tcu::Resource> resource(archive.getResource(path));
39
40 std::vector<uint8_t> readBuffer(resource->getSize() + 1);
41 resource->read(&readBuffer[0], resource->getSize());
42 readBuffer[readBuffer.size() - 1] = 0;
43
44 return std::string(reinterpret_cast<const char *>(&readBuffer[0]));
45 }
46 };
47
48 template <typename Arg0>
49 struct NoPrograms1
50 {
initvkt::NoPrograms151 void init(vk::SourceCollections &, Arg0) const
52 {
53 }
54 };
55
56 template <typename Instance, typename Arg0, typename Programs = NoPrograms1<Arg0>>
57 class InstanceFactory1 : public TestCase
58 {
59 public:
InstanceFactory1(tcu::TestContext & testCtx,const std::string & name,const Arg0 & arg0)60 InstanceFactory1(tcu::TestContext &testCtx, const std::string &name, const Arg0 &arg0)
61 : TestCase(testCtx, name)
62 , m_progs()
63 , m_arg0(arg0)
64 {
65 }
66
InstanceFactory1(tcu::TestContext & testCtx,const std::string & name,const Programs & progs,const Arg0 & arg0)67 InstanceFactory1(tcu::TestContext &testCtx, const std::string &name, const Programs &progs, const Arg0 &arg0)
68 : TestCase(testCtx, name)
69 , m_progs(progs)
70 , m_arg0(arg0)
71 {
72 }
73
initPrograms(vk::SourceCollections & dst) const74 void initPrograms(vk::SourceCollections &dst) const
75 {
76 m_progs.init(dst, m_arg0);
77 }
createInstance(Context & context) const78 TestInstance *createInstance(Context &context) const
79 {
80 return new Instance(context, m_arg0);
81 }
checkSupport(Context &) const82 void checkSupport(Context &) const
83 {
84 }
85
86 private:
87 const Programs m_progs;
88 const Arg0 m_arg0;
89 };
90
91 template <typename Instance, typename Arg0, typename Support, typename Programs = NoPrograms1<Arg0>>
92 class InstanceFactory1WithSupport : public TestCase
93 {
94 public:
InstanceFactory1WithSupport(tcu::TestContext & testCtx,const std::string & name,const Arg0 & arg0,const Support & support)95 InstanceFactory1WithSupport(tcu::TestContext &testCtx, const std::string &name, const Arg0 &arg0,
96 const Support &support)
97 : TestCase(testCtx, name)
98 , m_progs()
99 , m_arg0(arg0)
100 , m_support(support)
101 {
102 }
103
InstanceFactory1WithSupport(tcu::TestContext & testCtx,const std::string & name,const Programs & progs,const Arg0 & arg0,const Support & support)104 InstanceFactory1WithSupport(tcu::TestContext &testCtx, const std::string &name, const Programs &progs,
105 const Arg0 &arg0, const Support &support)
106 : TestCase(testCtx, name)
107 , m_progs(progs)
108 , m_arg0(arg0)
109 , m_support(support)
110 {
111 }
112
initPrograms(vk::SourceCollections & dst) const113 void initPrograms(vk::SourceCollections &dst) const
114 {
115 m_progs.init(dst, m_arg0);
116 }
createInstance(Context & context) const117 TestInstance *createInstance(Context &context) const
118 {
119 return new Instance(context, m_arg0);
120 }
checkSupport(Context & context) const121 void checkSupport(Context &context) const
122 {
123 m_support.checkSupport(context);
124 }
125
126 private:
127 const Programs m_progs;
128 const Arg0 m_arg0;
129 const Support m_support;
130 };
131
132 class FunctionInstance0 : public TestInstance
133 {
134 public:
135 typedef tcu::TestStatus (*Function)(Context &context);
136
FunctionInstance0(Context & context,Function function)137 FunctionInstance0(Context &context, Function function) : TestInstance(context), m_function(function)
138 {
139 }
140
iterate(void)141 tcu::TestStatus iterate(void)
142 {
143 return m_function(m_context);
144 }
145
146 private:
147 const Function m_function;
148 };
149
150 template <typename Arg0>
151 class FunctionInstance1 : public TestInstance
152 {
153 public:
154 typedef tcu::TestStatus (*Function)(Context &context, Arg0 arg0);
155
156 struct Args
157 {
Argsvkt::FunctionInstance1::Args158 Args(Function func_, Arg0 arg0_) : func(func_), arg0(arg0_)
159 {
160 }
161
162 Function func;
163 Arg0 arg0;
164 };
165
FunctionInstance1(Context & context,const Args & args)166 FunctionInstance1(Context &context, const Args &args) : TestInstance(context), m_args(args)
167 {
168 }
169
iterate(void)170 tcu::TestStatus iterate(void)
171 {
172 return m_args.func(m_context, m_args.arg0);
173 }
174
175 private:
176 const Args m_args;
177 };
178
179 class FunctionPrograms0
180 {
181 public:
182 typedef void (*Function)(vk::SourceCollections &dst);
183
FunctionPrograms0(Function func)184 FunctionPrograms0(Function func) : m_func(func)
185 {
186 }
187
init(vk::SourceCollections & dst,FunctionInstance0::Function) const188 void init(vk::SourceCollections &dst, FunctionInstance0::Function) const
189 {
190 m_func(dst);
191 }
192
193 private:
194 const Function m_func;
195 };
196
197 struct NoSupport0
198 {
checkSupportvkt::NoSupport0199 void checkSupport(Context &) const
200 {
201 }
202 };
203
204 class FunctionSupport0
205 {
206 public:
207 typedef void (*Function)(Context &context);
208
FunctionSupport0(Function function)209 FunctionSupport0(Function function) : m_function(function)
210 {
211 }
212
checkSupport(Context & context) const213 void checkSupport(Context &context) const
214 {
215 m_function(context);
216 }
217
218 private:
219 const Function m_function;
220 };
221
222 template <typename Arg0>
223 struct NoSupport1
224 {
checkSupportvkt::NoSupport1225 void checkSupport(Context &, Arg0) const
226 {
227 }
228 };
229
230 template <typename Arg0>
231 class FunctionSupport1
232 {
233 public:
234 typedef void (*Function)(Context &context, Arg0 arg0);
235
236 struct Args
237 {
Argsvkt::FunctionSupport1::Args238 Args(Function func_, Arg0 arg0_) : func(func_), arg0(arg0_)
239 {
240 }
241
242 Function func;
243 Arg0 arg0;
244 };
245
FunctionSupport1(const Args & args)246 FunctionSupport1(const Args &args) : m_args(args)
247 {
248 }
249
checkSupport(Context & context) const250 void checkSupport(Context &context) const
251 {
252 return m_args.func(context, m_args.arg0);
253 }
254
255 private:
256 const Args m_args;
257 };
258
259 template <typename Arg0>
260 class FunctionPrograms1
261 {
262 public:
263 typedef void (*Function)(vk::SourceCollections &dst, Arg0 arg0);
264
FunctionPrograms1(Function func)265 FunctionPrograms1(Function func) : m_func(func)
266 {
267 }
268
init(vk::SourceCollections & dst,const typename FunctionInstance1<Arg0>::Args & args) const269 void init(vk::SourceCollections &dst, const typename FunctionInstance1<Arg0>::Args &args) const
270 {
271 m_func(dst, args.arg0);
272 }
273
274 private:
275 const Function m_func;
276 };
277
278 // createFunctionCase
279
createFunctionCase(tcu::TestContext & testCtx,const std::string & name,FunctionInstance0::Function testFunction)280 inline TestCase *createFunctionCase(tcu::TestContext &testCtx, const std::string &name,
281 FunctionInstance0::Function testFunction)
282 {
283 return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function>(testCtx, name, testFunction);
284 }
285
createFunctionCase(tcu::TestContext & testCtx,const std::string & name,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunction)286 inline TestCase *createFunctionCase(tcu::TestContext &testCtx, const std::string &name,
287 FunctionSupport0::Function checkSupport, FunctionInstance0::Function testFunction)
288 {
289 return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0>(
290 testCtx, name, testFunction, checkSupport);
291 }
292
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,const std::string & name,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunction)293 inline TestCase *createFunctionCaseWithPrograms(tcu::TestContext &testCtx, const std::string &name,
294 FunctionPrograms0::Function initPrograms,
295 FunctionInstance0::Function testFunction)
296 {
297 return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function, FunctionPrograms0>(
298 testCtx, name, FunctionPrograms0(initPrograms), testFunction);
299 }
300
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,const std::string & name,FunctionSupport0::Function checkSupport,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunction)301 inline TestCase *createFunctionCaseWithPrograms(tcu::TestContext &testCtx, const std::string &name,
302 FunctionSupport0::Function checkSupport,
303 FunctionPrograms0::Function initPrograms,
304 FunctionInstance0::Function testFunction)
305 {
306 return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0,
307 FunctionPrograms0>(testCtx, name, FunctionPrograms0(initPrograms),
308 testFunction, checkSupport);
309 }
310
311 template <typename Arg0>
createFunctionCase(tcu::TestContext & testCtx,const std::string & name,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)312 TestCase *createFunctionCase(tcu::TestContext &testCtx, const std::string &name,
313 typename FunctionInstance1<Arg0>::Function testFunction, Arg0 arg0)
314 {
315 return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args>(
316 testCtx, name, typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
317 }
318
319 template <typename Arg0>
createFunctionCase(tcu::TestContext & testCtx,const std::string & name,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)320 TestCase *createFunctionCase(tcu::TestContext &testCtx, const std::string &name,
321 typename FunctionSupport1<Arg0>::Function checkSupport,
322 typename FunctionInstance1<Arg0>::Function testFunction, Arg0 arg0)
323 {
324 return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args,
325 FunctionSupport1<Arg0>>(
326 testCtx, name, typename FunctionInstance1<Arg0>::Args(testFunction, arg0),
327 typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
328 }
329
330 template <typename Arg0>
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,const std::string & name,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)331 TestCase *createFunctionCaseWithPrograms(tcu::TestContext &testCtx, const std::string &name,
332 typename FunctionPrograms1<Arg0>::Function initPrograms,
333 typename FunctionInstance1<Arg0>::Function testFunction, Arg0 arg0)
334 {
335 return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args,
336 FunctionPrograms1<Arg0>>(testCtx, name, FunctionPrograms1<Arg0>(initPrograms),
337 typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
338 }
339
340 template <typename Arg0>
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,const std::string & name,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)341 TestCase *createFunctionCaseWithPrograms(tcu::TestContext &testCtx, const std::string &name,
342 typename FunctionSupport1<Arg0>::Function checkSupport,
343 typename FunctionPrograms1<Arg0>::Function initPrograms,
344 typename FunctionInstance1<Arg0>::Function testFunction, Arg0 arg0)
345 {
346 return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args,
347 FunctionSupport1<Arg0>, FunctionPrograms1<Arg0>>(
348 testCtx, name, FunctionPrograms1<Arg0>(initPrograms),
349 typename FunctionInstance1<Arg0>::Args(testFunction, arg0),
350 typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
351 }
352
353 // addFunctionCase
354
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,FunctionInstance0::Function testFunc)355 inline void addFunctionCase(tcu::TestCaseGroup *group, const std::string &name, FunctionInstance0::Function testFunc)
356 {
357 group->addChild(createFunctionCase(group->getTestContext(), name, testFunc));
358 }
359
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunc)360 inline void addFunctionCase(tcu::TestCaseGroup *group, const std::string &name, FunctionSupport0::Function checkSupport,
361 FunctionInstance0::Function testFunc)
362 {
363 group->addChild(createFunctionCase(group->getTestContext(), name, checkSupport, testFunc));
364 }
365
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunc)366 inline void addFunctionCaseWithPrograms(tcu::TestCaseGroup *group, const std::string &name,
367 FunctionPrograms0::Function initPrograms, FunctionInstance0::Function testFunc)
368 {
369 group->addChild(createFunctionCaseWithPrograms(group->getTestContext(), name, initPrograms, testFunc));
370 }
371
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,FunctionSupport0::Function checkSupport,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunc)372 inline void addFunctionCaseWithPrograms(tcu::TestCaseGroup *group, const std::string &name,
373 FunctionSupport0::Function checkSupport,
374 FunctionPrograms0::Function initPrograms, FunctionInstance0::Function testFunc)
375 {
376 group->addChild(
377 createFunctionCaseWithPrograms(group->getTestContext(), name, checkSupport, initPrograms, testFunc));
378 }
379
380 template <typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)381 void addFunctionCase(tcu::TestCaseGroup *group, const std::string &name,
382 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
383 {
384 group->addChild(createFunctionCase<Arg0>(group->getTestContext(), name, testFunc, arg0));
385 }
386
387 template <typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)388 void addFunctionCase(tcu::TestCaseGroup *group, const std::string &name,
389 typename FunctionSupport1<Arg0>::Function checkSupport,
390 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
391 {
392 group->addChild(createFunctionCase<Arg0>(group->getTestContext(), name, checkSupport, testFunc, arg0));
393 }
394
395 template <typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,tcu::TestNodeType type,const std::string & name,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)396 void addFunctionCase(tcu::TestCaseGroup *group, tcu::TestNodeType type, const std::string &name,
397 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
398 {
399 group->addChild(createFunctionCase<Arg0>(group->getTestContext(), type, name, testFunc, arg0));
400 }
401
402 template <typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)403 void addFunctionCaseWithPrograms(tcu::TestCaseGroup *group, const std::string &name,
404 typename FunctionPrograms1<Arg0>::Function initPrograms,
405 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
406 {
407 group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), name, initPrograms, testFunc, arg0));
408 }
409
410 template <typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)411 void addFunctionCaseWithPrograms(tcu::TestCaseGroup *group, const std::string &name,
412 typename FunctionSupport1<Arg0>::Function checkSupport,
413 typename FunctionPrograms1<Arg0>::Function initPrograms,
414 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
415 {
416 group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), name, checkSupport, initPrograms,
417 testFunc, arg0));
418 }
419
420 template <typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,tcu::TestNodeType type,const std::string & name,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)421 void addFunctionCaseWithPrograms(tcu::TestCaseGroup *group, tcu::TestNodeType type, const std::string &name,
422 typename FunctionPrograms1<Arg0>::Function initPrograms,
423 typename FunctionInstance1<Arg0>::Function testFunc, Arg0 arg0)
424 {
425 group->addChild(
426 createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), type, name, initPrograms, testFunc, arg0));
427 }
428
429 } // namespace vkt
430
431 #endif // _VKTTESTCASEUTIL_HPP
432