• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP
2 #define _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2017 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 Graphics pipeline and helper functions for SPIR-V assembly tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuCommandLine.hpp"
27 #include "tcuRGBA.hpp"
28 
29 #include "vkPrograms.hpp"
30 #include "vktSpvAsmComputeShaderTestUtil.hpp"
31 #include "vktSpvAsmUtils.hpp"
32 #include "vktTestCaseUtil.hpp"
33 
34 #include "deRandom.hpp"
35 #include "deSharedPtr.hpp"
36 
37 #include <map>
38 #include <sstream>
39 #include <string>
40 #include <utility>
41 
42 namespace vkt
43 {
44 namespace SpirVAssembly
45 {
46 
47 typedef vk::Unique<VkBuffer>										BufferHandleUp;
48 typedef de::SharedPtr<BufferHandleUp>								BufferHandleSp;
49 typedef vk::Unique<vk::VkShaderModule>								ModuleHandleUp;
50 typedef de::SharedPtr<ModuleHandleUp>								ModuleHandleSp;
51 typedef std::pair<std::string, vk::VkShaderStageFlagBits>			EntryToStage;
52 typedef std::map<std::string, std::vector<EntryToStage> >			ModuleMap;
53 typedef std::map<vk::VkShaderStageFlagBits, std::vector<deInt32> >	StageToSpecConstantMap;
54 typedef std::pair<vk::VkDescriptorType, BufferSp>					Resource;
55 
56 enum NumberType
57 {
58 	NUMBERTYPE_INT32,
59 	NUMBERTYPE_UINT32,
60 	NUMBERTYPE_FLOAT32,
61 	NUMBERTYPE_END32,		// Marks the end of 32-bit scalar types
62 	NUMBERTYPE_INT16,
63 	NUMBERTYPE_UINT16,
64 	NUMBERTYPE_FLOAT16,
65 };
66 
67 typedef enum RoundingModeFlags_e
68 {
69 	ROUNDINGMODE_RTE = 0x1,	// Round to nearest even
70 	ROUNDINGMODE_RTZ = 0x2,	// Round to zero
71 } RoundingModeFlags;
72 
73 typedef bool (*GraphicsVerifyIOFunc) (const std::vector<Resource>&		inputs,
74 									  const std::vector<AllocationSp>&	outputAllocations,
75 									  const std::vector<Resource>&		expectedOutputs,
76 									  tcu::TestLog&						log);
77 
78 // Resources used by graphics-pipeline-based tests.
79 struct GraphicsResources
80 {
81 	// Resources used as inputs.
82 	std::vector<Resource>	inputs;
83 	// Resources used as outputs. The data supplied will be used as
84 	// the expected outputs for the corresponding bindings by default.
85 	// If other behaviors are needed, please provide a custom verifyIO.
86 	std::vector<Resource>	outputs;
87 	// If null, a default verification will be performed by comparing the
88 	// memory pointed to by outputAllocations  and the contents of
89 	// expectedOutputs. Otherwise the function pointed to by verifyIO will
90 	// be called. If true is returned, then the test case is assumed to
91 	// have passed, if false is returned, then the test case is assumed
92 	// to have failed.
93 	GraphicsVerifyIOFunc	verifyIO;
94 
GraphicsResourcesvkt::SpirVAssembly::GraphicsResources95 							GraphicsResources()
96 								: verifyIO	(DE_NULL)
97 							{}
98 };
99 
100 // Interface data type.
101 struct IFDataType
102 {
IFDataTypevkt::SpirVAssembly::IFDataType103 						IFDataType			(deUint32 numE, NumberType elementT)
104 							: numElements	(numE)
105 							, elementType	(elementT)
106 						{
107 							DE_ASSERT(numE > 0 && numE < 5);
108 							DE_ASSERT(elementT != NUMBERTYPE_END32);
109 						}
110 
IFDataTypevkt::SpirVAssembly::IFDataType111 						IFDataType			(const IFDataType& that)
112 							: numElements	(that.numElements)
113 							, elementType	(that.elementType)
114 						{}
115 
116 	deUint32			getElementNumBytes	(void) const;
getNumBytesvkt::SpirVAssembly::IFDataType117 	deUint32			getNumBytes			(void) const { return numElements * getElementNumBytes(); }
118 
119 	vk::VkFormat		getVkFormat			(void) const;
120 
121 	tcu::TextureFormat	getTextureFormat	(void) const;
122 
123 	std::string			str					(void) const;
124 
elementIs32bitvkt::SpirVAssembly::IFDataType125 	bool				elementIs32bit		(void) const { return elementType < NUMBERTYPE_END32; }
isVectorvkt::SpirVAssembly::IFDataType126 	bool				isVector			(void) const { return numElements > 1; }
127 
128 	deUint32			numElements;
129 	NumberType			elementType;
130 };
131 
132 typedef std::pair<IFDataType, BufferSp>			Interface;
133 
134 // Interface variables used by graphics-pipeline-based tests.
135 class GraphicsInterfaces
136 {
137 public:
GraphicsInterfaces()138 						GraphicsInterfaces	()
139 							: rndMode	(static_cast<RoundingModeFlags>(0))
140 						{}
141 
GraphicsInterfaces(const GraphicsInterfaces & that)142 						GraphicsInterfaces	(const GraphicsInterfaces& that)
143 							: inputs	(that.inputs)
144 							, outputs	(that.outputs)
145 							, rndMode	(that.rndMode)
146 						{}
147 
setInputOutput(const Interface & input,const Interface & output)148 	void				setInputOutput		(const Interface& input, const Interface&  output)
149 						{
150 							inputs.clear();
151 							outputs.clear();
152 							inputs.push_back(input);
153 							outputs.push_back(output);
154 						}
155 
getInputType(void) const156 	const IFDataType&	getInputType		(void) const
157 						{
158 							DE_ASSERT(inputs.size() == 1);
159 							return inputs.front().first;
160 						}
161 
getOutputType(void) const162 	const IFDataType&	getOutputType		(void) const
163 						{
164 							DE_ASSERT(outputs.size() == 1);
165 							return outputs.front().first;
166 						}
167 
getInputBuffer(void) const168 	const BufferSp&		getInputBuffer		(void) const
169 						{
170 							DE_ASSERT(inputs.size() == 1);
171 							return inputs.front().second;
172 						}
173 
getOutputBuffer(void) const174 	const BufferSp&		getOutputBuffer		(void) const
175 						{
176 							DE_ASSERT(outputs.size() == 1);
177 							return outputs.front().second;
178 						}
179 
empty(void) const180 	bool				empty				(void) const
181 						{
182 							return inputs.size() == 0;
183 						}
184 
setRoundingMode(RoundingModeFlags flag)185 	void				setRoundingMode		(RoundingModeFlags flag)
186 						{
187 							rndMode = flag;
188 						}
getRoundingMode(void) const189 	RoundingModeFlags	getRoundingMode		(void) const
190 						{
191 							return rndMode;
192 						}
193 private:
194 	// vector<Interface> acts as a null-able Interface here. Canonically we should use
195 	// std::unique_ptr, but sadly we cannot leverage C++11 in dEQP. dEQP has its own
196 	// de::UniquePtr, but still cumbersome to use in InstanceContext and do copies
197 	// at various places.
198 	// Public methods should make sure that there are less than two elements in both
199 	// members and both members have the same number of elements.
200 	std::vector<Interface>	inputs;
201 	std::vector<Interface>	outputs;
202 	RoundingModeFlags		rndMode;
203 
204 };
205 
206 struct PushConstants
207 {
208 public:
PushConstantsvkt::SpirVAssembly::PushConstants209 							PushConstants (void)
210 							{}
211 
PushConstantsvkt::SpirVAssembly::PushConstants212 							PushConstants (const PushConstants& that)
213 								: pcs	(that.pcs)
214 							{}
215 
setPushConstantvkt::SpirVAssembly::PushConstants216 	void					setPushConstant	(const BufferSp& pc)
217 							{
218 								pcs.clear();
219 								pcs.push_back(pc);
220 							}
221 
emptyvkt::SpirVAssembly::PushConstants222 	bool					empty (void) const
223 							{
224 								return pcs.empty();
225 							}
226 
getBuffervkt::SpirVAssembly::PushConstants227 	const BufferSp&			getBuffer(void) const
228 							{
229 								DE_ASSERT(pcs.size() == 1);
230 								return pcs[0];
231 							}
232 
233 private:
234 	// Right now we only support one field in the push constant block.
235 	std::vector<BufferSp>	pcs;
236 };
237 
238 // Returns the corresponding buffer usage flag bit for the given descriptor type.
239 VkBufferUsageFlagBits getMatchingBufferUsageFlagBit(VkDescriptorType dType);
240 
241 // Context for a specific test instantiation. For example, an instantiation
242 // may test colors yellow/magenta/cyan/mauve in a tesselation shader
243 // with an entry point named 'main_to_the_main'
244 struct InstanceContext
245 {
246 	// Map of modules to what entry_points we care to use from those modules.
247 	ModuleMap								moduleMap;
248 	tcu::RGBA								inputColors[4];
249 	tcu::RGBA								outputColors[4];
250 	// Concrete SPIR-V code to test via boilerplate specialization.
251 	std::map<std::string, std::string>		testCodeFragments;
252 	StageToSpecConstantMap					specConstants;
253 	bool									hasTessellation;
254 	vk::VkShaderStageFlagBits				requiredStages;
255 	std::vector<std::string>				requiredDeviceExtensions;
256 	std::vector<std::string>				requiredDeviceFeatures;
257 	VulkanFeatures							requestedFeatures;
258 	PushConstants							pushConstants;
259 	// Specifies the (one or more) stages that use a customized shader code.
260 	VkShaderStageFlags						customizedStages;
261 	// Possible resources used by the graphics pipeline.
262 	// If it is not empty, a single descriptor set (number 0) will be allocated
263 	// to point to all resources specified. Binding numbers are allocated in
264 	// accord with the resources' order in the vector; outputs are allocated
265 	// after inputs.
266 	GraphicsResources						resources;
267 	// Possible interface variables use by the graphics pipeline.
268 	// If it is not empty, input/output variables will be set up for shader stages
269 	// in the test. Both the input and output variable will take location #2 in the
270 	// pipeline for all stages, except that the output variable in the fragment
271 	// stage will take location #1.
272 	GraphicsInterfaces						interfaces;
273 	qpTestResult							failResult;
274 	std::string								failMessageTemplate;	//!< ${reason} in the template will be replaced with a detailed failure message
275 
276 	InstanceContext (const tcu::RGBA							(&inputs)[4],
277 					 const tcu::RGBA							(&outputs)[4],
278 					 const std::map<std::string, std::string>&	testCodeFragments_,
279 					 const StageToSpecConstantMap&				specConstants_,
280 					 const PushConstants&						pushConsants_,
281 					 const GraphicsResources&					resources_,
282 					 const GraphicsInterfaces&					interfaces_,
283 					 const std::vector<std::string>&			extensions_,
284 					 const std::vector<std::string>&			features_,
285 					 VulkanFeatures								vulkanFeatures_,
286 					 VkShaderStageFlags							customizedStages_);
287 
288 	InstanceContext (const InstanceContext& other);
289 
290 	std::string getSpecializedFailMessage (const std::string& failureReason);
291 };
292 
293 // A description of a shader to be used for a single stage of the graphics pipeline.
294 struct ShaderElement
295 {
296 	// The module that contains this shader entrypoint.
297 	std::string					moduleName;
298 
299 	// The name of the entrypoint.
300 	std::string					entryName;
301 
302 	// Which shader stage this entry point represents.
303 	vk::VkShaderStageFlagBits	stage;
304 
305 	ShaderElement (const std::string& moduleName_, const std::string& entryPoint_, vk::VkShaderStageFlagBits shaderStage_);
306 };
307 
308 template <typename T>
numberToString(T number)309 const std::string numberToString (T number)
310 {
311 	std::stringstream ss;
312 	ss << number;
313 	return ss.str();
314 }
315 
316 // Performs a bitwise copy of source to the destination type Dest.
317 template <typename Dest, typename Src>
bitwiseCast(Src source)318 Dest bitwiseCast(Src source)
319 {
320   Dest dest;
321   DE_STATIC_ASSERT(sizeof(source) == sizeof(dest));
322   deMemcpy(&dest, &source, sizeof(dest));
323   return dest;
324 }
325 
326 template<typename T>	T			randomScalar	(de::Random& rnd, T minValue, T maxValue);
randomScalar(de::Random & rnd,float minValue,float maxValue)327 template<> inline		float		randomScalar	(de::Random& rnd, float minValue, float maxValue)		{ return rnd.getFloat(minValue, maxValue);	}
randomScalar(de::Random & rnd,deInt32 minValue,deInt32 maxValue)328 template<> inline		deInt32		randomScalar	(de::Random& rnd, deInt32 minValue, deInt32 maxValue)	{ return rnd.getInt(minValue, maxValue);	}
329 
330 
331 void getDefaultColors (tcu::RGBA (&colors)[4]);
332 
333 void getHalfColorsFullAlpha (tcu::RGBA (&colors)[4]);
334 
335 void getInvertedDefaultColors (tcu::RGBA (&colors)[4]);
336 
337 // Creates fragments that specialize into a simple pass-through shader (of any kind).
338 std::map<std::string, std::string> passthruFragments(void);
339 
340 void createCombinedModule(vk::SourceCollections& dst, InstanceContext);
341 
342 // This has two shaders of each stage. The first
343 // is a passthrough, the second inverts the color.
344 void createMultipleEntries(vk::SourceCollections& dst, InstanceContext);
345 
346 // Turns a statically sized array of ShaderElements into an instance-context
347 // by setting up the mapping of modules to their contained shaders and stages.
348 // The inputs and expected outputs are given by inputColors and outputColors
349 template<size_t N>
createInstanceContext(const ShaderElement (& elements)[N],const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,const StageToSpecConstantMap & specConstants,const PushConstants & pushConstants,const GraphicsResources & resources,const GraphicsInterfaces & interfaces,const std::vector<std::string> & extensions,const std::vector<std::string> & features,VulkanFeatures vulkanFeatures,VkShaderStageFlags customizedStages,const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())350 InstanceContext createInstanceContext (const ShaderElement							(&elements)[N],
351 									   const tcu::RGBA								(&inputColors)[4],
352 									   const tcu::RGBA								(&outputColors)[4],
353 									   const std::map<std::string, std::string>&	testCodeFragments,
354 									   const StageToSpecConstantMap&				specConstants,
355 									   const PushConstants&							pushConstants,
356 									   const GraphicsResources&						resources,
357 									   const GraphicsInterfaces&					interfaces,
358 									   const std::vector<std::string>&				extensions,
359 									   const std::vector<std::string>&				features,
360 									   VulkanFeatures								vulkanFeatures,
361 									   VkShaderStageFlags							customizedStages,
362 									   const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
363 									   const std::string&							failMessageTemplate	= std::string())
364 {
365 	InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, customizedStages);
366 	for (size_t i = 0; i < N; ++i)
367 	{
368 		ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage));
369 		ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | elements[i].stage);
370 	}
371 	ctx.failResult				= failResult;
372 	if (!failMessageTemplate.empty())
373 		ctx.failMessageTemplate	= failMessageTemplate;
374 	return ctx;
375 }
376 
377 // The same as createInstanceContext above, without extensions, spec constants, and resources.
378 template<size_t N>
createInstanceContext(const ShaderElement (& elements)[N],tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments)379 inline InstanceContext createInstanceContext (const ShaderElement						(&elements)[N],
380 											  tcu::RGBA									(&inputColors)[4],
381 											  const tcu::RGBA							(&outputColors)[4],
382 											  const std::map<std::string, std::string>&	testCodeFragments)
383 {
384 	return createInstanceContext(elements, inputColors, outputColors, testCodeFragments,
385 								 StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
386 								 GraphicsInterfaces(), std::vector<std::string>(), std::vector<std::string>(),
387 								 VulkanFeatures(), vk::VK_SHADER_STAGE_ALL);
388 }
389 
390 // The same as createInstanceContext above, but with default colors.
391 template<size_t N>
createInstanceContext(const ShaderElement (& elements)[N],const std::map<std::string,std::string> & testCodeFragments)392 InstanceContext createInstanceContext (const ShaderElement							(&elements)[N],
393 									   const std::map<std::string, std::string>&	testCodeFragments)
394 {
395 	tcu::RGBA defaultColors[4];
396 	getDefaultColors(defaultColors);
397 	return createInstanceContext(elements, defaultColors, defaultColors, testCodeFragments);
398 }
399 
400 
401 void createTestsForAllStages (const std::string&						name,
402 							  const tcu::RGBA							(&inputColors)[4],
403 							  const tcu::RGBA							(&outputColors)[4],
404 							  const std::map<std::string, std::string>&	testCodeFragments,
405 							  const std::vector<deInt32>&				specConstants,
406 							  const PushConstants&						pushConstants,
407 							  const GraphicsResources&					resources,
408 							  const GraphicsInterfaces&					interfaces,
409 							  const std::vector<std::string>&			extensions,
410 							  const std::vector<std::string>&			features,
411 							  VulkanFeatures							vulkanFeatures,
412 							  tcu::TestCaseGroup*						tests,
413 							  const qpTestResult						failResult			= QP_TEST_RESULT_FAIL,
414 							  const std::string&						failMessageTemplate	= std::string());
415 
createTestsForAllStages(const std::string & name,const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,tcu::TestCaseGroup * tests,const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())416 inline void createTestsForAllStages (const std::string&							name,
417 									 const tcu::RGBA							(&inputColors)[4],
418 									 const tcu::RGBA							(&outputColors)[4],
419 									 const std::map<std::string, std::string>&	testCodeFragments,
420 									 tcu::TestCaseGroup*						tests,
421 									 const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
422 									 const std::string&							failMessageTemplate	= std::string())
423 {
424 	std::vector<deInt32>		noSpecConstants;
425 	PushConstants				noPushConstants;
426 	GraphicsResources			noResources;
427 	GraphicsInterfaces			noInterfaces;
428 	std::vector<std::string>	noExtensions;
429 	std::vector<std::string>	noFeatures;
430 
431 	createTestsForAllStages(
432 			name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
433 			noResources, noInterfaces, noExtensions, noFeatures, VulkanFeatures(),
434 			tests, failResult, failMessageTemplate);
435 }
436 
createTestsForAllStages(const std::string & name,const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,const std::vector<deInt32> & specConstants,tcu::TestCaseGroup * tests,const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())437 inline void createTestsForAllStages (const std::string&							name,
438 									 const tcu::RGBA							(&inputColors)[4],
439 									 const tcu::RGBA							(&outputColors)[4],
440 									 const std::map<std::string, std::string>&	testCodeFragments,
441 									 const std::vector<deInt32>&				specConstants,
442 									 tcu::TestCaseGroup*						tests,
443 									 const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
444 									 const std::string&							failMessageTemplate	= std::string())
445 {
446 	PushConstants					noPushConstants;
447 	GraphicsResources				noResources;
448 	GraphicsInterfaces				noInterfaces;
449 	std::vector<std::string>		noExtensions;
450 	std::vector<std::string>		noFeatures;
451 
452 	createTestsForAllStages(
453 			name, inputColors, outputColors, testCodeFragments, specConstants, noPushConstants,
454 			noResources, noInterfaces, noExtensions, noFeatures, VulkanFeatures(),
455 			tests, failResult, failMessageTemplate);
456 }
457 
createTestsForAllStages(const std::string & name,const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,const GraphicsResources & resources,const std::vector<std::string> & extensions,tcu::TestCaseGroup * tests,VulkanFeatures vulkanFeatures=VulkanFeatures (),const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())458 inline void createTestsForAllStages (const std::string&							name,
459 									 const tcu::RGBA							(&inputColors)[4],
460 									 const tcu::RGBA							(&outputColors)[4],
461 									 const std::map<std::string, std::string>&	testCodeFragments,
462 									 const GraphicsResources&					resources,
463 									 const std::vector<std::string>&			extensions,
464 									 tcu::TestCaseGroup*						tests,
465 									 VulkanFeatures								vulkanFeatures		= VulkanFeatures(),
466 									 const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
467 									 const std::string&							failMessageTemplate	= std::string())
468 {
469 	std::vector<deInt32>		noSpecConstants;
470 	PushConstants				noPushConstants;
471 	GraphicsInterfaces			noInterfaces;
472 	std::vector<std::string>	noFeatures;
473 
474 	createTestsForAllStages(
475 			name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
476 			resources, noInterfaces, extensions, noFeatures, vulkanFeatures,
477 			tests, failResult, failMessageTemplate);
478 }
479 
createTestsForAllStages(const std::string & name,const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,const GraphicsInterfaces interfaces,const std::vector<std::string> & extensions,tcu::TestCaseGroup * tests,VulkanFeatures vulkanFeatures=VulkanFeatures (),const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())480 inline void createTestsForAllStages (const std::string& name,
481 									 const tcu::RGBA							(&inputColors)[4],
482 									 const tcu::RGBA							(&outputColors)[4],
483 									 const std::map<std::string, std::string>&	testCodeFragments,
484 									 const GraphicsInterfaces					interfaces,
485 									 const std::vector<std::string>&			extensions,
486 									 tcu::TestCaseGroup*						tests,
487 									 VulkanFeatures								vulkanFeatures		= VulkanFeatures(),
488 									 const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
489 									 const std::string&							failMessageTemplate	= std::string())
490 {
491 	GraphicsResources			noResources;
492 	std::vector<deInt32>		noSpecConstants;
493 	std::vector<std::string>	noFeatures;
494 	PushConstants				noPushConstants;
495 
496 	createTestsForAllStages(
497 			name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
498 			noResources, interfaces, extensions, noFeatures, vulkanFeatures,
499 			tests, failResult, failMessageTemplate);
500 }
501 
createTestsForAllStages(const std::string & name,const tcu::RGBA (& inputColors)[4],const tcu::RGBA (& outputColors)[4],const std::map<std::string,std::string> & testCodeFragments,const PushConstants & pushConstants,const GraphicsResources & resources,const std::vector<std::string> & extensions,tcu::TestCaseGroup * tests,VulkanFeatures vulkanFeatures=VulkanFeatures (),const qpTestResult failResult=QP_TEST_RESULT_FAIL,const std::string & failMessageTemplate=std::string ())502 inline void createTestsForAllStages (const std::string& name,
503 									 const tcu::RGBA							(&inputColors)[4],
504 									 const tcu::RGBA							(&outputColors)[4],
505 									 const std::map<std::string, std::string>&	testCodeFragments,
506 									 const PushConstants&						pushConstants,
507 									 const GraphicsResources&					resources,
508 									 const std::vector<std::string>&			extensions,
509 									 tcu::TestCaseGroup*						tests,
510 									 VulkanFeatures								vulkanFeatures		= VulkanFeatures(),
511 									 const qpTestResult							failResult			= QP_TEST_RESULT_FAIL,
512 									 const std::string&							failMessageTemplate	= std::string())
513 {
514 	std::vector<deInt32>			noSpecConstants;
515 	GraphicsInterfaces				noInterfaces;
516 	std::vector<std::string>		noFeatures;
517 
518 	createTestsForAllStages(
519 			name, inputColors, outputColors, testCodeFragments, noSpecConstants, pushConstants,
520 			resources, noInterfaces, extensions, noFeatures, vulkanFeatures,
521 			tests, failResult, failMessageTemplate);
522 }
523 
524 // Sets up and runs a Vulkan pipeline, then spot-checks the resulting image.
525 // Feeds the pipeline a set of colored triangles, which then must occur in the
526 // rendered image.  The surface is cleared before executing the pipeline, so
527 // whatever the shaders draw can be directly spot-checked.
528 tcu::TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance);
529 
530 // Adds a new test to group using custom fragments for the tessellation-control
531 // stage and passthrough fragments for all other stages.  Uses default colors
532 // for input and expected output.
533 void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const std::map<std::string, std::string>& fragments);
534 
535 // Given the original 32-bit float value, computes the corresponding 16-bit
536 // float value under the given rounding mode flags and compares with the
537 // returned 16-bit float value. Returns true if they are considered as equal.
538 //
539 // The following equivalence criteria are respected:
540 // * Positive and negative zeros are considered equivalent.
541 // * Denormalized floats are allowed to be flushed to zeros, including
542 //   * Inputted 32bit denormalized float
543 //   * Generated 16bit denormalized float
544 // * Different bit patterns of NaNs are allowed.
545 // * For the rest, require exactly the same bit pattern.
546 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
547 
548 // Compare the returned 32-bit float against its expected value.
549 //
550 // The following equivalence criteria are respected:
551 // * Denormalized floats are allowed to be flushed to zeros, including
552 //   * The expected value itself is a denormalized float
553 //   * The expected value is a denormalized float if converted to 16bit
554 // * Different bit patterns of NaNs/Infs are allowed.
555 // * For the rest, use C++ float equivalence check.
556 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log);
557 
558 } // SpirVAssembly
559 } // vkt
560 
561 #endif // _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP
562