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