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<deUint8> 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 template<typename Instance, typename Arg0, typename Programs = NoPrograms1<Arg0> >
55 class InstanceFactory1 : public TestCase
56 {
57 public:
InstanceFactory1(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,const Arg0 & arg0)58 					InstanceFactory1	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Arg0& arg0)
59 						: TestCase	(testCtx, type, name, desc)
60 						, m_progs	()
61 						, m_arg0	(arg0)
62 					{}
63 
InstanceFactory1(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,const Programs & progs,const Arg0 & arg0)64 					InstanceFactory1	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Programs& progs, const Arg0& arg0)
65 						: TestCase	(testCtx, type, name, desc)
66 						, m_progs	(progs)
67 						, m_arg0	(arg0)
68 					{}
69 
initPrograms(vk::SourceCollections & dst) const70 	void			initPrograms	(vk::SourceCollections& dst)	const { m_progs.init(dst, m_arg0); }
createInstance(Context & context) const71 	TestInstance*	createInstance	(Context& context)				const { return new Instance(context, m_arg0); }
checkSupport(Context &) const72 	void			checkSupport	(Context&)						const { }
73 
74 private:
75 	const Programs	m_progs;
76 	const Arg0		m_arg0;
77 };
78 
79 template<typename Instance, typename Arg0, typename Support, typename Programs = NoPrograms1<Arg0> >
80 class InstanceFactory1WithSupport : public TestCase
81 {
82 public:
83 
InstanceFactory1WithSupport(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,const Arg0 & arg0,const Support & support)84 					InstanceFactory1WithSupport	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Arg0& arg0, const Support& support)
85 						: TestCase	(testCtx, type, name, desc)
86 						, m_progs	()
87 						, m_arg0	(arg0)
88 						, m_support	(support)
89 					{}
90 
InstanceFactory1WithSupport(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,const Programs & progs,const Arg0 & arg0,const Support & support)91 					InstanceFactory1WithSupport	(tcu::TestContext& testCtx, tcu::TestNodeType type, const std::string& name, const std::string& desc, const Programs& progs, const Arg0& arg0, const Support& support)
92 						: TestCase	(testCtx, type, name, desc)
93 						, m_progs	(progs)
94 						, m_arg0	(arg0)
95 						, m_support	(support)
96 					{}
97 
initPrograms(vk::SourceCollections & dst) const98 	void			initPrograms	(vk::SourceCollections& dst)	const { m_progs.init(dst, m_arg0); }
createInstance(Context & context) const99 	TestInstance*	createInstance	(Context& context)				const { return new Instance(context, m_arg0); }
checkSupport(Context & context) const100 	void			checkSupport	(Context& context)				const { m_support.checkSupport(context); }
101 
102 private:
103 	const Programs	m_progs;
104 	const Arg0		m_arg0;
105 	const Support	m_support;
106 };
107 
108 class FunctionInstance0 : public TestInstance
109 {
110 public:
111 	typedef tcu::TestStatus	(*Function)	(Context& context);
112 
FunctionInstance0(Context & context,Function function)113 					FunctionInstance0	(Context& context, Function function)
114 						: TestInstance	(context)
115 						, m_function	(function)
116 					{}
117 
iterate(void)118 	tcu::TestStatus	iterate				(void) { return m_function(m_context); }
119 
120 private:
121 	const Function	m_function;
122 };
123 
124 template<typename Arg0>
125 class FunctionInstance1 : public TestInstance
126 {
127 public:
128 	typedef tcu::TestStatus	(*Function)	(Context& context, Arg0 arg0);
129 
130 	struct Args
131 	{
Argsvkt::FunctionInstance1::Args132 		Args (Function func_, Arg0 arg0_) : func(func_), arg0(arg0_) {}
133 
134 		Function	func;
135 		Arg0		arg0;
136 	};
137 
FunctionInstance1(Context & context,const Args & args)138 					FunctionInstance1	(Context& context, const Args& args)
139 						: TestInstance	(context)
140 						, m_args		(args)
141 					{}
142 
iterate(void)143 	tcu::TestStatus	iterate				(void) { return m_args.func(m_context, m_args.arg0); }
144 
145 private:
146 	const Args		m_args;
147 };
148 
149 class FunctionPrograms0
150 {
151 public:
152 	typedef void	(*Function)		(vk::SourceCollections& dst);
153 
FunctionPrograms0(Function func)154 					FunctionPrograms0	(Function func)
155 						: m_func(func)
156 					{}
157 
init(vk::SourceCollections & dst,FunctionInstance0::Function) const158 	void			init			(vk::SourceCollections& dst, FunctionInstance0::Function) const { m_func(dst); }
159 
160 private:
161 	const Function	m_func;
162 };
163 
164 struct NoSupport0
165 {
checkSupportvkt::NoSupport0166 	void			checkSupport	(Context&) const {};
167 };
168 
169 class FunctionSupport0
170 {
171 public:
172 	typedef void	(*Function)	(Context& context);
173 
FunctionSupport0(Function function)174 					FunctionSupport0 (Function function)
175 						: m_function(function)
176 					{}
177 
checkSupport(Context & context) const178 	void			checkSupport (Context& context) const { m_function(context); }
179 
180 private:
181 	const Function	m_function;
182 };
183 
184 template<typename Arg0>
185 struct NoSupport1
186 {
checkSupportvkt::NoSupport1187 	void			checkSupport	(Context&, Arg0) const {};
188 };
189 
190 template<typename Arg0>
191 class FunctionSupport1
192 {
193 public:
194 	typedef void	(*Function)	(Context& context, Arg0 arg0);
195 
196 	struct Args
197 	{
Argsvkt::FunctionSupport1::Args198 		Args (Function func_, Arg0 arg0_)
199 			: func(func_)
200 			, arg0(arg0_)
201 		{}
202 
203 		Function	func;
204 		Arg0		arg0;
205 	};
206 
FunctionSupport1(const Args & args)207 					FunctionSupport1 (const Args& args)
208 						: m_args(args)
209 					{}
210 
checkSupport(Context & context) const211 	void			checkSupport (Context& context) const { return m_args.func(context, m_args.arg0); }
212 
213 private:
214 	const Args		m_args;
215 };
216 
217 template<typename Arg0>
218 class FunctionPrograms1
219 {
220 public:
221 	typedef void	(*Function)		(vk::SourceCollections& dst, Arg0 arg0);
222 
FunctionPrograms1(Function func)223 					FunctionPrograms1	(Function func)
224 						: m_func(func)
225 					{}
226 
init(vk::SourceCollections & dst,const typename FunctionInstance1<Arg0>::Args & args) const227 	void			init			(vk::SourceCollections& dst, const typename FunctionInstance1<Arg0>::Args& args) const { m_func(dst, args.arg0); }
228 
229 private:
230 	const Function	m_func;
231 };
232 
233 // createFunctionCase
234 
createFunctionCase(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,FunctionInstance0::Function testFunction)235 inline TestCase* createFunctionCase (tcu::TestContext&				testCtx,
236 									 tcu::TestNodeType				type,
237 									 const std::string&				name,
238 									 const std::string&				desc,
239 									 FunctionInstance0::Function	testFunction)
240 {
241 	return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function>(testCtx, type, name, desc, testFunction);
242 }
243 
createFunctionCase(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunction)244 inline TestCase* createFunctionCase (tcu::TestContext&				testCtx,
245 									 tcu::TestNodeType				type,
246 									 const std::string&				name,
247 									 const std::string&				desc,
248 									 FunctionSupport0::Function		checkSupport,
249 									 FunctionInstance0::Function	testFunction)
250 {
251 	return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0>(testCtx, type, name, desc, testFunction, checkSupport);
252 }
253 
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunction)254 inline TestCase* createFunctionCaseWithPrograms (tcu::TestContext&				testCtx,
255 												 tcu::TestNodeType				type,
256 												 const std::string&				name,
257 												 const std::string&				desc,
258 												 FunctionPrograms0::Function	initPrograms,
259 												 FunctionInstance0::Function	testFunction)
260 {
261 	return new InstanceFactory1<FunctionInstance0, FunctionInstance0::Function, FunctionPrograms0>(
262 		testCtx, type, name, desc, FunctionPrograms0(initPrograms), testFunction);
263 }
264 
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,FunctionSupport0::Function checkSupport,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunction)265 inline TestCase* createFunctionCaseWithPrograms (tcu::TestContext&				testCtx,
266 												 tcu::TestNodeType				type,
267 												 const std::string&				name,
268 												 const std::string&				desc,
269 												 FunctionSupport0::Function		checkSupport,
270 												 FunctionPrograms0::Function	initPrograms,
271 												 FunctionInstance0::Function	testFunction)
272 {
273 	return new InstanceFactory1WithSupport<FunctionInstance0, FunctionInstance0::Function, FunctionSupport0, FunctionPrograms0>(
274 		testCtx, type, name, desc, FunctionPrograms0(initPrograms), testFunction, checkSupport);
275 }
276 
277 template<typename Arg0>
createFunctionCase(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)278 TestCase* createFunctionCase (tcu::TestContext&								testCtx,
279 							  tcu::TestNodeType								type,
280 							  const std::string&							name,
281 							  const std::string&							desc,
282 							  typename FunctionInstance1<Arg0>::Function	testFunction,
283 							  Arg0											arg0)
284 {
285 	return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args>(
286 		testCtx, type, name, desc, typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
287 }
288 
289 template<typename Arg0>
createFunctionCase(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)290 TestCase* createFunctionCase (tcu::TestContext&								testCtx,
291 							  tcu::TestNodeType								type,
292 							  const std::string&							name,
293 							  const std::string&							desc,
294 							  typename FunctionSupport1<Arg0>::Function		checkSupport,
295 							  typename FunctionInstance1<Arg0>::Function	testFunction,
296 							  Arg0											arg0)
297 {
298 	return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionSupport1<Arg0> >(
299 		testCtx, type, name, desc, typename FunctionInstance1<Arg0>::Args(testFunction, arg0), typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
300 }
301 
302 template<typename Arg0>
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)303 TestCase* createFunctionCaseWithPrograms (tcu::TestContext&								testCtx,
304 										  tcu::TestNodeType								type,
305 										  const std::string&							name,
306 										  const std::string&							desc,
307 										  typename FunctionPrograms1<Arg0>::Function	initPrograms,
308 										  typename FunctionInstance1<Arg0>::Function	testFunction,
309 										  Arg0											arg0)
310 {
311 	return new InstanceFactory1<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionPrograms1<Arg0> >(
312 		testCtx, type, name, desc, FunctionPrograms1<Arg0>(initPrograms), typename FunctionInstance1<Arg0>::Args(testFunction, arg0));
313 }
314 
315 template<typename Arg0>
createFunctionCaseWithPrograms(tcu::TestContext & testCtx,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunction,Arg0 arg0)316 TestCase* createFunctionCaseWithPrograms (tcu::TestContext&								testCtx,
317 										  tcu::TestNodeType								type,
318 										  const std::string&							name,
319 										  const std::string&							desc,
320 										  typename FunctionSupport1<Arg0>::Function		checkSupport,
321 										  typename FunctionPrograms1<Arg0>::Function	initPrograms,
322 										  typename FunctionInstance1<Arg0>::Function	testFunction,
323 										  Arg0											arg0)
324 {
325 	return new InstanceFactory1WithSupport<FunctionInstance1<Arg0>, typename FunctionInstance1<Arg0>::Args, FunctionSupport1<Arg0>, FunctionPrograms1<Arg0> >(
326 		testCtx, type, name, desc, FunctionPrograms1<Arg0>(initPrograms), typename FunctionInstance1<Arg0>::Args(testFunction, arg0), typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
327 }
328 
329 // addFunctionCase
330 
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,FunctionInstance0::Function testFunc)331 inline void addFunctionCase (tcu::TestCaseGroup*			group,
332 							 const std::string&				name,
333 							 const std::string&				desc,
334 							 FunctionInstance0::Function	testFunc)
335 {
336 	group->addChild(createFunctionCase(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, testFunc));
337 }
338 
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,FunctionSupport0::Function checkSupport,FunctionInstance0::Function testFunc)339 inline void addFunctionCase (tcu::TestCaseGroup*			group,
340 							 const std::string&				name,
341 							 const std::string&				desc,
342 							 FunctionSupport0::Function		checkSupport,
343 							 FunctionInstance0::Function	testFunc)
344 {
345 	group->addChild(createFunctionCase(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, testFunc));
346 }
347 
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunc)348 inline void addFunctionCaseWithPrograms (tcu::TestCaseGroup*			group,
349 										 const std::string&				name,
350 										 const std::string&				desc,
351 										 FunctionPrograms0::Function	initPrograms,
352 										 FunctionInstance0::Function	testFunc)
353 {
354 	group->addChild(createFunctionCaseWithPrograms(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, initPrograms, testFunc));
355 }
356 
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,FunctionSupport0::Function checkSupport,FunctionPrograms0::Function initPrograms,FunctionInstance0::Function testFunc)357 inline void addFunctionCaseWithPrograms (tcu::TestCaseGroup*			group,
358 										 const std::string&				name,
359 										 const std::string&				desc,
360 										 FunctionSupport0::Function		checkSupport,
361 										 FunctionPrograms0::Function	initPrograms,
362 										 FunctionInstance0::Function	testFunc)
363 {
364 	group->addChild(createFunctionCaseWithPrograms(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, initPrograms, testFunc));
365 }
366 
367 template<typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)368 void addFunctionCase (tcu::TestCaseGroup*							group,
369 					  const std::string&							name,
370 					  const std::string&							desc,
371 					  typename FunctionInstance1<Arg0>::Function	testFunc,
372 					  Arg0											arg0)
373 {
374 	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, testFunc, arg0));
375 }
376 
377 template<typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)378 void addFunctionCase (tcu::TestCaseGroup*							group,
379 					  const std::string&							name,
380 					  const std::string&							desc,
381 					  typename FunctionSupport1<Arg0>::Function		checkSupport,
382 					  typename FunctionInstance1<Arg0>::Function	testFunc,
383 					  Arg0											arg0)
384 {
385 	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, testFunc, arg0));
386 }
387 
388 template<typename Arg0>
addFunctionCase(tcu::TestCaseGroup * group,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)389 void addFunctionCase (tcu::TestCaseGroup*							group,
390 					  tcu::TestNodeType								type,
391 					  const std::string&							name,
392 					  const std::string&							desc,
393 					  typename FunctionInstance1<Arg0>::Function	testFunc,
394 					  Arg0											arg0)
395 {
396 	group->addChild(createFunctionCase<Arg0>(group->getTestContext(), type, name, desc, testFunc, arg0));
397 }
398 
399 template<typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)400 void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
401 								  const std::string&							name,
402 								  const std::string&							desc,
403 								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
404 								  typename FunctionInstance1<Arg0>::Function	testFunc,
405 								  Arg0											arg0)
406 {
407 	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, initPrograms, testFunc, arg0));
408 }
409 
410 template<typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,const std::string & name,const std::string & desc,typename FunctionSupport1<Arg0>::Function checkSupport,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)411 void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
412 								  const std::string&							name,
413 								  const std::string&							desc,
414 								  typename FunctionSupport1<Arg0>::Function		checkSupport,
415 								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
416 								  typename FunctionInstance1<Arg0>::Function	testFunc,
417 								  Arg0											arg0)
418 {
419 	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), tcu::NODETYPE_SELF_VALIDATE, name, desc, checkSupport, initPrograms, testFunc, arg0));
420 }
421 
422 template<typename Arg0>
addFunctionCaseWithPrograms(tcu::TestCaseGroup * group,tcu::TestNodeType type,const std::string & name,const std::string & desc,typename FunctionPrograms1<Arg0>::Function initPrograms,typename FunctionInstance1<Arg0>::Function testFunc,Arg0 arg0)423 void addFunctionCaseWithPrograms (tcu::TestCaseGroup*							group,
424 								  tcu::TestNodeType								type,
425 								  const std::string&							name,
426 								  const std::string&							desc,
427 								  typename FunctionPrograms1<Arg0>::Function	initPrograms,
428 								  typename FunctionInstance1<Arg0>::Function	testFunc,
429 								  Arg0											arg0)
430 {
431 	group->addChild(createFunctionCaseWithPrograms<Arg0>(group->getTestContext(), type, name, desc, initPrograms, testFunc, arg0));
432 }
433 
434 } // vkt
435 
436 #endif // _VKTTESTCASEUTIL_HPP
437